blob: 3674aa929917924b027abf94b6deeb17280e9a1f [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;
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
buzbee67bc2362011-10-11 18:08:40 -0700344static uint32_t checkMasks[32] = {
345 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
346 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
347 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
348 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000,
349 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000,
350 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
351 0x40000000, 0x80000000 };
352
buzbee67bf8852011-08-17 17:51:35 -0700353/*
354 * Allocate a bit vector with enough space to hold at least the specified
355 * number of bits.
356 *
357 * NOTE: memory is allocated from the compiler arena.
358 */
buzbeeba938cb2012-02-03 14:47:55 -0800359ArenaBitVector* oatAllocBitVector(CompilationUnit* cUnit,
360 unsigned int startBits, bool expandable,
buzbee5abfa3e2012-01-31 17:01:43 -0800361 oatBitMapKind kind)
buzbee67bf8852011-08-17 17:51:35 -0700362{
363 ArenaBitVector* bv;
364 unsigned int count;
365
Elliott Hughesf5a7a472011-10-07 14:31:02 -0700366 DCHECK_EQ(sizeof(bv->storage[0]), 4U); /* assuming 32-bit units */
buzbee67bf8852011-08-17 17:51:35 -0700367
buzbeeba938cb2012-02-03 14:47:55 -0800368 bv = (ArenaBitVector*) oatNew(cUnit, sizeof(ArenaBitVector), false,
buzbee5abfa3e2012-01-31 17:01:43 -0800369 kAllocGrowableBitMap);
buzbee67bf8852011-08-17 17:51:35 -0700370
371 count = (startBits + 31) >> 5;
372
373 bv->storageSize = count;
374 bv->expandable = expandable;
buzbeeba938cb2012-02-03 14:47:55 -0800375 bv->storage = (u4*) oatNew(cUnit, count * sizeof(u4), true,
376 kAllocGrowableBitMap);
buzbee5abfa3e2012-01-31 17:01:43 -0800377#ifdef WITH_MEMSTATS
378 bv->kind = kind;
buzbeeba938cb2012-02-03 14:47:55 -0800379 cUnit->mstats->bitMapSizes[kind] += count * sizeof(u4);
buzbee5abfa3e2012-01-31 17:01:43 -0800380#endif
buzbee67bf8852011-08-17 17:51:35 -0700381 return bv;
382}
383
384/*
385 * Determine whether or not the specified bit is set.
386 */
387bool oatIsBitSet(const ArenaBitVector* pBits, unsigned int num)
388{
buzbeeed3e9302011-09-23 17:34:19 -0700389 DCHECK_LT(num, pBits->storageSize * sizeof(u4) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700390
buzbee67bc2362011-10-11 18:08:40 -0700391 unsigned int val = pBits->storage[num >> 5] & checkMasks[num & 0x1f];
buzbee67bf8852011-08-17 17:51:35 -0700392 return (val != 0);
393}
394
395/*
396 * Mark all bits bit as "clear".
397 */
398void oatClearAllBits(ArenaBitVector* pBits)
399{
400 unsigned int count = pBits->storageSize;
401 memset(pBits->storage, 0, count * sizeof(u4));
402}
403
404/*
405 * Mark the specified bit as "set".
406 *
407 * Returns "false" if the bit is outside the range of the vector and we're
408 * not allowed to expand.
409 *
410 * NOTE: memory is allocated from the compiler arena.
411 */
buzbeeba938cb2012-02-03 14:47:55 -0800412bool oatSetBit(CompilationUnit* cUnit, ArenaBitVector* pBits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700413{
414 if (num >= pBits->storageSize * sizeof(u4) * 8) {
415 if (!pBits->expandable) {
416 LOG(FATAL) << "Can't expand";
417 }
418
419 /* Round up to word boundaries for "num+1" bits */
420 unsigned int newSize = (num + 1 + 31) >> 5;
buzbeeed3e9302011-09-23 17:34:19 -0700421 DCHECK_GT(newSize, pBits->storageSize);
buzbeeba938cb2012-02-03 14:47:55 -0800422 u4 *newStorage = (u4*)oatNew(cUnit, newSize * sizeof(u4), false,
buzbee5abfa3e2012-01-31 17:01:43 -0800423 kAllocGrowableBitMap);
buzbee67bf8852011-08-17 17:51:35 -0700424 memcpy(newStorage, pBits->storage, pBits->storageSize * sizeof(u4));
425 memset(&newStorage[pBits->storageSize], 0,
426 (newSize - pBits->storageSize) * sizeof(u4));
buzbee5abfa3e2012-01-31 17:01:43 -0800427#ifdef WITH_MEMSTATS
buzbeeba938cb2012-02-03 14:47:55 -0800428 cUnit->mstats->bitMapWasted[pBits->kind] +=
429 pBits->storageSize * sizeof(u4);
430 cUnit->mstats->bitMapSizes[pBits->kind] += newSize * sizeof(u4);
431 cUnit->mstats->bitMapGrows[pBits->kind]++;
buzbee5abfa3e2012-01-31 17:01:43 -0800432#endif
buzbee67bf8852011-08-17 17:51:35 -0700433 pBits->storage = newStorage;
434 pBits->storageSize = newSize;
435 }
436
buzbee67bc2362011-10-11 18:08:40 -0700437 pBits->storage[num >> 5] |= checkMasks[num & 0x1f];
buzbee67bf8852011-08-17 17:51:35 -0700438 return true;
439}
440
441/*
442 * Mark the specified bit as "unset".
443 *
444 * Returns "false" if the bit is outside the range of the vector and we're
445 * not allowed to expand.
446 *
447 * NOTE: memory is allocated from the compiler arena.
448 */
449bool oatClearBit(ArenaBitVector* pBits, unsigned int num)
450{
451 if (num >= pBits->storageSize * sizeof(u4) * 8) {
452 LOG(FATAL) << "Attempt to clear a bit not set in the vector yet";;
453 }
454
buzbee67bc2362011-10-11 18:08:40 -0700455 pBits->storage[num >> 5] &= ~checkMasks[num & 0x1f];
buzbee67bf8852011-08-17 17:51:35 -0700456 return true;
457}
458
459/*
460 * If set is true, mark all bits as 1. Otherwise mark all bits as 0.
461 */
462void oatMarkAllBits(ArenaBitVector* pBits, bool set)
463{
464 int value = set ? -1 : 0;
465 memset(pBits->storage, value, pBits->storageSize * (int)sizeof(u4));
466}
467
468void oatDebugBitVector(char* msg, const ArenaBitVector* bv, int length)
469{
470 int i;
471
472 LOG(INFO) << msg;
473 for (i = 0; i < length; i++) {
474 if (oatIsBitSet(bv, i)) {
475 LOG(INFO) << " Bit " << i << " is set";
476 }
477 }
478}
479
480void oatAbort(CompilationUnit* cUnit)
481{
482 LOG(FATAL) << "Compiler aborting";
483}
484
485void oatDumpBlockBitVector(const GrowableList* blocks, char* msg,
486 const ArenaBitVector* bv, int length)
487{
488 int i;
489
490 LOG(INFO) << msg;
491 for (i = 0; i < length; i++) {
492 if (oatIsBitSet(bv, i)) {
493 BasicBlock *bb =
494 (BasicBlock *) oatGrowableListGetElement(blocks, i);
495 char blockName[BLOCK_NAME_LEN];
496 oatGetBlockName(bb, blockName);
497 LOG(INFO) << "Bit " << i << " / " << blockName << " is set";
498 }
499 }
500}
501/* Initialize the iterator structure */
502void oatBitVectorIteratorInit(ArenaBitVector* pBits,
503 ArenaBitVectorIterator* iterator)
504{
505 iterator->pBits = pBits;
506 iterator->bitSize = pBits->storageSize * sizeof(u4) * 8;
507 iterator->idx = 0;
508}
509
510/*
511 * If the vector sizes don't match, log an error and abort.
512 */
buzbee31a4a6f2012-02-28 15:36:15 -0800513void checkSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
buzbee67bf8852011-08-17 17:51:35 -0700514{
515 if (bv1->storageSize != bv2->storageSize) {
516 LOG(FATAL) << "Mismatched vector sizes (" << bv1->storageSize <<
517 ", " << bv2->storageSize << ")";
518 }
519}
520
521/*
522 * Copy a whole vector to the other. Only do that when the both vectors have
523 * the same size.
524 */
525void oatCopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src)
526{
527 /* if dest is expandable and < src, we could expand dest to match */
528 checkSizes(dest, src);
529
530 memcpy(dest->storage, src->storage, sizeof(u4) * dest->storageSize);
531}
532
533/*
534 * Intersect two bit vectors and store the result to the dest vector.
535 */
536
537bool oatIntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
538 const ArenaBitVector* src2)
539{
buzbeeaad72012011-09-21 21:52:09 -0700540 DCHECK(src1 != NULL);
541 DCHECK(src2 != NULL);
542 if (dest->storageSize != src1->storageSize ||
buzbee67bf8852011-08-17 17:51:35 -0700543 dest->storageSize != src2->storageSize ||
544 dest->expandable != src1->expandable ||
545 dest->expandable != src2->expandable)
546 return false;
547
548 unsigned int idx;
549 for (idx = 0; idx < dest->storageSize; idx++) {
550 dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
551 }
552 return true;
553}
554
555/*
556 * Unify two bit vectors and store the result to the dest vector.
557 */
558bool oatUnifyBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
559 const ArenaBitVector* src2)
560{
buzbeeaad72012011-09-21 21:52:09 -0700561 DCHECK(src1 != NULL);
562 DCHECK(src2 != NULL);
563 if (dest->storageSize != src1->storageSize ||
buzbee67bf8852011-08-17 17:51:35 -0700564 dest->storageSize != src2->storageSize ||
565 dest->expandable != src1->expandable ||
566 dest->expandable != src2->expandable)
567 return false;
568
569 unsigned int idx;
570 for (idx = 0; idx < dest->storageSize; idx++) {
571 dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
572 }
573 return true;
574}
575
576/*
buzbeee1965672012-03-11 18:39:19 -0700577 * Return true if any bits collide. Vectors must be same size.
578 */
579bool oatTestBitVectors(const ArenaBitVector* src1,
580 const ArenaBitVector* src2)
581{
582 DCHECK_EQ(src1->storageSize, src2->storageSize);
583 for (uint32_t idx = 0; idx < src1->storageSize; idx++) {
584 if (src1->storage[idx] & src2->storage[idx]) return true;
585 }
586 return false;
587}
588
589/*
buzbee67bf8852011-08-17 17:51:35 -0700590 * Compare two bit vectors and return true if difference is seen.
591 */
592bool oatCompareBitVectors(const ArenaBitVector* src1,
593 const ArenaBitVector* src2)
594{
595 if (src1->storageSize != src2->storageSize ||
596 src1->expandable != src2->expandable)
597 return true;
598
599 unsigned int idx;
600 for (idx = 0; idx < src1->storageSize; idx++) {
601 if (src1->storage[idx] != src2->storage[idx]) return true;
602 }
603 return false;
604}
605
606/*
607 * Count the number of bits that are set.
608 */
609int oatCountSetBits(const ArenaBitVector* pBits)
610{
611 unsigned int word;
612 unsigned int count = 0;
613
614 for (word = 0; word < pBits->storageSize; word++) {
615 u4 val = pBits->storage[word];
616
617 if (val != 0) {
618 if (val == 0xffffffff) {
619 count += 32;
620 } else {
621 /* count the number of '1' bits */
622 while (val != 0) {
623 val &= val - 1;
624 count++;
625 }
626 }
627 }
628 }
629
630 return count;
631}
632
633/* Return the next position set to 1. -1 means end-of-element reached */
634int oatBitVectorIteratorNext(ArenaBitVectorIterator* iterator)
635{
buzbee5b537102012-01-17 17:33:47 -0800636 ArenaBitVector* pBits = iterator->pBits;
buzbee67bf8852011-08-17 17:51:35 -0700637 u4 bitIndex = iterator->idx;
buzbee5abfa3e2012-01-31 17:01:43 -0800638 u4 bitSize = iterator->bitSize;
buzbee67bf8852011-08-17 17:51:35 -0700639
buzbee5abfa3e2012-01-31 17:01:43 -0800640 DCHECK_EQ(bitSize, pBits->storageSize * sizeof(u4) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700641
buzbee5abfa3e2012-01-31 17:01:43 -0800642 if (bitIndex >= bitSize) return -1;
buzbee5b537102012-01-17 17:33:47 -0800643
buzbee5abfa3e2012-01-31 17:01:43 -0800644 u4 wordIndex = bitIndex >> 5;
645 u4 endWordIndex = bitSize >> 5;
646 u4* storage = pBits->storage;
647 u4 word = storage[wordIndex++];
buzbee5b537102012-01-17 17:33:47 -0800648
buzbee5abfa3e2012-01-31 17:01:43 -0800649 // Mask out any bits in the first word we've already considered
650 word &= ~((1 << (bitIndex & 0x1f))-1);
651
652 for (; wordIndex <= endWordIndex;) {
653 u4 bitPos = bitIndex & 0x1f;
buzbee67bc2362011-10-11 18:08:40 -0700654 if (word == 0) {
buzbee67bc2362011-10-11 18:08:40 -0700655 bitIndex += (32 - bitPos);
buzbee5abfa3e2012-01-31 17:01:43 -0800656 word = storage[wordIndex++];
657 continue;
658 }
659 for (; bitPos < 32; bitPos++) {
660 if (word & (1 << bitPos)) {
661 iterator->idx = bitIndex + 1;
662 return bitIndex;
663 }
buzbee67bc2362011-10-11 18:08:40 -0700664 bitIndex++;
665 }
buzbee5abfa3e2012-01-31 17:01:43 -0800666 word = storage[wordIndex++];
buzbee67bf8852011-08-17 17:51:35 -0700667 }
buzbee5abfa3e2012-01-31 17:01:43 -0800668 iterator->idx = iterator->bitSize;
buzbee67bf8852011-08-17 17:51:35 -0700669 return -1;
670}
671
672/*
673 * Mark specified number of bits as "set". Cannot set all bits like ClearAll
674 * since there might be unused bits - setting those to one will confuse the
675 * iterator.
676 */
677void oatSetInitialBits(ArenaBitVector* pBits, unsigned int numBits)
678{
679 unsigned int idx;
buzbeeed3e9302011-09-23 17:34:19 -0700680 DCHECK_LE(((numBits + 31) >> 5), pBits->storageSize);
buzbee67bf8852011-08-17 17:51:35 -0700681 for (idx = 0; idx < (numBits >> 5); idx++) {
682 pBits->storage[idx] = -1;
683 }
684 unsigned int remNumBits = numBits & 0x1f;
685 if (remNumBits) {
686 pBits->storage[idx] = (1 << remNumBits) - 1;
687 }
688}
689
690void oatGetBlockName(BasicBlock* bb, char* name)
691{
692 switch (bb->blockType) {
693 case kEntryBlock:
694 snprintf(name, BLOCK_NAME_LEN, "entry");
695 break;
696 case kExitBlock:
697 snprintf(name, BLOCK_NAME_LEN, "exit");
698 break;
699 case kDalvikByteCode:
700 snprintf(name, BLOCK_NAME_LEN, "block%04x", bb->startOffset);
701 break;
702 case kExceptionHandling:
703 snprintf(name, BLOCK_NAME_LEN, "exception%04x", bb->startOffset);
704 break;
705 default:
706 snprintf(name, BLOCK_NAME_LEN, "??");
707 break;
708 }
709}
buzbeeed3e9302011-09-23 17:34:19 -0700710
711const char* oatGetShortyFromTargetIdx(CompilationUnit *cUnit, int targetIdx)
712{
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800713 const DexFile::MethodId& methodId = cUnit->dex_file->GetMethodId(targetIdx);
Ian Rogersa3760aa2011-11-14 14:32:37 -0800714 return cUnit->dex_file->GetShorty(methodId.proto_idx_);
buzbeeed3e9302011-09-23 17:34:19 -0700715}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800716
717} // namespace art