blob: defd647bdbf5a4e2145cba082161a0e77ce2525b [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "Dalvik.h"
18#include "CompilerInternals.h"
19
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080020namespace art {
21
buzbee5abfa3e2012-01-31 17:01:43 -080022#ifdef WITH_MEMSTATS
buzbeeba938cb2012-02-03 14:47:55 -080023typedef struct Memstats {
24 u4 allocStats[kNumAllocKinds];
25 int listSizes[kNumListKinds];
26 int listWasted[kNumListKinds];
27 int listGrows[kNumListKinds];
28 int listMaxElems[kNumListKinds];
29 int bitMapSizes[kNumBitMapKinds];
30 int bitMapWasted[kNumBitMapKinds];
31 int bitMapGrows[kNumBitMapKinds];
32} memstats;
buzbee5abfa3e2012-01-31 17:01:43 -080033
34const char* allocNames[kNumAllocKinds] = {
35 "Misc ",
36 "BasicBlock ",
37 "LIR ",
38 "MIR ",
39 "DataFlow ",
40 "GrowList ",
41 "GrowBitMap ",
42 "Dalvik2SSA ",
43 "DebugInfo ",
44 "Successor ",
45 "RegAlloc ",
46 "Data ",
47 "Preds ",
48};
49
50const char* listNames[kNumListKinds] = {
51 "Misc ",
52 "blockList ",
53 "SSAtoDalvik ",
54 "dfsOrder ",
55 "dfsPostOrder ",
56 "domPostOrderTraversal ",
57 "throwLaunchPads ",
58 "suspendLaunchPads ",
59 "switchTables ",
60 "fillArrayData ",
61 "SuccessorBlocks ",
62 "Predecessors ",
63};
64
65const char* bitMapNames[kNumBitMapKinds] = {
66 "Misc ",
67 "Use ",
68 "Def ",
69 "LiveIn ",
70 "BlockMatrix ",
71 "Dominators ",
72 "IDominated ",
73 "DomFrontier ",
74 "Phi ",
75 "TmpBlocks ",
76 "InputBlocks ",
77 "RegisterV ",
78 "TempSSARegisterV ",
79 "Null Check ",
80 "TmpBlockV ",
81 "Predecessors ",
82};
83#endif
84
buzbee67bf8852011-08-17 17:51:35 -070085#define kArenaBitVectorGrowth 4 /* increase by 4 u4s when limit hit */
86
87/* Allocate the initial memory block for arena-based allocation */
buzbeeba938cb2012-02-03 14:47:55 -080088bool oatHeapInit(CompilationUnit* cUnit)
buzbee67bf8852011-08-17 17:51:35 -070089{
buzbeeba938cb2012-02-03 14:47:55 -080090 DCHECK(cUnit->arenaHead == NULL);
91 cUnit->arenaHead =
buzbee67bf8852011-08-17 17:51:35 -070092 (ArenaMemBlock *) malloc(sizeof(ArenaMemBlock) + ARENA_DEFAULT_SIZE);
buzbeeba938cb2012-02-03 14:47:55 -080093 if (cUnit->arenaHead == NULL) {
buzbee67bf8852011-08-17 17:51:35 -070094 LOG(FATAL) << "No memory left to create compiler heap memory";
95 }
buzbeeba938cb2012-02-03 14:47:55 -080096 cUnit->arenaHead->blockSize = ARENA_DEFAULT_SIZE;
97 cUnit->currentArena = cUnit->arenaHead;
98 cUnit->currentArena->bytesAllocated = 0;
99 cUnit->currentArena->next = NULL;
100 cUnit->numArenaBlocks = 1;
101#ifdef WITH_MEMSTATS
102 cUnit->mstats = (Memstats*) oatNew(cUnit, sizeof(Memstats), true,
103 kAllocDebugInfo);
104#endif
buzbee67bf8852011-08-17 17:51:35 -0700105 return true;
106}
107
108/* Arena-based malloc for compilation tasks */
buzbeeba938cb2012-02-03 14:47:55 -0800109void* oatNew(CompilationUnit* cUnit, size_t size, bool zero, oatAllocKind kind)
buzbee67bf8852011-08-17 17:51:35 -0700110{
111 size = (size + 3) & ~3;
buzbee5abfa3e2012-01-31 17:01:43 -0800112#ifdef WITH_MEMSTATS
buzbeeba938cb2012-02-03 14:47:55 -0800113 if (cUnit->mstats != NULL) {
114 cUnit->mstats->allocStats[kind] += size;
115 }
buzbee5abfa3e2012-01-31 17:01:43 -0800116#endif
buzbee67bf8852011-08-17 17:51:35 -0700117retry:
118 /* Normal case - space is available in the current page */
buzbeeba938cb2012-02-03 14:47:55 -0800119 if (size + cUnit->currentArena->bytesAllocated <=
120 cUnit->currentArena->blockSize) {
buzbee67bf8852011-08-17 17:51:35 -0700121 void *ptr;
buzbeeba938cb2012-02-03 14:47:55 -0800122 ptr = &cUnit->currentArena->ptr[cUnit->currentArena->bytesAllocated];
123 cUnit->currentArena->bytesAllocated += size;
buzbee67bf8852011-08-17 17:51:35 -0700124 if (zero) {
125 memset(ptr, 0, size);
126 }
127 return ptr;
128 } else {
129 /*
130 * See if there are previously allocated arena blocks before the last
131 * reset
132 */
buzbeeba938cb2012-02-03 14:47:55 -0800133 if (cUnit->currentArena->next) {
134 cUnit->currentArena = cUnit->currentArena->next;
135 cUnit->currentArena->bytesAllocated = 0;
buzbee67bf8852011-08-17 17:51:35 -0700136 goto retry;
137 }
138
139 size_t blockSize = (size < ARENA_DEFAULT_SIZE) ?
140 ARENA_DEFAULT_SIZE : size;
141 /* Time to allocate a new arena */
142 ArenaMemBlock *newArena = (ArenaMemBlock *)
143 malloc(sizeof(ArenaMemBlock) + blockSize);
144 if (newArena == NULL) {
145 LOG(FATAL) << "Arena allocation failure";
146 }
147 newArena->blockSize = blockSize;
148 newArena->bytesAllocated = 0;
149 newArena->next = NULL;
buzbeeba938cb2012-02-03 14:47:55 -0800150 cUnit->currentArena->next = newArena;
151 cUnit->currentArena = newArena;
152 cUnit->numArenaBlocks++;
153 if (cUnit->numArenaBlocks > 20000) {
154 LOG(INFO) << "Total arena pages: " << cUnit->numArenaBlocks;
buzbee67bf8852011-08-17 17:51:35 -0700155 }
156 goto retry;
157 }
158}
159
160/* Reclaim all the arena blocks allocated so far */
buzbeeba938cb2012-02-03 14:47:55 -0800161void oatArenaReset(CompilationUnit* cUnit)
buzbee67bf8852011-08-17 17:51:35 -0700162{
buzbeeba938cb2012-02-03 14:47:55 -0800163 ArenaMemBlock* head = cUnit->arenaHead;
164 while (head != NULL) {
165 ArenaMemBlock* p = head;
166 head = head->next;
167 free(p);
buzbee67bc2362011-10-11 18:08:40 -0700168 }
buzbeeba938cb2012-02-03 14:47:55 -0800169 cUnit->arenaHead = NULL;
170 cUnit->currentArena = NULL;
buzbee67bf8852011-08-17 17:51:35 -0700171}
172
173/* Growable List initialization */
buzbeeba938cb2012-02-03 14:47:55 -0800174void oatInitGrowableList(CompilationUnit* cUnit, GrowableList* gList,
175 size_t initLength, oatListKind kind)
buzbee67bf8852011-08-17 17:51:35 -0700176{
177 gList->numAllocated = initLength;
178 gList->numUsed = 0;
buzbeeba938cb2012-02-03 14:47:55 -0800179 gList->elemList = (intptr_t *) oatNew(cUnit, sizeof(intptr_t) * initLength,
180 true, kAllocGrowableList);
buzbee5abfa3e2012-01-31 17:01:43 -0800181#ifdef WITH_MEMSTATS
buzbeeba938cb2012-02-03 14:47:55 -0800182 cUnit->mstats->listSizes[kind] += sizeof(intptr_t) * initLength;
buzbee5abfa3e2012-01-31 17:01:43 -0800183 gList->kind = kind;
buzbeeba938cb2012-02-03 14:47:55 -0800184 if ((int)initLength > cUnit->mstats->listMaxElems[kind]) {
185 cUnit->mstats->listMaxElems[kind] = initLength;
buzbee5abfa3e2012-01-31 17:01:43 -0800186 }
187#endif
buzbee67bf8852011-08-17 17:51:35 -0700188}
189
190/* Expand the capacity of a growable list */
buzbeeba938cb2012-02-03 14:47:55 -0800191STATIC void expandGrowableList(CompilationUnit* cUnit, GrowableList* gList)
buzbee67bf8852011-08-17 17:51:35 -0700192{
193 int newLength = gList->numAllocated;
194 if (newLength < 128) {
195 newLength <<= 1;
196 } else {
197 newLength += 128;
198 }
199 intptr_t *newArray =
buzbeeba938cb2012-02-03 14:47:55 -0800200 (intptr_t *) oatNew(cUnit, sizeof(intptr_t) * newLength, true,
buzbee5abfa3e2012-01-31 17:01:43 -0800201 kAllocGrowableList);
buzbee67bf8852011-08-17 17:51:35 -0700202 memcpy(newArray, gList->elemList, sizeof(intptr_t) * gList->numAllocated);
buzbee5abfa3e2012-01-31 17:01:43 -0800203#ifdef WITH_MEMSTATS
buzbeeba938cb2012-02-03 14:47:55 -0800204 cUnit->mstats->listSizes[gList->kind] += sizeof(intptr_t) * newLength;
205 cUnit->mstats->listWasted[gList->kind] +=
206 sizeof(intptr_t) * gList->numAllocated;
207 cUnit->mstats->listGrows[gList->kind]++;
208 if (newLength > cUnit->mstats->listMaxElems[gList->kind]) {
209 cUnit->mstats->listMaxElems[gList->kind] = newLength;
buzbee5abfa3e2012-01-31 17:01:43 -0800210 }
211#endif
buzbee67bf8852011-08-17 17:51:35 -0700212 gList->numAllocated = newLength;
213 gList->elemList = newArray;
214}
215
216/* Insert a new element into the growable list */
buzbeeba938cb2012-02-03 14:47:55 -0800217void oatInsertGrowableList(CompilationUnit* cUnit, GrowableList* gList,
218 intptr_t elem)
buzbee67bf8852011-08-17 17:51:35 -0700219{
Elliott Hughesf5a7a472011-10-07 14:31:02 -0700220 DCHECK_NE(gList->numAllocated, 0U);
buzbee67bf8852011-08-17 17:51:35 -0700221 if (gList->numUsed == gList->numAllocated) {
buzbeeba938cb2012-02-03 14:47:55 -0800222 expandGrowableList(cUnit, gList);
buzbee67bf8852011-08-17 17:51:35 -0700223 }
224 gList->elemList[gList->numUsed++] = elem;
225}
226
buzbee5abfa3e2012-01-31 17:01:43 -0800227/* Delete an element from a growable list. Element must be present */
228void oatDeleteGrowableList(GrowableList* gList, intptr_t elem)
229{
230 bool found = false;
231 for (unsigned int i = 0; i < gList->numUsed; i++) {
232 if (!found && gList->elemList[i] == elem) {
233 found = true;
234 }
235 if (found) {
236 gList->elemList[i] = gList->elemList[i+1];
237 }
238 }
239 DCHECK_EQ(found, true);
240 gList->numUsed--;
241}
242
buzbee67bf8852011-08-17 17:51:35 -0700243void oatGrowableListIteratorInit(GrowableList* gList,
244 GrowableListIterator* iterator)
245{
246 iterator->list = gList;
247 iterator->idx = 0;
248 iterator->size = gList->numUsed;
249}
250
251intptr_t oatGrowableListIteratorNext(GrowableListIterator* iterator)
252{
buzbeeed3e9302011-09-23 17:34:19 -0700253 DCHECK_EQ(iterator->size, iterator->list->numUsed);
buzbee67bf8852011-08-17 17:51:35 -0700254 if (iterator->idx == iterator->size) return 0;
255 return iterator->list->elemList[iterator->idx++];
256}
257
258intptr_t oatGrowableListGetElement(const GrowableList* gList, size_t idx)
259{
buzbeeed3e9302011-09-23 17:34:19 -0700260 DCHECK_LT(idx, gList->numUsed);
buzbee67bf8852011-08-17 17:51:35 -0700261 return gList->elemList[idx];
262}
263
buzbee5abfa3e2012-01-31 17:01:43 -0800264#ifdef WITH_MEMSTATS
265/* Dump memory usage stats */
266void oatDumpMemStats(CompilationUnit* cUnit)
267{
268 u4 total = 0;
269 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeeba938cb2012-02-03 14:47:55 -0800270 total += cUnit->mstats->allocStats[i];
buzbee5abfa3e2012-01-31 17:01:43 -0800271 }
272 if (total > (10 * 1024 * 1024)) {
273 LOG(INFO) << "MEMUSAGE: " << total << " : "
274 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
275 LOG(INFO) << "insnsSize: " << cUnit->insnsSize;
276 if (cUnit->disableDataflow) {
277 LOG(INFO) << " ** Dataflow disabled ** ";
278 }
279 LOG(INFO) << "===== Overall allocations";
280 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeeba938cb2012-02-03 14:47:55 -0800281 LOG(INFO) << allocNames[i] << std::setw(10) <<
282 cUnit->mstats->allocStats[i];
buzbee5abfa3e2012-01-31 17:01:43 -0800283 }
284 LOG(INFO) << "===== GrowableList allocations";
285 for (int i = 0; i < kNumListKinds; i++) {
286 LOG(INFO) << listNames[i]
buzbeeba938cb2012-02-03 14:47:55 -0800287 << " S:" << cUnit->mstats->listSizes[i]
288 << ", W:" << cUnit->mstats->listWasted[i]
289 << ", G:" << cUnit->mstats->listGrows[i]
290 << ", E:" << cUnit->mstats->listMaxElems[i];
buzbee5abfa3e2012-01-31 17:01:43 -0800291 }
292 LOG(INFO) << "===== GrowableBitMap allocations";
293 for (int i = 0; i < kNumBitMapKinds; i++) {
294 LOG(INFO) << bitMapNames[i]
buzbeeba938cb2012-02-03 14:47:55 -0800295 << " S:" << cUnit->mstats->bitMapSizes[i]
296 << ", W:" << cUnit->mstats->bitMapWasted[i]
297 << ", G:" << cUnit->mstats->bitMapGrows[i];
buzbee5abfa3e2012-01-31 17:01:43 -0800298 }
299 }
300}
301#endif
302
buzbee67bf8852011-08-17 17:51:35 -0700303/* Debug Utility - dump a compilation unit */
304void oatDumpCompilationUnit(CompilationUnit* cUnit)
305{
306 BasicBlock* bb;
307 const char* blockTypeNames[] = {
308 "Entry Block",
309 "Code Block",
310 "Exit Block",
311 "Exception Handling",
312 "Catch Block"
313 };
314
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800315 LOG(INFO) << "Compiling " << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
buzbee67bf8852011-08-17 17:51:35 -0700316 LOG(INFO) << cUnit->insns << " insns";
317 LOG(INFO) << cUnit->numBlocks << " blocks in total";
318 GrowableListIterator iterator;
319
320 oatGrowableListIteratorInit(&cUnit->blockList, &iterator);
321
322 while (true) {
323 bb = (BasicBlock *) oatGrowableListIteratorNext(&iterator);
324 if (bb == NULL) break;
325 char buf[100];
326 snprintf(buf, 100, "Block %d (%s) (insn %04x - %04x%s)",
327 bb->id,
328 blockTypeNames[bb->blockType],
329 bb->startOffset,
330 bb->lastMIRInsn ? bb->lastMIRInsn->offset : bb->startOffset,
331 bb->lastMIRInsn ? "" : " empty");
332 LOG(INFO) << buf;
333 if (bb->taken) {
334 LOG(INFO) << " Taken branch: block " << bb->taken->id <<
335 "(0x" << std::hex << bb->taken->startOffset << ")";
336 }
337 if (bb->fallThrough) {
338 LOG(INFO) << " Fallthrough : block " << bb->fallThrough->id <<
339 " (0x" << std::hex << bb->fallThrough->startOffset << ")";
340 }
341 }
342}
343
344/*
345 * Dump the current stats of the compiler.
346 */
347void oatDumpStats(void)
348{
349 oatArchDump();
350}
351
buzbee67bc2362011-10-11 18:08:40 -0700352static uint32_t checkMasks[32] = {
353 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
354 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
355 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
356 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000,
357 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000,
358 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
359 0x40000000, 0x80000000 };
360
buzbee67bf8852011-08-17 17:51:35 -0700361/*
362 * Allocate a bit vector with enough space to hold at least the specified
363 * number of bits.
364 *
365 * NOTE: memory is allocated from the compiler arena.
366 */
buzbeeba938cb2012-02-03 14:47:55 -0800367ArenaBitVector* oatAllocBitVector(CompilationUnit* cUnit,
368 unsigned int startBits, bool expandable,
buzbee5abfa3e2012-01-31 17:01:43 -0800369 oatBitMapKind kind)
buzbee67bf8852011-08-17 17:51:35 -0700370{
371 ArenaBitVector* bv;
372 unsigned int count;
373
Elliott Hughesf5a7a472011-10-07 14:31:02 -0700374 DCHECK_EQ(sizeof(bv->storage[0]), 4U); /* assuming 32-bit units */
buzbee67bf8852011-08-17 17:51:35 -0700375
buzbeeba938cb2012-02-03 14:47:55 -0800376 bv = (ArenaBitVector*) oatNew(cUnit, sizeof(ArenaBitVector), false,
buzbee5abfa3e2012-01-31 17:01:43 -0800377 kAllocGrowableBitMap);
buzbee67bf8852011-08-17 17:51:35 -0700378
379 count = (startBits + 31) >> 5;
380
381 bv->storageSize = count;
382 bv->expandable = expandable;
buzbeeba938cb2012-02-03 14:47:55 -0800383 bv->storage = (u4*) oatNew(cUnit, count * sizeof(u4), true,
384 kAllocGrowableBitMap);
buzbee5abfa3e2012-01-31 17:01:43 -0800385#ifdef WITH_MEMSTATS
386 bv->kind = kind;
buzbeeba938cb2012-02-03 14:47:55 -0800387 cUnit->mstats->bitMapSizes[kind] += count * sizeof(u4);
buzbee5abfa3e2012-01-31 17:01:43 -0800388#endif
buzbee67bf8852011-08-17 17:51:35 -0700389 return bv;
390}
391
392/*
393 * Determine whether or not the specified bit is set.
394 */
395bool oatIsBitSet(const ArenaBitVector* pBits, unsigned int num)
396{
buzbeeed3e9302011-09-23 17:34:19 -0700397 DCHECK_LT(num, pBits->storageSize * sizeof(u4) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700398
buzbee67bc2362011-10-11 18:08:40 -0700399 unsigned int val = pBits->storage[num >> 5] & checkMasks[num & 0x1f];
buzbee67bf8852011-08-17 17:51:35 -0700400 return (val != 0);
401}
402
403/*
404 * Mark all bits bit as "clear".
405 */
406void oatClearAllBits(ArenaBitVector* pBits)
407{
408 unsigned int count = pBits->storageSize;
409 memset(pBits->storage, 0, count * sizeof(u4));
410}
411
412/*
413 * Mark the specified bit as "set".
414 *
415 * Returns "false" if the bit is outside the range of the vector and we're
416 * not allowed to expand.
417 *
418 * NOTE: memory is allocated from the compiler arena.
419 */
buzbeeba938cb2012-02-03 14:47:55 -0800420bool oatSetBit(CompilationUnit* cUnit, ArenaBitVector* pBits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700421{
422 if (num >= pBits->storageSize * sizeof(u4) * 8) {
423 if (!pBits->expandable) {
424 LOG(FATAL) << "Can't expand";
425 }
426
427 /* Round up to word boundaries for "num+1" bits */
428 unsigned int newSize = (num + 1 + 31) >> 5;
buzbeeed3e9302011-09-23 17:34:19 -0700429 DCHECK_GT(newSize, pBits->storageSize);
buzbeeba938cb2012-02-03 14:47:55 -0800430 u4 *newStorage = (u4*)oatNew(cUnit, newSize * sizeof(u4), false,
buzbee5abfa3e2012-01-31 17:01:43 -0800431 kAllocGrowableBitMap);
buzbee67bf8852011-08-17 17:51:35 -0700432 memcpy(newStorage, pBits->storage, pBits->storageSize * sizeof(u4));
433 memset(&newStorage[pBits->storageSize], 0,
434 (newSize - pBits->storageSize) * sizeof(u4));
buzbee5abfa3e2012-01-31 17:01:43 -0800435#ifdef WITH_MEMSTATS
buzbeeba938cb2012-02-03 14:47:55 -0800436 cUnit->mstats->bitMapWasted[pBits->kind] +=
437 pBits->storageSize * sizeof(u4);
438 cUnit->mstats->bitMapSizes[pBits->kind] += newSize * sizeof(u4);
439 cUnit->mstats->bitMapGrows[pBits->kind]++;
buzbee5abfa3e2012-01-31 17:01:43 -0800440#endif
buzbee67bf8852011-08-17 17:51:35 -0700441 pBits->storage = newStorage;
442 pBits->storageSize = newSize;
443 }
444
buzbee67bc2362011-10-11 18:08:40 -0700445 pBits->storage[num >> 5] |= checkMasks[num & 0x1f];
buzbee67bf8852011-08-17 17:51:35 -0700446 return true;
447}
448
449/*
450 * Mark the specified bit as "unset".
451 *
452 * Returns "false" if the bit is outside the range of the vector and we're
453 * not allowed to expand.
454 *
455 * NOTE: memory is allocated from the compiler arena.
456 */
457bool oatClearBit(ArenaBitVector* pBits, unsigned int num)
458{
459 if (num >= pBits->storageSize * sizeof(u4) * 8) {
460 LOG(FATAL) << "Attempt to clear a bit not set in the vector yet";;
461 }
462
buzbee67bc2362011-10-11 18:08:40 -0700463 pBits->storage[num >> 5] &= ~checkMasks[num & 0x1f];
buzbee67bf8852011-08-17 17:51:35 -0700464 return true;
465}
466
467/*
468 * If set is true, mark all bits as 1. Otherwise mark all bits as 0.
469 */
470void oatMarkAllBits(ArenaBitVector* pBits, bool set)
471{
472 int value = set ? -1 : 0;
473 memset(pBits->storage, value, pBits->storageSize * (int)sizeof(u4));
474}
475
476void oatDebugBitVector(char* msg, const ArenaBitVector* bv, int length)
477{
478 int i;
479
480 LOG(INFO) << msg;
481 for (i = 0; i < length; i++) {
482 if (oatIsBitSet(bv, i)) {
483 LOG(INFO) << " Bit " << i << " is set";
484 }
485 }
486}
487
488void oatAbort(CompilationUnit* cUnit)
489{
490 LOG(FATAL) << "Compiler aborting";
491}
492
493void oatDumpBlockBitVector(const GrowableList* blocks, char* msg,
494 const ArenaBitVector* bv, int length)
495{
496 int i;
497
498 LOG(INFO) << msg;
499 for (i = 0; i < length; i++) {
500 if (oatIsBitSet(bv, i)) {
501 BasicBlock *bb =
502 (BasicBlock *) oatGrowableListGetElement(blocks, i);
503 char blockName[BLOCK_NAME_LEN];
504 oatGetBlockName(bb, blockName);
505 LOG(INFO) << "Bit " << i << " / " << blockName << " is set";
506 }
507 }
508}
509/* Initialize the iterator structure */
510void oatBitVectorIteratorInit(ArenaBitVector* pBits,
511 ArenaBitVectorIterator* iterator)
512{
513 iterator->pBits = pBits;
514 iterator->bitSize = pBits->storageSize * sizeof(u4) * 8;
515 iterator->idx = 0;
516}
517
518/*
519 * If the vector sizes don't match, log an error and abort.
520 */
buzbeeed3e9302011-09-23 17:34:19 -0700521STATIC void checkSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
buzbee67bf8852011-08-17 17:51:35 -0700522{
523 if (bv1->storageSize != bv2->storageSize) {
524 LOG(FATAL) << "Mismatched vector sizes (" << bv1->storageSize <<
525 ", " << bv2->storageSize << ")";
526 }
527}
528
529/*
530 * Copy a whole vector to the other. Only do that when the both vectors have
531 * the same size.
532 */
533void oatCopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src)
534{
535 /* if dest is expandable and < src, we could expand dest to match */
536 checkSizes(dest, src);
537
538 memcpy(dest->storage, src->storage, sizeof(u4) * dest->storageSize);
539}
540
541/*
542 * Intersect two bit vectors and store the result to the dest vector.
543 */
544
545bool oatIntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
546 const ArenaBitVector* src2)
547{
buzbeeaad72012011-09-21 21:52:09 -0700548 DCHECK(src1 != NULL);
549 DCHECK(src2 != NULL);
550 if (dest->storageSize != src1->storageSize ||
buzbee67bf8852011-08-17 17:51:35 -0700551 dest->storageSize != src2->storageSize ||
552 dest->expandable != src1->expandable ||
553 dest->expandable != src2->expandable)
554 return false;
555
556 unsigned int idx;
557 for (idx = 0; idx < dest->storageSize; idx++) {
558 dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
559 }
560 return true;
561}
562
563/*
564 * Unify two bit vectors and store the result to the dest vector.
565 */
566bool oatUnifyBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
567 const ArenaBitVector* src2)
568{
buzbeeaad72012011-09-21 21:52:09 -0700569 DCHECK(src1 != NULL);
570 DCHECK(src2 != NULL);
571 if (dest->storageSize != src1->storageSize ||
buzbee67bf8852011-08-17 17:51:35 -0700572 dest->storageSize != src2->storageSize ||
573 dest->expandable != src1->expandable ||
574 dest->expandable != src2->expandable)
575 return false;
576
577 unsigned int idx;
578 for (idx = 0; idx < dest->storageSize; idx++) {
579 dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
580 }
581 return true;
582}
583
584/*
585 * Compare two bit vectors and return true if difference is seen.
586 */
587bool oatCompareBitVectors(const ArenaBitVector* src1,
588 const ArenaBitVector* src2)
589{
590 if (src1->storageSize != src2->storageSize ||
591 src1->expandable != src2->expandable)
592 return true;
593
594 unsigned int idx;
595 for (idx = 0; idx < src1->storageSize; idx++) {
596 if (src1->storage[idx] != src2->storage[idx]) return true;
597 }
598 return false;
599}
600
601/*
602 * Count the number of bits that are set.
603 */
604int oatCountSetBits(const ArenaBitVector* pBits)
605{
606 unsigned int word;
607 unsigned int count = 0;
608
609 for (word = 0; word < pBits->storageSize; word++) {
610 u4 val = pBits->storage[word];
611
612 if (val != 0) {
613 if (val == 0xffffffff) {
614 count += 32;
615 } else {
616 /* count the number of '1' bits */
617 while (val != 0) {
618 val &= val - 1;
619 count++;
620 }
621 }
622 }
623 }
624
625 return count;
626}
627
628/* Return the next position set to 1. -1 means end-of-element reached */
629int oatBitVectorIteratorNext(ArenaBitVectorIterator* iterator)
630{
buzbee5b537102012-01-17 17:33:47 -0800631 ArenaBitVector* pBits = iterator->pBits;
buzbee67bf8852011-08-17 17:51:35 -0700632 u4 bitIndex = iterator->idx;
buzbee5abfa3e2012-01-31 17:01:43 -0800633 u4 bitSize = iterator->bitSize;
buzbee67bf8852011-08-17 17:51:35 -0700634
buzbee5abfa3e2012-01-31 17:01:43 -0800635 DCHECK_EQ(bitSize, pBits->storageSize * sizeof(u4) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700636
buzbee5abfa3e2012-01-31 17:01:43 -0800637 if (bitIndex >= bitSize) return -1;
buzbee5b537102012-01-17 17:33:47 -0800638
buzbee5abfa3e2012-01-31 17:01:43 -0800639 u4 wordIndex = bitIndex >> 5;
640 u4 endWordIndex = bitSize >> 5;
641 u4* storage = pBits->storage;
642 u4 word = storage[wordIndex++];
buzbee5b537102012-01-17 17:33:47 -0800643
buzbee5abfa3e2012-01-31 17:01:43 -0800644 // Mask out any bits in the first word we've already considered
645 word &= ~((1 << (bitIndex & 0x1f))-1);
646
647 for (; wordIndex <= endWordIndex;) {
648 u4 bitPos = bitIndex & 0x1f;
buzbee67bc2362011-10-11 18:08:40 -0700649 if (word == 0) {
buzbee67bc2362011-10-11 18:08:40 -0700650 bitIndex += (32 - bitPos);
buzbee5abfa3e2012-01-31 17:01:43 -0800651 word = storage[wordIndex++];
652 continue;
653 }
654 for (; bitPos < 32; bitPos++) {
655 if (word & (1 << bitPos)) {
656 iterator->idx = bitIndex + 1;
657 return bitIndex;
658 }
buzbee67bc2362011-10-11 18:08:40 -0700659 bitIndex++;
660 }
buzbee5abfa3e2012-01-31 17:01:43 -0800661 word = storage[wordIndex++];
buzbee67bf8852011-08-17 17:51:35 -0700662 }
buzbee5abfa3e2012-01-31 17:01:43 -0800663 iterator->idx = iterator->bitSize;
buzbee67bf8852011-08-17 17:51:35 -0700664 return -1;
665}
666
667/*
668 * Mark specified number of bits as "set". Cannot set all bits like ClearAll
669 * since there might be unused bits - setting those to one will confuse the
670 * iterator.
671 */
672void oatSetInitialBits(ArenaBitVector* pBits, unsigned int numBits)
673{
674 unsigned int idx;
buzbeeed3e9302011-09-23 17:34:19 -0700675 DCHECK_LE(((numBits + 31) >> 5), pBits->storageSize);
buzbee67bf8852011-08-17 17:51:35 -0700676 for (idx = 0; idx < (numBits >> 5); idx++) {
677 pBits->storage[idx] = -1;
678 }
679 unsigned int remNumBits = numBits & 0x1f;
680 if (remNumBits) {
681 pBits->storage[idx] = (1 << remNumBits) - 1;
682 }
683}
684
685void oatGetBlockName(BasicBlock* bb, char* name)
686{
687 switch (bb->blockType) {
688 case kEntryBlock:
689 snprintf(name, BLOCK_NAME_LEN, "entry");
690 break;
691 case kExitBlock:
692 snprintf(name, BLOCK_NAME_LEN, "exit");
693 break;
694 case kDalvikByteCode:
695 snprintf(name, BLOCK_NAME_LEN, "block%04x", bb->startOffset);
696 break;
697 case kExceptionHandling:
698 snprintf(name, BLOCK_NAME_LEN, "exception%04x", bb->startOffset);
699 break;
700 default:
701 snprintf(name, BLOCK_NAME_LEN, "??");
702 break;
703 }
704}
buzbeeed3e9302011-09-23 17:34:19 -0700705
706const char* oatGetShortyFromTargetIdx(CompilationUnit *cUnit, int targetIdx)
707{
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800708 const DexFile::MethodId& methodId = cUnit->dex_file->GetMethodId(targetIdx);
Ian Rogersa3760aa2011-11-14 14:32:37 -0800709 return cUnit->dex_file->GetShorty(methodId.proto_idx_);
buzbeeed3e9302011-09-23 17:34:19 -0700710}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800711
712} // namespace art