blob: 47dfb503419cc7a3eabcb20171b3f6058da987d7 [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
buzbeeefc63692012-11-14 16:31:52 -080017#include "compiler_internals.h"
buzbee67bf8852011-08-17 17:51:35 -070018
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080019namespace art {
20
buzbeecbd6d442012-11-17 14:11:25 -080021const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
22 "kMirOpPhi",
23 "kMirOpCopy",
24 "kMirFusedCmplFloat",
25 "kMirFusedCmpgFloat",
26 "kMirFusedCmplDouble",
27 "kMirFusedCmpgDouble",
28 "kMirFusedCmpLong",
29 "kMirNop",
30 "kMirOpNullCheck",
31 "kMirOpRangeCheck",
32 "kMirOpDivZeroCheck",
33 "kMirOpCheck",
34};
35
buzbee5abfa3e2012-01-31 17:01:43 -080036#ifdef WITH_MEMSTATS
Elliott Hughes719ace42012-03-09 18:06:03 -080037struct Memstats {
buzbeeeaf09bc2012-11-15 14:51:41 -080038 uint32_t allocStats[kNumAllocKinds];
Bill Buzbeea114add2012-05-03 15:00:40 -070039 int listSizes[kNumListKinds];
40 int listWasted[kNumListKinds];
41 int listGrows[kNumListKinds];
42 int listMaxElems[kNumListKinds];
43 int bitMapSizes[kNumBitMapKinds];
44 int bitMapWasted[kNumBitMapKinds];
45 int bitMapGrows[kNumBitMapKinds];
Elliott Hughes719ace42012-03-09 18:06:03 -080046};
buzbee5abfa3e2012-01-31 17:01:43 -080047
48const char* allocNames[kNumAllocKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070049 "Misc ",
50 "BasicBlock ",
51 "LIR ",
52 "MIR ",
53 "DataFlow ",
54 "GrowList ",
55 "GrowBitMap ",
56 "Dalvik2SSA ",
57 "DebugInfo ",
58 "Successor ",
59 "RegAlloc ",
60 "Data ",
61 "Preds ",
buzbee5abfa3e2012-01-31 17:01:43 -080062};
63
64const char* listNames[kNumListKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070065 "Misc ",
66 "blockList ",
67 "SSAtoDalvik ",
68 "dfsOrder ",
69 "dfsPostOrder ",
70 "domPostOrderTraversal ",
71 "throwLaunchPads ",
72 "suspendLaunchPads ",
73 "switchTables ",
74 "fillArrayData ",
75 "SuccessorBlocks ",
76 "Predecessors ",
buzbee5abfa3e2012-01-31 17:01:43 -080077};
78
79const char* bitMapNames[kNumBitMapKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070080 "Misc ",
81 "Use ",
82 "Def ",
83 "LiveIn ",
84 "BlockMatrix ",
85 "Dominators ",
86 "IDominated ",
87 "DomFrontier ",
88 "Phi ",
89 "TmpBlocks ",
90 "InputBlocks ",
91 "RegisterV ",
92 "TempSSARegisterV ",
93 "Null Check ",
94 "TmpBlockV ",
95 "Predecessors ",
buzbee5abfa3e2012-01-31 17:01:43 -080096};
97#endif
98
buzbeeeaf09bc2012-11-15 14:51:41 -080099#define kArenaBitVectorGrowth 4 /* increase by 4 uint32_ts when limit hit */
buzbee67bf8852011-08-17 17:51:35 -0700100
101/* Allocate the initial memory block for arena-based allocation */
buzbee52a77fc2012-11-20 19:50:46 -0800102bool HeapInit(CompilationUnit* cUnit)
buzbee67bf8852011-08-17 17:51:35 -0700103{
Bill Buzbeea114add2012-05-03 15:00:40 -0700104 DCHECK(cUnit->arenaHead == NULL);
105 cUnit->arenaHead =
buzbeecbd6d442012-11-17 14:11:25 -0800106 static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + ARENA_DEFAULT_SIZE));
Bill Buzbeea114add2012-05-03 15:00:40 -0700107 if (cUnit->arenaHead == NULL) {
108 LOG(FATAL) << "No memory left to create compiler heap memory";
109 }
110 cUnit->arenaHead->blockSize = ARENA_DEFAULT_SIZE;
111 cUnit->currentArena = cUnit->arenaHead;
112 cUnit->currentArena->bytesAllocated = 0;
113 cUnit->currentArena->next = NULL;
114 cUnit->numArenaBlocks = 1;
buzbeeba938cb2012-02-03 14:47:55 -0800115#ifdef WITH_MEMSTATS
buzbee52a77fc2012-11-20 19:50:46 -0800116 cUnit->mstats = (Memstats*) NewMem(cUnit, sizeof(Memstats), true,
Bill Buzbeea114add2012-05-03 15:00:40 -0700117 kAllocDebugInfo);
buzbeeba938cb2012-02-03 14:47:55 -0800118#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700119 return true;
buzbee67bf8852011-08-17 17:51:35 -0700120}
121
122/* Arena-based malloc for compilation tasks */
buzbee52a77fc2012-11-20 19:50:46 -0800123void* NewMem(CompilationUnit* cUnit, size_t size, bool zero, oatAllocKind kind)
buzbee67bf8852011-08-17 17:51:35 -0700124{
Bill Buzbeea114add2012-05-03 15:00:40 -0700125 size = (size + 3) & ~3;
buzbee5abfa3e2012-01-31 17:01:43 -0800126#ifdef WITH_MEMSTATS
Bill Buzbeea114add2012-05-03 15:00:40 -0700127 if (cUnit->mstats != NULL) {
128 cUnit->mstats->allocStats[kind] += size;
129 }
buzbee5abfa3e2012-01-31 17:01:43 -0800130#endif
buzbee67bf8852011-08-17 17:51:35 -0700131retry:
Bill Buzbeea114add2012-05-03 15:00:40 -0700132 /* Normal case - space is available in the current page */
133 if (size + cUnit->currentArena->bytesAllocated <=
134 cUnit->currentArena->blockSize) {
135 void *ptr;
136 ptr = &cUnit->currentArena->ptr[cUnit->currentArena->bytesAllocated];
137 cUnit->currentArena->bytesAllocated += size;
138 if (zero) {
139 memset(ptr, 0, size);
140 }
141 return ptr;
142 } else {
143 /*
144 * See if there are previously allocated arena blocks before the last
145 * reset
146 */
147 if (cUnit->currentArena->next) {
148 cUnit->currentArena = cUnit->currentArena->next;
149 cUnit->currentArena->bytesAllocated = 0;
buzbee67bf8852011-08-17 17:51:35 -0700150 goto retry;
151 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700152
153 size_t blockSize = (size < ARENA_DEFAULT_SIZE) ? ARENA_DEFAULT_SIZE : size;
154 /* Time to allocate a new arena */
buzbeecbd6d442012-11-17 14:11:25 -0800155 ArenaMemBlock *newArena =
156 static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + blockSize));
Bill Buzbeea114add2012-05-03 15:00:40 -0700157 if (newArena == NULL) {
158 LOG(FATAL) << "Arena allocation failure";
159 }
160 newArena->blockSize = blockSize;
161 newArena->bytesAllocated = 0;
162 newArena->next = NULL;
163 cUnit->currentArena->next = newArena;
164 cUnit->currentArena = newArena;
165 cUnit->numArenaBlocks++;
166 if (cUnit->numArenaBlocks > 20000) {
167 LOG(INFO) << "Total arena pages: " << cUnit->numArenaBlocks;
168 }
169 goto retry;
170 }
buzbee67bf8852011-08-17 17:51:35 -0700171}
172
173/* Reclaim all the arena blocks allocated so far */
buzbee52a77fc2012-11-20 19:50:46 -0800174void ArenaReset(CompilationUnit* cUnit)
buzbee67bf8852011-08-17 17:51:35 -0700175{
Bill Buzbeea114add2012-05-03 15:00:40 -0700176 ArenaMemBlock* head = cUnit->arenaHead;
177 while (head != NULL) {
178 ArenaMemBlock* p = head;
179 head = head->next;
180 free(p);
181 }
182 cUnit->arenaHead = NULL;
183 cUnit->currentArena = NULL;
buzbee67bf8852011-08-17 17:51:35 -0700184}
185
186/* Growable List initialization */
buzbee52a77fc2012-11-20 19:50:46 -0800187void CompilerInitGrowableList(CompilationUnit* cUnit, GrowableList* gList,
Bill Buzbeea114add2012-05-03 15:00:40 -0700188 size_t initLength, oatListKind kind)
buzbee67bf8852011-08-17 17:51:35 -0700189{
Bill Buzbeea114add2012-05-03 15:00:40 -0700190 gList->numAllocated = initLength;
191 gList->numUsed = 0;
buzbee52a77fc2012-11-20 19:50:46 -0800192 gList->elemList = static_cast<uintptr_t *>(NewMem(cUnit, sizeof(intptr_t) * initLength,
buzbeecbd6d442012-11-17 14:11:25 -0800193 true, kAllocGrowableList));
buzbee5abfa3e2012-01-31 17:01:43 -0800194#ifdef WITH_MEMSTATS
buzbeecbd6d442012-11-17 14:11:25 -0800195 cUnit->mstats->listSizes[kind] += sizeof(uintptr_t) * initLength;
Bill Buzbeea114add2012-05-03 15:00:40 -0700196 gList->kind = kind;
buzbeecbd6d442012-11-17 14:11:25 -0800197 if (static_cast<int>(initLength) > cUnit->mstats->listMaxElems[kind]) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700198 cUnit->mstats->listMaxElems[kind] = initLength;
199 }
buzbee5abfa3e2012-01-31 17:01:43 -0800200#endif
buzbee67bf8852011-08-17 17:51:35 -0700201}
202
203/* Expand the capacity of a growable list */
buzbee52a77fc2012-11-20 19:50:46 -0800204static void ExpandGrowableList(CompilationUnit* cUnit, GrowableList* gList)
buzbee67bf8852011-08-17 17:51:35 -0700205{
Bill Buzbeea114add2012-05-03 15:00:40 -0700206 int newLength = gList->numAllocated;
207 if (newLength < 128) {
208 newLength <<= 1;
209 } else {
210 newLength += 128;
211 }
buzbeecbd6d442012-11-17 14:11:25 -0800212 uintptr_t *newArray =
buzbee52a77fc2012-11-20 19:50:46 -0800213 static_cast<uintptr_t*>(NewMem(cUnit, sizeof(uintptr_t) * newLength, true,
buzbeecbd6d442012-11-17 14:11:25 -0800214 kAllocGrowableList));
215 memcpy(newArray, gList->elemList, sizeof(uintptr_t) * gList->numAllocated);
buzbee5abfa3e2012-01-31 17:01:43 -0800216#ifdef WITH_MEMSTATS
buzbeecbd6d442012-11-17 14:11:25 -0800217 cUnit->mstats->listSizes[gList->kind] += sizeof(uintptr_t) * newLength;
Bill Buzbeea114add2012-05-03 15:00:40 -0700218 cUnit->mstats->listWasted[gList->kind] +=
buzbeecbd6d442012-11-17 14:11:25 -0800219 sizeof(uintptr_t) * gList->numAllocated;
Bill Buzbeea114add2012-05-03 15:00:40 -0700220 cUnit->mstats->listGrows[gList->kind]++;
221 if (newLength > cUnit->mstats->listMaxElems[gList->kind]) {
222 cUnit->mstats->listMaxElems[gList->kind] = newLength;
223 }
buzbee5abfa3e2012-01-31 17:01:43 -0800224#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700225 gList->numAllocated = newLength;
226 gList->elemList = newArray;
buzbee67bf8852011-08-17 17:51:35 -0700227}
228
229/* Insert a new element into the growable list */
buzbee52a77fc2012-11-20 19:50:46 -0800230void InsertGrowableList(CompilationUnit* cUnit, GrowableList* gList,
buzbeecbd6d442012-11-17 14:11:25 -0800231 uintptr_t elem)
buzbee67bf8852011-08-17 17:51:35 -0700232{
Bill Buzbeea114add2012-05-03 15:00:40 -0700233 DCHECK_NE(gList->numAllocated, 0U);
234 if (gList->numUsed == gList->numAllocated) {
buzbee52a77fc2012-11-20 19:50:46 -0800235 ExpandGrowableList(cUnit, gList);
Bill Buzbeea114add2012-05-03 15:00:40 -0700236 }
237 gList->elemList[gList->numUsed++] = elem;
buzbee67bf8852011-08-17 17:51:35 -0700238}
239
buzbee5abfa3e2012-01-31 17:01:43 -0800240/* Delete an element from a growable list. Element must be present */
buzbee52a77fc2012-11-20 19:50:46 -0800241void DeleteGrowableList(GrowableList* gList, uintptr_t elem)
buzbee5abfa3e2012-01-31 17:01:43 -0800242{
Bill Buzbeea114add2012-05-03 15:00:40 -0700243 bool found = false;
244 for (unsigned int i = 0; i < gList->numUsed; i++) {
245 if (!found && gList->elemList[i] == elem) {
246 found = true;
buzbee5abfa3e2012-01-31 17:01:43 -0800247 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700248 if (found) {
249 gList->elemList[i] = gList->elemList[i+1];
250 }
251 }
252 DCHECK_EQ(found, true);
253 gList->numUsed--;
buzbee5abfa3e2012-01-31 17:01:43 -0800254}
255
buzbee52a77fc2012-11-20 19:50:46 -0800256void GrowableListIteratorInit(GrowableList* gList,
Bill Buzbeea114add2012-05-03 15:00:40 -0700257 GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700258{
Bill Buzbeea114add2012-05-03 15:00:40 -0700259 iterator->list = gList;
260 iterator->idx = 0;
261 iterator->size = gList->numUsed;
buzbee67bf8852011-08-17 17:51:35 -0700262}
263
buzbee52a77fc2012-11-20 19:50:46 -0800264uintptr_t GrowableListIteratorNext(GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700265{
Bill Buzbeea114add2012-05-03 15:00:40 -0700266 DCHECK_EQ(iterator->size, iterator->list->numUsed);
267 if (iterator->idx == iterator->size) return 0;
268 return iterator->list->elemList[iterator->idx++];
buzbee67bf8852011-08-17 17:51:35 -0700269}
270
buzbee52a77fc2012-11-20 19:50:46 -0800271uintptr_t GrowableListGetElement(const GrowableList* gList, size_t idx)
buzbee67bf8852011-08-17 17:51:35 -0700272{
Bill Buzbeea114add2012-05-03 15:00:40 -0700273 DCHECK_LT(idx, gList->numUsed);
274 return gList->elemList[idx];
buzbee67bf8852011-08-17 17:51:35 -0700275}
276
buzbee5abfa3e2012-01-31 17:01:43 -0800277#ifdef WITH_MEMSTATS
278/* Dump memory usage stats */
buzbee52a77fc2012-11-20 19:50:46 -0800279void DumpMemStats(CompilationUnit* cUnit)
buzbee5abfa3e2012-01-31 17:01:43 -0800280{
buzbeeeaf09bc2012-11-15 14:51:41 -0800281 uint32_t total = 0;
Bill Buzbeea114add2012-05-03 15:00:40 -0700282 for (int i = 0; i < kNumAllocKinds; i++) {
283 total += cUnit->mstats->allocStats[i];
284 }
285 if (total > (10 * 1024 * 1024)) {
286 LOG(INFO) << "MEMUSAGE: " << total << " : "
287 << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
288 LOG(INFO) << "insnsSize: " << cUnit->insnsSize;
289 if (cUnit->disableDataflow) {
290 LOG(INFO) << " ** Dataflow disabled ** ";
buzbee5abfa3e2012-01-31 17:01:43 -0800291 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700292 LOG(INFO) << "===== Overall allocations";
293 for (int i = 0; i < kNumAllocKinds; i++) {
294 LOG(INFO) << allocNames[i] << std::setw(10) <<
295 cUnit->mstats->allocStats[i];
296 }
297 LOG(INFO) << "===== GrowableList allocations";
298 for (int i = 0; i < kNumListKinds; i++) {
299 LOG(INFO) << listNames[i]
buzbeeba938cb2012-02-03 14:47:55 -0800300 << " S:" << cUnit->mstats->listSizes[i]
301 << ", W:" << cUnit->mstats->listWasted[i]
302 << ", G:" << cUnit->mstats->listGrows[i]
303 << ", E:" << cUnit->mstats->listMaxElems[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700304 }
305 LOG(INFO) << "===== GrowableBitMap allocations";
306 for (int i = 0; i < kNumBitMapKinds; i++) {
307 LOG(INFO) << bitMapNames[i]
buzbeeba938cb2012-02-03 14:47:55 -0800308 << " S:" << cUnit->mstats->bitMapSizes[i]
309 << ", W:" << cUnit->mstats->bitMapWasted[i]
310 << ", G:" << cUnit->mstats->bitMapGrows[i];
buzbee5abfa3e2012-01-31 17:01:43 -0800311 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700312 }
buzbee5abfa3e2012-01-31 17:01:43 -0800313}
314#endif
315
buzbee67bf8852011-08-17 17:51:35 -0700316/* Debug Utility - dump a compilation unit */
buzbee52a77fc2012-11-20 19:50:46 -0800317void DumpCompilationUnit(CompilationUnit* cUnit)
buzbee67bf8852011-08-17 17:51:35 -0700318{
Bill Buzbeea114add2012-05-03 15:00:40 -0700319 BasicBlock* bb;
320 const char* blockTypeNames[] = {
321 "Entry Block",
322 "Code Block",
323 "Exit Block",
324 "Exception Handling",
325 "Catch Block"
326 };
buzbee67bf8852011-08-17 17:51:35 -0700327
Bill Buzbeea114add2012-05-03 15:00:40 -0700328 LOG(INFO) << "Compiling " << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
329 LOG(INFO) << cUnit->insns << " insns";
330 LOG(INFO) << cUnit->numBlocks << " blocks in total";
331 GrowableListIterator iterator;
buzbee67bf8852011-08-17 17:51:35 -0700332
buzbee52a77fc2012-11-20 19:50:46 -0800333 GrowableListIteratorInit(&cUnit->blockList, &iterator);
buzbee67bf8852011-08-17 17:51:35 -0700334
Bill Buzbeea114add2012-05-03 15:00:40 -0700335 while (true) {
buzbee52a77fc2012-11-20 19:50:46 -0800336 bb = reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&iterator));
Bill Buzbeea114add2012-05-03 15:00:40 -0700337 if (bb == NULL) break;
338 LOG(INFO) << StringPrintf("Block %d (%s) (insn %04x - %04x%s)",
339 bb->id,
340 blockTypeNames[bb->blockType],
341 bb->startOffset,
342 bb->lastMIRInsn ? bb->lastMIRInsn->offset : bb->startOffset,
343 bb->lastMIRInsn ? "" : " empty");
344 if (bb->taken) {
345 LOG(INFO) << " Taken branch: block " << bb->taken->id
346 << "(0x" << std::hex << bb->taken->startOffset << ")";
buzbee67bf8852011-08-17 17:51:35 -0700347 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700348 if (bb->fallThrough) {
349 LOG(INFO) << " Fallthrough : block " << bb->fallThrough->id
350 << " (0x" << std::hex << bb->fallThrough->startOffset << ")";
351 }
352 }
buzbee67bf8852011-08-17 17:51:35 -0700353}
354
buzbee67bc2362011-10-11 18:08:40 -0700355static uint32_t checkMasks[32] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700356 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
357 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
358 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
359 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000,
360 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000,
361 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
362 0x40000000, 0x80000000 };
buzbee67bc2362011-10-11 18:08:40 -0700363
buzbee67bf8852011-08-17 17:51:35 -0700364/*
365 * Allocate a bit vector with enough space to hold at least the specified
366 * number of bits.
367 *
368 * NOTE: memory is allocated from the compiler arena.
369 */
buzbee52a77fc2012-11-20 19:50:46 -0800370ArenaBitVector* AllocBitVector(CompilationUnit* cUnit,
Bill Buzbeea114add2012-05-03 15:00:40 -0700371 unsigned int startBits, bool expandable,
372 oatBitMapKind kind)
buzbee67bf8852011-08-17 17:51:35 -0700373{
Bill Buzbeea114add2012-05-03 15:00:40 -0700374 ArenaBitVector* bv;
375 unsigned int count;
buzbee67bf8852011-08-17 17:51:35 -0700376
Bill Buzbeea114add2012-05-03 15:00:40 -0700377 DCHECK_EQ(sizeof(bv->storage[0]), 4U); /* assuming 32-bit units */
buzbee67bf8852011-08-17 17:51:35 -0700378
buzbee52a77fc2012-11-20 19:50:46 -0800379 bv = static_cast<ArenaBitVector*>(NewMem(cUnit, sizeof(ArenaBitVector), false,
buzbeecbd6d442012-11-17 14:11:25 -0800380 kAllocGrowableBitMap));
buzbee67bf8852011-08-17 17:51:35 -0700381
Bill Buzbeea114add2012-05-03 15:00:40 -0700382 count = (startBits + 31) >> 5;
buzbee67bf8852011-08-17 17:51:35 -0700383
Bill Buzbeea114add2012-05-03 15:00:40 -0700384 bv->storageSize = count;
385 bv->expandable = expandable;
buzbee52a77fc2012-11-20 19:50:46 -0800386 bv->storage = static_cast<uint32_t*>(NewMem(cUnit, count * sizeof(uint32_t), true,
buzbeeeaf09bc2012-11-15 14:51:41 -0800387 kAllocGrowableBitMap));
buzbee5abfa3e2012-01-31 17:01:43 -0800388#ifdef WITH_MEMSTATS
Bill Buzbeea114add2012-05-03 15:00:40 -0700389 bv->kind = kind;
buzbeeeaf09bc2012-11-15 14:51:41 -0800390 cUnit->mstats->bitMapSizes[kind] += count * sizeof(uint32_t);
buzbee5abfa3e2012-01-31 17:01:43 -0800391#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700392 return bv;
buzbee67bf8852011-08-17 17:51:35 -0700393}
394
395/*
396 * Determine whether or not the specified bit is set.
397 */
buzbee52a77fc2012-11-20 19:50:46 -0800398bool IsBitSet(const ArenaBitVector* pBits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700399{
buzbeeeaf09bc2012-11-15 14:51:41 -0800400 DCHECK_LT(num, pBits->storageSize * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700401
Bill Buzbeea114add2012-05-03 15:00:40 -0700402 unsigned int val = pBits->storage[num >> 5] & checkMasks[num & 0x1f];
403 return (val != 0);
buzbee67bf8852011-08-17 17:51:35 -0700404}
405
406/*
407 * Mark all bits bit as "clear".
408 */
buzbee52a77fc2012-11-20 19:50:46 -0800409void ClearAllBits(ArenaBitVector* pBits)
buzbee67bf8852011-08-17 17:51:35 -0700410{
Bill Buzbeea114add2012-05-03 15:00:40 -0700411 unsigned int count = pBits->storageSize;
buzbeeeaf09bc2012-11-15 14:51:41 -0800412 memset(pBits->storage, 0, count * sizeof(uint32_t));
buzbee67bf8852011-08-17 17:51:35 -0700413}
414
415/*
416 * Mark the specified bit as "set".
417 *
418 * Returns "false" if the bit is outside the range of the vector and we're
419 * not allowed to expand.
420 *
421 * NOTE: memory is allocated from the compiler arena.
422 */
buzbee52a77fc2012-11-20 19:50:46 -0800423bool SetBit(CompilationUnit* cUnit, ArenaBitVector* pBits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700424{
buzbeeeaf09bc2012-11-15 14:51:41 -0800425 if (num >= pBits->storageSize * sizeof(uint32_t) * 8) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700426 if (!pBits->expandable) {
427 LOG(FATAL) << "Can't expand";
buzbee67bf8852011-08-17 17:51:35 -0700428 }
429
Bill Buzbeea114add2012-05-03 15:00:40 -0700430 /* Round up to word boundaries for "num+1" bits */
431 unsigned int newSize = (num + 1 + 31) >> 5;
432 DCHECK_GT(newSize, pBits->storageSize);
buzbee52a77fc2012-11-20 19:50:46 -0800433 uint32_t *newStorage = static_cast<uint32_t*>(NewMem(cUnit, newSize * sizeof(uint32_t), false,
buzbeeeaf09bc2012-11-15 14:51:41 -0800434 kAllocGrowableBitMap));
435 memcpy(newStorage, pBits->storage, pBits->storageSize * sizeof(uint32_t));
Bill Buzbeea114add2012-05-03 15:00:40 -0700436 memset(&newStorage[pBits->storageSize], 0,
buzbeeeaf09bc2012-11-15 14:51:41 -0800437 (newSize - pBits->storageSize) * sizeof(uint32_t));
Bill Buzbeea114add2012-05-03 15:00:40 -0700438#ifdef WITH_MEMSTATS
439 cUnit->mstats->bitMapWasted[pBits->kind] +=
buzbeeeaf09bc2012-11-15 14:51:41 -0800440 pBits->storageSize * sizeof(uint32_t);
441 cUnit->mstats->bitMapSizes[pBits->kind] += newSize * sizeof(uint32_t);
Bill Buzbeea114add2012-05-03 15:00:40 -0700442 cUnit->mstats->bitMapGrows[pBits->kind]++;
443#endif
444 pBits->storage = newStorage;
445 pBits->storageSize = newSize;
446 }
447
448 pBits->storage[num >> 5] |= checkMasks[num & 0x1f];
449 return true;
buzbee67bf8852011-08-17 17:51:35 -0700450}
451
452/*
453 * Mark the specified bit as "unset".
454 *
455 * Returns "false" if the bit is outside the range of the vector and we're
456 * not allowed to expand.
457 *
458 * NOTE: memory is allocated from the compiler arena.
459 */
buzbee52a77fc2012-11-20 19:50:46 -0800460bool ClearBit(ArenaBitVector* pBits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700461{
buzbeeeaf09bc2012-11-15 14:51:41 -0800462 if (num >= pBits->storageSize * sizeof(uint32_t) * 8) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700463 LOG(FATAL) << "Attempt to clear a bit not set in the vector yet";;
464 }
buzbee67bf8852011-08-17 17:51:35 -0700465
Bill Buzbeea114add2012-05-03 15:00:40 -0700466 pBits->storage[num >> 5] &= ~checkMasks[num & 0x1f];
467 return true;
buzbee67bf8852011-08-17 17:51:35 -0700468}
469
buzbee67bf8852011-08-17 17:51:35 -0700470/* Initialize the iterator structure */
buzbee52a77fc2012-11-20 19:50:46 -0800471void BitVectorIteratorInit(ArenaBitVector* pBits,
Bill Buzbeea114add2012-05-03 15:00:40 -0700472 ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700473{
Bill Buzbeea114add2012-05-03 15:00:40 -0700474 iterator->pBits = pBits;
buzbeeeaf09bc2012-11-15 14:51:41 -0800475 iterator->bitSize = pBits->storageSize * sizeof(uint32_t) * 8;
Bill Buzbeea114add2012-05-03 15:00:40 -0700476 iterator->idx = 0;
buzbee67bf8852011-08-17 17:51:35 -0700477}
478
479/*
480 * If the vector sizes don't match, log an error and abort.
481 */
buzbee52a77fc2012-11-20 19:50:46 -0800482static void CheckSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
buzbee67bf8852011-08-17 17:51:35 -0700483{
Bill Buzbeea114add2012-05-03 15:00:40 -0700484 if (bv1->storageSize != bv2->storageSize) {
485 LOG(FATAL) << "Mismatched vector sizes (" << bv1->storageSize
486 << ", " << bv2->storageSize << ")";
487 }
buzbee67bf8852011-08-17 17:51:35 -0700488}
489
490/*
491 * Copy a whole vector to the other. Only do that when the both vectors have
492 * the same size.
493 */
buzbee52a77fc2012-11-20 19:50:46 -0800494void CopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src)
buzbee67bf8852011-08-17 17:51:35 -0700495{
Bill Buzbeea114add2012-05-03 15:00:40 -0700496 /* if dest is expandable and < src, we could expand dest to match */
buzbee52a77fc2012-11-20 19:50:46 -0800497 CheckSizes(dest, src);
buzbee67bf8852011-08-17 17:51:35 -0700498
buzbeeeaf09bc2012-11-15 14:51:41 -0800499 memcpy(dest->storage, src->storage, sizeof(uint32_t) * dest->storageSize);
buzbee67bf8852011-08-17 17:51:35 -0700500}
501
502/*
503 * Intersect two bit vectors and store the result to the dest vector.
504 */
505
buzbee52a77fc2012-11-20 19:50:46 -0800506bool IntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700507 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700508{
Bill Buzbeea114add2012-05-03 15:00:40 -0700509 DCHECK(src1 != NULL);
510 DCHECK(src2 != NULL);
511 if (dest->storageSize != src1->storageSize ||
512 dest->storageSize != src2->storageSize ||
513 dest->expandable != src1->expandable ||
514 dest->expandable != src2->expandable)
515 return false;
buzbee67bf8852011-08-17 17:51:35 -0700516
Bill Buzbeea114add2012-05-03 15:00:40 -0700517 unsigned int idx;
518 for (idx = 0; idx < dest->storageSize; idx++) {
519 dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
520 }
521 return true;
buzbee67bf8852011-08-17 17:51:35 -0700522}
523
524/*
525 * Unify two bit vectors and store the result to the dest vector.
526 */
buzbee52a77fc2012-11-20 19:50:46 -0800527bool UnifyBitVetors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700528 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700529{
Bill Buzbeea114add2012-05-03 15:00:40 -0700530 DCHECK(src1 != NULL);
531 DCHECK(src2 != NULL);
532 if (dest->storageSize != src1->storageSize ||
533 dest->storageSize != src2->storageSize ||
534 dest->expandable != src1->expandable ||
535 dest->expandable != src2->expandable)
536 return false;
buzbee67bf8852011-08-17 17:51:35 -0700537
Bill Buzbeea114add2012-05-03 15:00:40 -0700538 unsigned int idx;
539 for (idx = 0; idx < dest->storageSize; idx++) {
540 dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
541 }
542 return true;
buzbee67bf8852011-08-17 17:51:35 -0700543}
544
545/*
buzbeee1965672012-03-11 18:39:19 -0700546 * Return true if any bits collide. Vectors must be same size.
547 */
buzbee52a77fc2012-11-20 19:50:46 -0800548bool TestBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700549 const ArenaBitVector* src2)
buzbeee1965672012-03-11 18:39:19 -0700550{
Bill Buzbeea114add2012-05-03 15:00:40 -0700551 DCHECK_EQ(src1->storageSize, src2->storageSize);
552 for (uint32_t idx = 0; idx < src1->storageSize; idx++) {
553 if (src1->storage[idx] & src2->storage[idx]) return true;
554 }
555 return false;
buzbeee1965672012-03-11 18:39:19 -0700556}
557
558/*
buzbee67bf8852011-08-17 17:51:35 -0700559 * Compare two bit vectors and return true if difference is seen.
560 */
buzbee52a77fc2012-11-20 19:50:46 -0800561bool CompareBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700562 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700563{
Bill Buzbeea114add2012-05-03 15:00:40 -0700564 if (src1->storageSize != src2->storageSize ||
565 src1->expandable != src2->expandable)
566 return true;
buzbee67bf8852011-08-17 17:51:35 -0700567
Bill Buzbeea114add2012-05-03 15:00:40 -0700568 unsigned int idx;
569 for (idx = 0; idx < src1->storageSize; idx++) {
570 if (src1->storage[idx] != src2->storage[idx]) return true;
571 }
572 return false;
buzbee67bf8852011-08-17 17:51:35 -0700573}
574
575/*
576 * Count the number of bits that are set.
577 */
buzbee52a77fc2012-11-20 19:50:46 -0800578int CountSetBits(const ArenaBitVector* pBits)
buzbee67bf8852011-08-17 17:51:35 -0700579{
Bill Buzbeea114add2012-05-03 15:00:40 -0700580 unsigned int word;
581 unsigned int count = 0;
buzbee67bf8852011-08-17 17:51:35 -0700582
Bill Buzbeea114add2012-05-03 15:00:40 -0700583 for (word = 0; word < pBits->storageSize; word++) {
buzbeeeaf09bc2012-11-15 14:51:41 -0800584 uint32_t val = pBits->storage[word];
buzbee67bf8852011-08-17 17:51:35 -0700585
Bill Buzbeea114add2012-05-03 15:00:40 -0700586 if (val != 0) {
587 if (val == 0xffffffff) {
588 count += 32;
589 } else {
590 /* count the number of '1' bits */
591 while (val != 0) {
592 val &= val - 1;
593 count++;
buzbee67bf8852011-08-17 17:51:35 -0700594 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700595 }
buzbee67bf8852011-08-17 17:51:35 -0700596 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700597 }
buzbee67bf8852011-08-17 17:51:35 -0700598
Bill Buzbeea114add2012-05-03 15:00:40 -0700599 return count;
buzbee67bf8852011-08-17 17:51:35 -0700600}
601
602/* Return the next position set to 1. -1 means end-of-element reached */
buzbee52a77fc2012-11-20 19:50:46 -0800603int BitVectorIteratorNext(ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700604{
Bill Buzbeea114add2012-05-03 15:00:40 -0700605 ArenaBitVector* pBits = iterator->pBits;
buzbeeeaf09bc2012-11-15 14:51:41 -0800606 uint32_t bitIndex = iterator->idx;
607 uint32_t bitSize = iterator->bitSize;
buzbee67bf8852011-08-17 17:51:35 -0700608
buzbeeeaf09bc2012-11-15 14:51:41 -0800609 DCHECK_EQ(bitSize, pBits->storageSize * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700610
Bill Buzbeea114add2012-05-03 15:00:40 -0700611 if (bitIndex >= bitSize) return -1;
buzbee5b537102012-01-17 17:33:47 -0800612
buzbeeeaf09bc2012-11-15 14:51:41 -0800613 uint32_t wordIndex = bitIndex >> 5;
614 uint32_t endWordIndex = bitSize >> 5;
615 uint32_t* storage = pBits->storage;
616 uint32_t word = storage[wordIndex++];
buzbee5b537102012-01-17 17:33:47 -0800617
Bill Buzbeea114add2012-05-03 15:00:40 -0700618 // Mask out any bits in the first word we've already considered
619 word &= ~((1 << (bitIndex & 0x1f))-1);
buzbee5abfa3e2012-01-31 17:01:43 -0800620
Bill Buzbeea114add2012-05-03 15:00:40 -0700621 for (; wordIndex <= endWordIndex;) {
buzbeeeaf09bc2012-11-15 14:51:41 -0800622 uint32_t bitPos = bitIndex & 0x1f;
Bill Buzbeea114add2012-05-03 15:00:40 -0700623 if (word == 0) {
624 bitIndex += (32 - bitPos);
625 word = storage[wordIndex++];
626 continue;
buzbee67bf8852011-08-17 17:51:35 -0700627 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700628 for (; bitPos < 32; bitPos++) {
629 if (word & (1 << bitPos)) {
630 iterator->idx = bitIndex + 1;
631 return bitIndex;
632 }
633 bitIndex++;
634 }
635 word = storage[wordIndex++];
636 }
637 iterator->idx = iterator->bitSize;
638 return -1;
buzbee67bf8852011-08-17 17:51:35 -0700639}
640
641/*
642 * Mark specified number of bits as "set". Cannot set all bits like ClearAll
643 * since there might be unused bits - setting those to one will confuse the
644 * iterator.
645 */
buzbee52a77fc2012-11-20 19:50:46 -0800646void SetInitialBits(ArenaBitVector* pBits, unsigned int numBits)
buzbee67bf8852011-08-17 17:51:35 -0700647{
Bill Buzbeea114add2012-05-03 15:00:40 -0700648 unsigned int idx;
649 DCHECK_LE(((numBits + 31) >> 5), pBits->storageSize);
650 for (idx = 0; idx < (numBits >> 5); idx++) {
651 pBits->storage[idx] = -1;
652 }
653 unsigned int remNumBits = numBits & 0x1f;
654 if (remNumBits) {
655 pBits->storage[idx] = (1 << remNumBits) - 1;
656 }
buzbee67bf8852011-08-17 17:51:35 -0700657}
658
buzbee52a77fc2012-11-20 19:50:46 -0800659void GetBlockName(BasicBlock* bb, char* name)
buzbee67bf8852011-08-17 17:51:35 -0700660{
Bill Buzbeea114add2012-05-03 15:00:40 -0700661 switch (bb->blockType) {
662 case kEntryBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700663 snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700664 break;
665 case kExitBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700666 snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700667 break;
668 case kDalvikByteCode:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700669 snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->startOffset, bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700670 break;
671 case kExceptionHandling:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700672 snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->startOffset,
673 bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700674 break;
675 default:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700676 snprintf(name, BLOCK_NAME_LEN, "??_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700677 break;
678 }
buzbee67bf8852011-08-17 17:51:35 -0700679}
buzbeeed3e9302011-09-23 17:34:19 -0700680
buzbee52a77fc2012-11-20 19:50:46 -0800681const char* GetShortyFromTargetIdx(CompilationUnit *cUnit, int targetIdx)
buzbeeed3e9302011-09-23 17:34:19 -0700682{
Bill Buzbeea114add2012-05-03 15:00:40 -0700683 const DexFile::MethodId& methodId = cUnit->dex_file->GetMethodId(targetIdx);
684 return cUnit->dex_file->GetShorty(methodId.proto_idx_);
buzbeeed3e9302011-09-23 17:34:19 -0700685}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800686
687} // namespace art