blob: f5b478c1b31995494fd7323e838c0ab6935934a6 [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
Elliott Hughes719ace42012-03-09 18:06:03 -080023struct Memstats {
buzbeeba938cb2012-02-03 14:47:55 -080024 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];
Elliott Hughes719ace42012-03-09 18:06:03 -080032};
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 */
buzbee31a4a6f2012-02-28 15:36:15 -0800191void 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;
Elliott Hughesbdf6c3d2012-03-20 13:43:53 -0700325 LOG(INFO) << StringPrintf("Block %d (%s) (insn %04x - %04x%s)",
buzbee67bf8852011-08-17 17:51:35 -0700326 bb->id,
327 blockTypeNames[bb->blockType],
328 bb->startOffset,
329 bb->lastMIRInsn ? bb->lastMIRInsn->offset : bb->startOffset,
330 bb->lastMIRInsn ? "" : " empty");
buzbee67bf8852011-08-17 17:51:35 -0700331 if (bb->taken) {
332 LOG(INFO) << " Taken branch: block " << bb->taken->id <<
333 "(0x" << std::hex << bb->taken->startOffset << ")";
334 }
335 if (bb->fallThrough) {
336 LOG(INFO) << " Fallthrough : block " << bb->fallThrough->id <<
337 " (0x" << std::hex << bb->fallThrough->startOffset << ")";
338 }
339 }
340}
341
buzbee67bc2362011-10-11 18:08:40 -0700342static uint32_t checkMasks[32] = {
343 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
344 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
345 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
346 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000,
347 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000,
348 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
349 0x40000000, 0x80000000 };
350
buzbee67bf8852011-08-17 17:51:35 -0700351/*
352 * Allocate a bit vector with enough space to hold at least the specified
353 * number of bits.
354 *
355 * NOTE: memory is allocated from the compiler arena.
356 */
buzbeeba938cb2012-02-03 14:47:55 -0800357ArenaBitVector* oatAllocBitVector(CompilationUnit* cUnit,
358 unsigned int startBits, bool expandable,
buzbee5abfa3e2012-01-31 17:01:43 -0800359 oatBitMapKind kind)
buzbee67bf8852011-08-17 17:51:35 -0700360{
361 ArenaBitVector* bv;
362 unsigned int count;
363
Elliott Hughesf5a7a472011-10-07 14:31:02 -0700364 DCHECK_EQ(sizeof(bv->storage[0]), 4U); /* assuming 32-bit units */
buzbee67bf8852011-08-17 17:51:35 -0700365
buzbeeba938cb2012-02-03 14:47:55 -0800366 bv = (ArenaBitVector*) oatNew(cUnit, sizeof(ArenaBitVector), false,
buzbee5abfa3e2012-01-31 17:01:43 -0800367 kAllocGrowableBitMap);
buzbee67bf8852011-08-17 17:51:35 -0700368
369 count = (startBits + 31) >> 5;
370
371 bv->storageSize = count;
372 bv->expandable = expandable;
buzbeeba938cb2012-02-03 14:47:55 -0800373 bv->storage = (u4*) oatNew(cUnit, count * sizeof(u4), true,
374 kAllocGrowableBitMap);
buzbee5abfa3e2012-01-31 17:01:43 -0800375#ifdef WITH_MEMSTATS
376 bv->kind = kind;
buzbeeba938cb2012-02-03 14:47:55 -0800377 cUnit->mstats->bitMapSizes[kind] += count * sizeof(u4);
buzbee5abfa3e2012-01-31 17:01:43 -0800378#endif
buzbee67bf8852011-08-17 17:51:35 -0700379 return bv;
380}
381
382/*
383 * Determine whether or not the specified bit is set.
384 */
385bool oatIsBitSet(const ArenaBitVector* pBits, unsigned int num)
386{
buzbeeed3e9302011-09-23 17:34:19 -0700387 DCHECK_LT(num, pBits->storageSize * sizeof(u4) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700388
buzbee67bc2362011-10-11 18:08:40 -0700389 unsigned int val = pBits->storage[num >> 5] & checkMasks[num & 0x1f];
buzbee67bf8852011-08-17 17:51:35 -0700390 return (val != 0);
391}
392
393/*
394 * Mark all bits bit as "clear".
395 */
396void oatClearAllBits(ArenaBitVector* pBits)
397{
398 unsigned int count = pBits->storageSize;
399 memset(pBits->storage, 0, count * sizeof(u4));
400}
401
402/*
403 * Mark the specified bit as "set".
404 *
405 * Returns "false" if the bit is outside the range of the vector and we're
406 * not allowed to expand.
407 *
408 * NOTE: memory is allocated from the compiler arena.
409 */
buzbeeba938cb2012-02-03 14:47:55 -0800410bool oatSetBit(CompilationUnit* cUnit, ArenaBitVector* pBits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700411{
412 if (num >= pBits->storageSize * sizeof(u4) * 8) {
413 if (!pBits->expandable) {
414 LOG(FATAL) << "Can't expand";
415 }
416
417 /* Round up to word boundaries for "num+1" bits */
418 unsigned int newSize = (num + 1 + 31) >> 5;
buzbeeed3e9302011-09-23 17:34:19 -0700419 DCHECK_GT(newSize, pBits->storageSize);
buzbeeba938cb2012-02-03 14:47:55 -0800420 u4 *newStorage = (u4*)oatNew(cUnit, newSize * sizeof(u4), false,
buzbee5abfa3e2012-01-31 17:01:43 -0800421 kAllocGrowableBitMap);
buzbee67bf8852011-08-17 17:51:35 -0700422 memcpy(newStorage, pBits->storage, pBits->storageSize * sizeof(u4));
423 memset(&newStorage[pBits->storageSize], 0,
424 (newSize - pBits->storageSize) * sizeof(u4));
buzbee5abfa3e2012-01-31 17:01:43 -0800425#ifdef WITH_MEMSTATS
buzbeeba938cb2012-02-03 14:47:55 -0800426 cUnit->mstats->bitMapWasted[pBits->kind] +=
427 pBits->storageSize * sizeof(u4);
428 cUnit->mstats->bitMapSizes[pBits->kind] += newSize * sizeof(u4);
429 cUnit->mstats->bitMapGrows[pBits->kind]++;
buzbee5abfa3e2012-01-31 17:01:43 -0800430#endif
buzbee67bf8852011-08-17 17:51:35 -0700431 pBits->storage = newStorage;
432 pBits->storageSize = newSize;
433 }
434
buzbee67bc2362011-10-11 18:08:40 -0700435 pBits->storage[num >> 5] |= checkMasks[num & 0x1f];
buzbee67bf8852011-08-17 17:51:35 -0700436 return true;
437}
438
439/*
440 * Mark the specified bit as "unset".
441 *
442 * Returns "false" if the bit is outside the range of the vector and we're
443 * not allowed to expand.
444 *
445 * NOTE: memory is allocated from the compiler arena.
446 */
447bool oatClearBit(ArenaBitVector* pBits, unsigned int num)
448{
449 if (num >= pBits->storageSize * sizeof(u4) * 8) {
450 LOG(FATAL) << "Attempt to clear a bit not set in the vector yet";;
451 }
452
buzbee67bc2362011-10-11 18:08:40 -0700453 pBits->storage[num >> 5] &= ~checkMasks[num & 0x1f];
buzbee67bf8852011-08-17 17:51:35 -0700454 return true;
455}
456
457/*
458 * If set is true, mark all bits as 1. Otherwise mark all bits as 0.
459 */
460void oatMarkAllBits(ArenaBitVector* pBits, bool set)
461{
462 int value = set ? -1 : 0;
463 memset(pBits->storage, value, pBits->storageSize * (int)sizeof(u4));
464}
465
466void oatDebugBitVector(char* msg, const ArenaBitVector* bv, int length)
467{
468 int i;
469
470 LOG(INFO) << msg;
471 for (i = 0; i < length; i++) {
472 if (oatIsBitSet(bv, i)) {
473 LOG(INFO) << " Bit " << i << " is set";
474 }
475 }
476}
477
478void oatAbort(CompilationUnit* cUnit)
479{
480 LOG(FATAL) << "Compiler aborting";
481}
482
483void oatDumpBlockBitVector(const GrowableList* blocks, char* msg,
484 const ArenaBitVector* bv, int length)
485{
486 int i;
487
488 LOG(INFO) << msg;
489 for (i = 0; i < length; i++) {
490 if (oatIsBitSet(bv, i)) {
491 BasicBlock *bb =
492 (BasicBlock *) oatGrowableListGetElement(blocks, i);
493 char blockName[BLOCK_NAME_LEN];
494 oatGetBlockName(bb, blockName);
495 LOG(INFO) << "Bit " << i << " / " << blockName << " is set";
496 }
497 }
498}
499/* Initialize the iterator structure */
500void oatBitVectorIteratorInit(ArenaBitVector* pBits,
501 ArenaBitVectorIterator* iterator)
502{
503 iterator->pBits = pBits;
504 iterator->bitSize = pBits->storageSize * sizeof(u4) * 8;
505 iterator->idx = 0;
506}
507
508/*
509 * If the vector sizes don't match, log an error and abort.
510 */
buzbee31a4a6f2012-02-28 15:36:15 -0800511void checkSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
buzbee67bf8852011-08-17 17:51:35 -0700512{
513 if (bv1->storageSize != bv2->storageSize) {
514 LOG(FATAL) << "Mismatched vector sizes (" << bv1->storageSize <<
515 ", " << bv2->storageSize << ")";
516 }
517}
518
519/*
520 * Copy a whole vector to the other. Only do that when the both vectors have
521 * the same size.
522 */
523void oatCopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src)
524{
525 /* if dest is expandable and < src, we could expand dest to match */
526 checkSizes(dest, src);
527
528 memcpy(dest->storage, src->storage, sizeof(u4) * dest->storageSize);
529}
530
531/*
532 * Intersect two bit vectors and store the result to the dest vector.
533 */
534
535bool oatIntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
536 const ArenaBitVector* src2)
537{
buzbeeaad72012011-09-21 21:52:09 -0700538 DCHECK(src1 != NULL);
539 DCHECK(src2 != NULL);
540 if (dest->storageSize != src1->storageSize ||
buzbee67bf8852011-08-17 17:51:35 -0700541 dest->storageSize != src2->storageSize ||
542 dest->expandable != src1->expandable ||
543 dest->expandable != src2->expandable)
544 return false;
545
546 unsigned int idx;
547 for (idx = 0; idx < dest->storageSize; idx++) {
548 dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
549 }
550 return true;
551}
552
553/*
554 * Unify two bit vectors and store the result to the dest vector.
555 */
556bool oatUnifyBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
557 const ArenaBitVector* src2)
558{
buzbeeaad72012011-09-21 21:52:09 -0700559 DCHECK(src1 != NULL);
560 DCHECK(src2 != NULL);
561 if (dest->storageSize != src1->storageSize ||
buzbee67bf8852011-08-17 17:51:35 -0700562 dest->storageSize != src2->storageSize ||
563 dest->expandable != src1->expandable ||
564 dest->expandable != src2->expandable)
565 return false;
566
567 unsigned int idx;
568 for (idx = 0; idx < dest->storageSize; idx++) {
569 dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
570 }
571 return true;
572}
573
574/*
buzbeee1965672012-03-11 18:39:19 -0700575 * Return true if any bits collide. Vectors must be same size.
576 */
577bool oatTestBitVectors(const ArenaBitVector* src1,
578 const ArenaBitVector* src2)
579{
580 DCHECK_EQ(src1->storageSize, src2->storageSize);
581 for (uint32_t idx = 0; idx < src1->storageSize; idx++) {
582 if (src1->storage[idx] & src2->storage[idx]) return true;
583 }
584 return false;
585}
586
587/*
buzbee67bf8852011-08-17 17:51:35 -0700588 * Compare two bit vectors and return true if difference is seen.
589 */
590bool oatCompareBitVectors(const ArenaBitVector* src1,
591 const ArenaBitVector* src2)
592{
593 if (src1->storageSize != src2->storageSize ||
594 src1->expandable != src2->expandable)
595 return true;
596
597 unsigned int idx;
598 for (idx = 0; idx < src1->storageSize; idx++) {
599 if (src1->storage[idx] != src2->storage[idx]) return true;
600 }
601 return false;
602}
603
604/*
605 * Count the number of bits that are set.
606 */
607int oatCountSetBits(const ArenaBitVector* pBits)
608{
609 unsigned int word;
610 unsigned int count = 0;
611
612 for (word = 0; word < pBits->storageSize; word++) {
613 u4 val = pBits->storage[word];
614
615 if (val != 0) {
616 if (val == 0xffffffff) {
617 count += 32;
618 } else {
619 /* count the number of '1' bits */
620 while (val != 0) {
621 val &= val - 1;
622 count++;
623 }
624 }
625 }
626 }
627
628 return count;
629}
630
631/* Return the next position set to 1. -1 means end-of-element reached */
632int oatBitVectorIteratorNext(ArenaBitVectorIterator* iterator)
633{
buzbee5b537102012-01-17 17:33:47 -0800634 ArenaBitVector* pBits = iterator->pBits;
buzbee67bf8852011-08-17 17:51:35 -0700635 u4 bitIndex = iterator->idx;
buzbee5abfa3e2012-01-31 17:01:43 -0800636 u4 bitSize = iterator->bitSize;
buzbee67bf8852011-08-17 17:51:35 -0700637
buzbee5abfa3e2012-01-31 17:01:43 -0800638 DCHECK_EQ(bitSize, pBits->storageSize * sizeof(u4) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700639
buzbee5abfa3e2012-01-31 17:01:43 -0800640 if (bitIndex >= bitSize) return -1;
buzbee5b537102012-01-17 17:33:47 -0800641
buzbee5abfa3e2012-01-31 17:01:43 -0800642 u4 wordIndex = bitIndex >> 5;
643 u4 endWordIndex = bitSize >> 5;
644 u4* storage = pBits->storage;
645 u4 word = storage[wordIndex++];
buzbee5b537102012-01-17 17:33:47 -0800646
buzbee5abfa3e2012-01-31 17:01:43 -0800647 // Mask out any bits in the first word we've already considered
648 word &= ~((1 << (bitIndex & 0x1f))-1);
649
650 for (; wordIndex <= endWordIndex;) {
651 u4 bitPos = bitIndex & 0x1f;
buzbee67bc2362011-10-11 18:08:40 -0700652 if (word == 0) {
buzbee67bc2362011-10-11 18:08:40 -0700653 bitIndex += (32 - bitPos);
buzbee5abfa3e2012-01-31 17:01:43 -0800654 word = storage[wordIndex++];
655 continue;
656 }
657 for (; bitPos < 32; bitPos++) {
658 if (word & (1 << bitPos)) {
659 iterator->idx = bitIndex + 1;
660 return bitIndex;
661 }
buzbee67bc2362011-10-11 18:08:40 -0700662 bitIndex++;
663 }
buzbee5abfa3e2012-01-31 17:01:43 -0800664 word = storage[wordIndex++];
buzbee67bf8852011-08-17 17:51:35 -0700665 }
buzbee5abfa3e2012-01-31 17:01:43 -0800666 iterator->idx = iterator->bitSize;
buzbee67bf8852011-08-17 17:51:35 -0700667 return -1;
668}
669
670/*
671 * Mark specified number of bits as "set". Cannot set all bits like ClearAll
672 * since there might be unused bits - setting those to one will confuse the
673 * iterator.
674 */
675void oatSetInitialBits(ArenaBitVector* pBits, unsigned int numBits)
676{
677 unsigned int idx;
buzbeeed3e9302011-09-23 17:34:19 -0700678 DCHECK_LE(((numBits + 31) >> 5), pBits->storageSize);
buzbee67bf8852011-08-17 17:51:35 -0700679 for (idx = 0; idx < (numBits >> 5); idx++) {
680 pBits->storage[idx] = -1;
681 }
682 unsigned int remNumBits = numBits & 0x1f;
683 if (remNumBits) {
684 pBits->storage[idx] = (1 << remNumBits) - 1;
685 }
686}
687
688void oatGetBlockName(BasicBlock* bb, char* name)
689{
690 switch (bb->blockType) {
691 case kEntryBlock:
692 snprintf(name, BLOCK_NAME_LEN, "entry");
693 break;
694 case kExitBlock:
695 snprintf(name, BLOCK_NAME_LEN, "exit");
696 break;
697 case kDalvikByteCode:
698 snprintf(name, BLOCK_NAME_LEN, "block%04x", bb->startOffset);
699 break;
700 case kExceptionHandling:
701 snprintf(name, BLOCK_NAME_LEN, "exception%04x", bb->startOffset);
702 break;
703 default:
704 snprintf(name, BLOCK_NAME_LEN, "??");
705 break;
706 }
707}
buzbeeed3e9302011-09-23 17:34:19 -0700708
709const char* oatGetShortyFromTargetIdx(CompilationUnit *cUnit, int targetIdx)
710{
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800711 const DexFile::MethodId& methodId = cUnit->dex_file->GetMethodId(targetIdx);
Ian Rogersa3760aa2011-11-14 14:32:37 -0800712 return cUnit->dex_file->GetShorty(methodId.proto_idx_);
buzbeeed3e9302011-09-23 17:34:19 -0700713}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800714
715} // namespace art