blob: a0ab292908e302c9cb445dbb77b37a4e5fbd1866 [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 */
buzbeeba938cb2012-02-03 14:47:55 -0800102bool oatHeapInit(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
Bill Buzbeea114add2012-05-03 15:00:40 -0700116 cUnit->mstats = (Memstats*) oatNew(cUnit, sizeof(Memstats), true,
117 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 */
buzbeeba938cb2012-02-03 14:47:55 -0800123void* oatNew(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 */
buzbeeba938cb2012-02-03 14:47:55 -0800174void oatArenaReset(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 */
buzbeeba938cb2012-02-03 14:47:55 -0800187void oatInitGrowableList(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;
buzbeecbd6d442012-11-17 14:11:25 -0800192 gList->elemList = static_cast<uintptr_t *>(oatNew(cUnit, sizeof(intptr_t) * initLength,
193 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 */
buzbee31a4a6f2012-02-28 15:36:15 -0800204void 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 =
213 static_cast<uintptr_t*>(oatNew(cUnit, sizeof(uintptr_t) * newLength, true,
214 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 */
buzbeeba938cb2012-02-03 14:47:55 -0800230void oatInsertGrowableList(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) {
235 expandGrowableList(cUnit, gList);
236 }
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 */
buzbeecbd6d442012-11-17 14:11:25 -0800241void oatDeleteGrowableList(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
buzbee67bf8852011-08-17 17:51:35 -0700256void oatGrowableListIteratorInit(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
buzbeecbd6d442012-11-17 14:11:25 -0800264uintptr_t oatGrowableListIteratorNext(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
buzbeecbd6d442012-11-17 14:11:25 -0800271uintptr_t oatGrowableListGetElement(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 */
279void oatDumpMemStats(CompilationUnit* cUnit)
280{
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 */
317void oatDumpCompilationUnit(CompilationUnit* cUnit)
318{
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
Bill Buzbeea114add2012-05-03 15:00:40 -0700333 oatGrowableListIteratorInit(&cUnit->blockList, &iterator);
buzbee67bf8852011-08-17 17:51:35 -0700334
Bill Buzbeea114add2012-05-03 15:00:40 -0700335 while (true) {
buzbeecbd6d442012-11-17 14:11:25 -0800336 bb = reinterpret_cast<BasicBlock*>(oatGrowableListIteratorNext(&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 */
buzbeeba938cb2012-02-03 14:47:55 -0800370ArenaBitVector* oatAllocBitVector(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
buzbeecbd6d442012-11-17 14:11:25 -0800379 bv = static_cast<ArenaBitVector*>(oatNew(cUnit, sizeof(ArenaBitVector), false,
380 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;
buzbeeeaf09bc2012-11-15 14:51:41 -0800386 bv->storage = static_cast<uint32_t*>(oatNew(cUnit, count * sizeof(uint32_t), true,
387 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 */
398bool oatIsBitSet(const ArenaBitVector* pBits, unsigned int num)
399{
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 */
409void oatClearAllBits(ArenaBitVector* pBits)
410{
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 */
buzbeeba938cb2012-02-03 14:47:55 -0800423bool oatSetBit(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);
buzbeeeaf09bc2012-11-15 14:51:41 -0800433 uint32_t *newStorage = static_cast<uint32_t*>(oatNew(cUnit, newSize * sizeof(uint32_t), false,
434 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 */
460bool oatClearBit(ArenaBitVector* pBits, unsigned int num)
461{
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
470/*
471 * If set is true, mark all bits as 1. Otherwise mark all bits as 0.
472 */
473void oatMarkAllBits(ArenaBitVector* pBits, bool set)
474{
Bill Buzbeea114add2012-05-03 15:00:40 -0700475 int value = set ? -1 : 0;
buzbeeeaf09bc2012-11-15 14:51:41 -0800476 memset(pBits->storage, value, pBits->storageSize * static_cast<int>(sizeof(uint32_t)));
buzbee67bf8852011-08-17 17:51:35 -0700477}
478
479void oatDebugBitVector(char* msg, const ArenaBitVector* bv, int length)
480{
Bill Buzbeea114add2012-05-03 15:00:40 -0700481 int i;
buzbee67bf8852011-08-17 17:51:35 -0700482
Bill Buzbeea114add2012-05-03 15:00:40 -0700483 LOG(INFO) << msg;
484 for (i = 0; i < length; i++) {
485 if (oatIsBitSet(bv, i)) {
486 LOG(INFO) << " Bit " << i << " is set";
buzbee67bf8852011-08-17 17:51:35 -0700487 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700488 }
buzbee67bf8852011-08-17 17:51:35 -0700489}
490
491void oatAbort(CompilationUnit* cUnit)
492{
Bill Buzbeea114add2012-05-03 15:00:40 -0700493 LOG(FATAL) << "Compiler aborting";
buzbee67bf8852011-08-17 17:51:35 -0700494}
495
496void oatDumpBlockBitVector(const GrowableList* blocks, char* msg,
Bill Buzbeea114add2012-05-03 15:00:40 -0700497 const ArenaBitVector* bv, int length)
buzbee67bf8852011-08-17 17:51:35 -0700498{
Bill Buzbeea114add2012-05-03 15:00:40 -0700499 int i;
buzbee67bf8852011-08-17 17:51:35 -0700500
Bill Buzbeea114add2012-05-03 15:00:40 -0700501 LOG(INFO) << msg;
502 for (i = 0; i < length; i++) {
503 if (oatIsBitSet(bv, i)) {
buzbeecbd6d442012-11-17 14:11:25 -0800504 BasicBlock *bb = reinterpret_cast<BasicBlock*>(oatGrowableListGetElement(blocks, i));
Bill Buzbeea114add2012-05-03 15:00:40 -0700505 char blockName[BLOCK_NAME_LEN];
506 oatGetBlockName(bb, blockName);
507 LOG(INFO) << "Bit " << i << " / " << blockName << " is set";
buzbee67bf8852011-08-17 17:51:35 -0700508 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700509 }
buzbee67bf8852011-08-17 17:51:35 -0700510}
511/* Initialize the iterator structure */
512void oatBitVectorIteratorInit(ArenaBitVector* pBits,
Bill Buzbeea114add2012-05-03 15:00:40 -0700513 ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700514{
Bill Buzbeea114add2012-05-03 15:00:40 -0700515 iterator->pBits = pBits;
buzbeeeaf09bc2012-11-15 14:51:41 -0800516 iterator->bitSize = pBits->storageSize * sizeof(uint32_t) * 8;
Bill Buzbeea114add2012-05-03 15:00:40 -0700517 iterator->idx = 0;
buzbee67bf8852011-08-17 17:51:35 -0700518}
519
520/*
521 * If the vector sizes don't match, log an error and abort.
522 */
buzbee31a4a6f2012-02-28 15:36:15 -0800523void checkSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
buzbee67bf8852011-08-17 17:51:35 -0700524{
Bill Buzbeea114add2012-05-03 15:00:40 -0700525 if (bv1->storageSize != bv2->storageSize) {
526 LOG(FATAL) << "Mismatched vector sizes (" << bv1->storageSize
527 << ", " << bv2->storageSize << ")";
528 }
buzbee67bf8852011-08-17 17:51:35 -0700529}
530
531/*
532 * Copy a whole vector to the other. Only do that when the both vectors have
533 * the same size.
534 */
535void oatCopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src)
536{
Bill Buzbeea114add2012-05-03 15:00:40 -0700537 /* if dest is expandable and < src, we could expand dest to match */
538 checkSizes(dest, src);
buzbee67bf8852011-08-17 17:51:35 -0700539
buzbeeeaf09bc2012-11-15 14:51:41 -0800540 memcpy(dest->storage, src->storage, sizeof(uint32_t) * dest->storageSize);
buzbee67bf8852011-08-17 17:51:35 -0700541}
542
543/*
544 * Intersect two bit vectors and store the result to the dest vector.
545 */
546
547bool oatIntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700548 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700549{
Bill Buzbeea114add2012-05-03 15:00:40 -0700550 DCHECK(src1 != NULL);
551 DCHECK(src2 != NULL);
552 if (dest->storageSize != src1->storageSize ||
553 dest->storageSize != src2->storageSize ||
554 dest->expandable != src1->expandable ||
555 dest->expandable != src2->expandable)
556 return false;
buzbee67bf8852011-08-17 17:51:35 -0700557
Bill Buzbeea114add2012-05-03 15:00:40 -0700558 unsigned int idx;
559 for (idx = 0; idx < dest->storageSize; idx++) {
560 dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
561 }
562 return true;
buzbee67bf8852011-08-17 17:51:35 -0700563}
564
565/*
566 * Unify two bit vectors and store the result to the dest vector.
567 */
568bool oatUnifyBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700569 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700570{
Bill Buzbeea114add2012-05-03 15:00:40 -0700571 DCHECK(src1 != NULL);
572 DCHECK(src2 != NULL);
573 if (dest->storageSize != src1->storageSize ||
574 dest->storageSize != src2->storageSize ||
575 dest->expandable != src1->expandable ||
576 dest->expandable != src2->expandable)
577 return false;
buzbee67bf8852011-08-17 17:51:35 -0700578
Bill Buzbeea114add2012-05-03 15:00:40 -0700579 unsigned int idx;
580 for (idx = 0; idx < dest->storageSize; idx++) {
581 dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
582 }
583 return true;
buzbee67bf8852011-08-17 17:51:35 -0700584}
585
586/*
buzbeee1965672012-03-11 18:39:19 -0700587 * Return true if any bits collide. Vectors must be same size.
588 */
589bool oatTestBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700590 const ArenaBitVector* src2)
buzbeee1965672012-03-11 18:39:19 -0700591{
Bill Buzbeea114add2012-05-03 15:00:40 -0700592 DCHECK_EQ(src1->storageSize, src2->storageSize);
593 for (uint32_t idx = 0; idx < src1->storageSize; idx++) {
594 if (src1->storage[idx] & src2->storage[idx]) return true;
595 }
596 return false;
buzbeee1965672012-03-11 18:39:19 -0700597}
598
599/*
buzbee67bf8852011-08-17 17:51:35 -0700600 * Compare two bit vectors and return true if difference is seen.
601 */
602bool oatCompareBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700603 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700604{
Bill Buzbeea114add2012-05-03 15:00:40 -0700605 if (src1->storageSize != src2->storageSize ||
606 src1->expandable != src2->expandable)
607 return true;
buzbee67bf8852011-08-17 17:51:35 -0700608
Bill Buzbeea114add2012-05-03 15:00:40 -0700609 unsigned int idx;
610 for (idx = 0; idx < src1->storageSize; idx++) {
611 if (src1->storage[idx] != src2->storage[idx]) return true;
612 }
613 return false;
buzbee67bf8852011-08-17 17:51:35 -0700614}
615
616/*
617 * Count the number of bits that are set.
618 */
619int oatCountSetBits(const ArenaBitVector* pBits)
620{
Bill Buzbeea114add2012-05-03 15:00:40 -0700621 unsigned int word;
622 unsigned int count = 0;
buzbee67bf8852011-08-17 17:51:35 -0700623
Bill Buzbeea114add2012-05-03 15:00:40 -0700624 for (word = 0; word < pBits->storageSize; word++) {
buzbeeeaf09bc2012-11-15 14:51:41 -0800625 uint32_t val = pBits->storage[word];
buzbee67bf8852011-08-17 17:51:35 -0700626
Bill Buzbeea114add2012-05-03 15:00:40 -0700627 if (val != 0) {
628 if (val == 0xffffffff) {
629 count += 32;
630 } else {
631 /* count the number of '1' bits */
632 while (val != 0) {
633 val &= val - 1;
634 count++;
buzbee67bf8852011-08-17 17:51:35 -0700635 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700636 }
buzbee67bf8852011-08-17 17:51:35 -0700637 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700638 }
buzbee67bf8852011-08-17 17:51:35 -0700639
Bill Buzbeea114add2012-05-03 15:00:40 -0700640 return count;
buzbee67bf8852011-08-17 17:51:35 -0700641}
642
643/* Return the next position set to 1. -1 means end-of-element reached */
644int oatBitVectorIteratorNext(ArenaBitVectorIterator* iterator)
645{
Bill Buzbeea114add2012-05-03 15:00:40 -0700646 ArenaBitVector* pBits = iterator->pBits;
buzbeeeaf09bc2012-11-15 14:51:41 -0800647 uint32_t bitIndex = iterator->idx;
648 uint32_t bitSize = iterator->bitSize;
buzbee67bf8852011-08-17 17:51:35 -0700649
buzbeeeaf09bc2012-11-15 14:51:41 -0800650 DCHECK_EQ(bitSize, pBits->storageSize * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700651
Bill Buzbeea114add2012-05-03 15:00:40 -0700652 if (bitIndex >= bitSize) return -1;
buzbee5b537102012-01-17 17:33:47 -0800653
buzbeeeaf09bc2012-11-15 14:51:41 -0800654 uint32_t wordIndex = bitIndex >> 5;
655 uint32_t endWordIndex = bitSize >> 5;
656 uint32_t* storage = pBits->storage;
657 uint32_t word = storage[wordIndex++];
buzbee5b537102012-01-17 17:33:47 -0800658
Bill Buzbeea114add2012-05-03 15:00:40 -0700659 // Mask out any bits in the first word we've already considered
660 word &= ~((1 << (bitIndex & 0x1f))-1);
buzbee5abfa3e2012-01-31 17:01:43 -0800661
Bill Buzbeea114add2012-05-03 15:00:40 -0700662 for (; wordIndex <= endWordIndex;) {
buzbeeeaf09bc2012-11-15 14:51:41 -0800663 uint32_t bitPos = bitIndex & 0x1f;
Bill Buzbeea114add2012-05-03 15:00:40 -0700664 if (word == 0) {
665 bitIndex += (32 - bitPos);
666 word = storage[wordIndex++];
667 continue;
buzbee67bf8852011-08-17 17:51:35 -0700668 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700669 for (; bitPos < 32; bitPos++) {
670 if (word & (1 << bitPos)) {
671 iterator->idx = bitIndex + 1;
672 return bitIndex;
673 }
674 bitIndex++;
675 }
676 word = storage[wordIndex++];
677 }
678 iterator->idx = iterator->bitSize;
679 return -1;
buzbee67bf8852011-08-17 17:51:35 -0700680}
681
682/*
683 * Mark specified number of bits as "set". Cannot set all bits like ClearAll
684 * since there might be unused bits - setting those to one will confuse the
685 * iterator.
686 */
687void oatSetInitialBits(ArenaBitVector* pBits, unsigned int numBits)
688{
Bill Buzbeea114add2012-05-03 15:00:40 -0700689 unsigned int idx;
690 DCHECK_LE(((numBits + 31) >> 5), pBits->storageSize);
691 for (idx = 0; idx < (numBits >> 5); idx++) {
692 pBits->storage[idx] = -1;
693 }
694 unsigned int remNumBits = numBits & 0x1f;
695 if (remNumBits) {
696 pBits->storage[idx] = (1 << remNumBits) - 1;
697 }
buzbee67bf8852011-08-17 17:51:35 -0700698}
699
700void oatGetBlockName(BasicBlock* bb, char* name)
701{
Bill Buzbeea114add2012-05-03 15:00:40 -0700702 switch (bb->blockType) {
703 case kEntryBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700704 snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700705 break;
706 case kExitBlock:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700707 snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700708 break;
709 case kDalvikByteCode:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700710 snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->startOffset, bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700711 break;
712 case kExceptionHandling:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700713 snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->startOffset,
714 bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700715 break;
716 default:
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700717 snprintf(name, BLOCK_NAME_LEN, "??_%d", bb->id);
Bill Buzbeea114add2012-05-03 15:00:40 -0700718 break;
719 }
buzbee67bf8852011-08-17 17:51:35 -0700720}
buzbeeed3e9302011-09-23 17:34:19 -0700721
722const char* oatGetShortyFromTargetIdx(CompilationUnit *cUnit, int targetIdx)
723{
Bill Buzbeea114add2012-05-03 15:00:40 -0700724 const DexFile::MethodId& methodId = cUnit->dex_file->GetMethodId(targetIdx);
725 return cUnit->dex_file->GetShorty(methodId.proto_idx_);
buzbeeed3e9302011-09-23 17:34:19 -0700726}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800727
728} // namespace art