| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 1 | /* | 
 | 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 Hughes | 11d1b0c | 2012-01-23 16:57:47 -0800 | [diff] [blame] | 20 | namespace art { | 
 | 21 |  | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 22 | #ifdef WITH_MEMSTATS | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 23 | typedef struct Memstats { | 
 | 24 |     u4 allocStats[kNumAllocKinds]; | 
 | 25 |     int listSizes[kNumListKinds]; | 
 | 26 |     int listWasted[kNumListKinds]; | 
 | 27 |     int listGrows[kNumListKinds]; | 
 | 28 |     int listMaxElems[kNumListKinds]; | 
 | 29 |     int bitMapSizes[kNumBitMapKinds]; | 
 | 30 |     int bitMapWasted[kNumBitMapKinds]; | 
 | 31 |     int bitMapGrows[kNumBitMapKinds]; | 
 | 32 | } memstats; | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 33 |  | 
 | 34 | const 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 |  | 
 | 50 | const 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 |  | 
 | 65 | const 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 |  | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 85 | #define kArenaBitVectorGrowth    4   /* increase by 4 u4s when limit hit */ | 
 | 86 |  | 
 | 87 | /* Allocate the initial memory block for arena-based allocation */ | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 88 | bool oatHeapInit(CompilationUnit* cUnit) | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 89 | { | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 90 |     DCHECK(cUnit->arenaHead == NULL); | 
 | 91 |     cUnit->arenaHead = | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 92 |         (ArenaMemBlock *) malloc(sizeof(ArenaMemBlock) + ARENA_DEFAULT_SIZE); | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 93 |     if (cUnit->arenaHead == NULL) { | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 94 |         LOG(FATAL) << "No memory left to create compiler heap memory"; | 
 | 95 |     } | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 96 |     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 | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 105 |     return true; | 
 | 106 | } | 
 | 107 |  | 
 | 108 | /* Arena-based malloc for compilation tasks */ | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 109 | void* oatNew(CompilationUnit* cUnit, size_t size, bool zero, oatAllocKind kind) | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 110 | { | 
 | 111 |     size = (size + 3) & ~3; | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 112 | #ifdef WITH_MEMSTATS | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 113 |     if (cUnit->mstats != NULL) { | 
 | 114 |         cUnit->mstats->allocStats[kind] += size; | 
 | 115 |     } | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 116 | #endif | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 117 | retry: | 
 | 118 |     /* Normal case - space is available in the current page */ | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 119 |     if (size + cUnit->currentArena->bytesAllocated <= | 
 | 120 |         cUnit->currentArena->blockSize) { | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 121 |         void *ptr; | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 122 |         ptr = &cUnit->currentArena->ptr[cUnit->currentArena->bytesAllocated]; | 
 | 123 |         cUnit->currentArena->bytesAllocated += size; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 124 |         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 |          */ | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 133 |         if (cUnit->currentArena->next) { | 
 | 134 |             cUnit->currentArena = cUnit->currentArena->next; | 
 | 135 |             cUnit->currentArena->bytesAllocated = 0; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 136 |             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; | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 150 |         cUnit->currentArena->next = newArena; | 
 | 151 |         cUnit->currentArena = newArena; | 
 | 152 |         cUnit->numArenaBlocks++; | 
 | 153 |         if (cUnit->numArenaBlocks > 20000) { | 
 | 154 |             LOG(INFO) << "Total arena pages: " << cUnit->numArenaBlocks; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 155 |         } | 
 | 156 |         goto retry; | 
 | 157 |     } | 
 | 158 | } | 
 | 159 |  | 
 | 160 | /* Reclaim all the arena blocks allocated so far */ | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 161 | void oatArenaReset(CompilationUnit* cUnit) | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 162 | { | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 163 |     ArenaMemBlock* head = cUnit->arenaHead; | 
 | 164 |     while (head != NULL) { | 
 | 165 |         ArenaMemBlock* p = head; | 
 | 166 |         head = head->next; | 
 | 167 |         free(p); | 
| buzbee | 67bc236 | 2011-10-11 18:08:40 -0700 | [diff] [blame] | 168 |     } | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 169 |     cUnit->arenaHead = NULL; | 
 | 170 |     cUnit->currentArena = NULL; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 171 | } | 
 | 172 |  | 
 | 173 | /* Growable List initialization */ | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 174 | void oatInitGrowableList(CompilationUnit* cUnit, GrowableList* gList, | 
 | 175 |                          size_t initLength, oatListKind kind) | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 176 | { | 
 | 177 |     gList->numAllocated = initLength; | 
 | 178 |     gList->numUsed = 0; | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 179 |     gList->elemList = (intptr_t *) oatNew(cUnit, sizeof(intptr_t) * initLength, | 
 | 180 |                                           true, kAllocGrowableList); | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 181 | #ifdef WITH_MEMSTATS | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 182 |     cUnit->mstats->listSizes[kind] += sizeof(intptr_t) * initLength; | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 183 |     gList->kind = kind; | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 184 |     if ((int)initLength > cUnit->mstats->listMaxElems[kind]) { | 
 | 185 |         cUnit->mstats->listMaxElems[kind] = initLength; | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 186 |     } | 
 | 187 | #endif | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 188 | } | 
 | 189 |  | 
 | 190 | /* Expand the capacity of a growable list */ | 
| buzbee | 31a4a6f | 2012-02-28 15:36:15 -0800 | [diff] [blame] | 191 | void expandGrowableList(CompilationUnit* cUnit, GrowableList* gList) | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 192 | { | 
 | 193 |     int newLength = gList->numAllocated; | 
 | 194 |     if (newLength < 128) { | 
 | 195 |         newLength <<= 1; | 
 | 196 |     } else { | 
 | 197 |         newLength += 128; | 
 | 198 |     } | 
 | 199 |     intptr_t *newArray = | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 200 |         (intptr_t *) oatNew(cUnit, sizeof(intptr_t) * newLength, true, | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 201 |                             kAllocGrowableList); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 202 |     memcpy(newArray, gList->elemList, sizeof(intptr_t) * gList->numAllocated); | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 203 | #ifdef WITH_MEMSTATS | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 204 |     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; | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 210 |     } | 
 | 211 | #endif | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 212 |     gList->numAllocated = newLength; | 
 | 213 |     gList->elemList = newArray; | 
 | 214 | } | 
 | 215 |  | 
 | 216 | /* Insert a new element into the growable list */ | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 217 | void oatInsertGrowableList(CompilationUnit* cUnit, GrowableList* gList, | 
 | 218 |                            intptr_t elem) | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 219 | { | 
| Elliott Hughes | f5a7a47 | 2011-10-07 14:31:02 -0700 | [diff] [blame] | 220 |     DCHECK_NE(gList->numAllocated, 0U); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 221 |     if (gList->numUsed == gList->numAllocated) { | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 222 |         expandGrowableList(cUnit, gList); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 223 |     } | 
 | 224 |     gList->elemList[gList->numUsed++] = elem; | 
 | 225 | } | 
 | 226 |  | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 227 | /* Delete an element from a growable list. Element must be present */ | 
 | 228 | void 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 |  | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 243 | void oatGrowableListIteratorInit(GrowableList* gList, | 
 | 244 |                                  GrowableListIterator* iterator) | 
 | 245 | { | 
 | 246 |     iterator->list = gList; | 
 | 247 |     iterator->idx = 0; | 
 | 248 |     iterator->size = gList->numUsed; | 
 | 249 | } | 
 | 250 |  | 
 | 251 | intptr_t oatGrowableListIteratorNext(GrowableListIterator* iterator) | 
 | 252 | { | 
| buzbee | ed3e930 | 2011-09-23 17:34:19 -0700 | [diff] [blame] | 253 |     DCHECK_EQ(iterator->size, iterator->list->numUsed); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 254 |     if (iterator->idx == iterator->size) return 0; | 
 | 255 |     return iterator->list->elemList[iterator->idx++]; | 
 | 256 | } | 
 | 257 |  | 
 | 258 | intptr_t oatGrowableListGetElement(const GrowableList* gList, size_t idx) | 
 | 259 | { | 
| buzbee | ed3e930 | 2011-09-23 17:34:19 -0700 | [diff] [blame] | 260 |     DCHECK_LT(idx, gList->numUsed); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 261 |     return gList->elemList[idx]; | 
 | 262 | } | 
 | 263 |  | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 264 | #ifdef WITH_MEMSTATS | 
 | 265 | /* Dump memory usage stats */ | 
 | 266 | void oatDumpMemStats(CompilationUnit* cUnit) | 
 | 267 | { | 
 | 268 |     u4 total = 0; | 
 | 269 |     for (int i = 0; i < kNumAllocKinds; i++) { | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 270 |         total += cUnit->mstats->allocStats[i]; | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 271 |     } | 
 | 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++) { | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 281 |             LOG(INFO) << allocNames[i] << std::setw(10) << | 
 | 282 |             cUnit->mstats->allocStats[i]; | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 283 |         } | 
 | 284 |         LOG(INFO) << "===== GrowableList allocations"; | 
 | 285 |         for (int i = 0; i < kNumListKinds; i++) { | 
 | 286 |             LOG(INFO) << listNames[i] | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 287 |                 << " S:" << cUnit->mstats->listSizes[i] | 
 | 288 |                 << ", W:" << cUnit->mstats->listWasted[i] | 
 | 289 |                 << ", G:" << cUnit->mstats->listGrows[i] | 
 | 290 |                 << ", E:" << cUnit->mstats->listMaxElems[i]; | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 291 |         } | 
 | 292 |         LOG(INFO) << "===== GrowableBitMap allocations"; | 
 | 293 |         for (int i = 0; i < kNumBitMapKinds; i++) { | 
 | 294 |             LOG(INFO) << bitMapNames[i] | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 295 |                 << " S:" << cUnit->mstats->bitMapSizes[i] | 
 | 296 |                 << ", W:" << cUnit->mstats->bitMapWasted[i] | 
 | 297 |                 << ", G:" << cUnit->mstats->bitMapGrows[i]; | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 298 |         } | 
 | 299 |     } | 
 | 300 | } | 
 | 301 | #endif | 
 | 302 |  | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 303 | /* Debug Utility - dump a compilation unit */ | 
 | 304 | void 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 Hughes | 11d1b0c | 2012-01-23 16:57:47 -0800 | [diff] [blame] | 315 |     LOG(INFO) << "Compiling " << PrettyMethod(cUnit->method_idx, *cUnit->dex_file); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 316 |     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 |  | 
| buzbee | 67bc236 | 2011-10-11 18:08:40 -0700 | [diff] [blame] | 344 | static 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 |  | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 353 | /* | 
 | 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 |  */ | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 359 | ArenaBitVector* oatAllocBitVector(CompilationUnit* cUnit, | 
 | 360 |                                   unsigned int startBits, bool expandable, | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 361 |                                   oatBitMapKind kind) | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 362 | { | 
 | 363 |     ArenaBitVector* bv; | 
 | 364 |     unsigned int count; | 
 | 365 |  | 
| Elliott Hughes | f5a7a47 | 2011-10-07 14:31:02 -0700 | [diff] [blame] | 366 |     DCHECK_EQ(sizeof(bv->storage[0]), 4U);        /* assuming 32-bit units */ | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 367 |  | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 368 |     bv = (ArenaBitVector*) oatNew(cUnit, sizeof(ArenaBitVector), false, | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 369 |                                   kAllocGrowableBitMap); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 370 |  | 
 | 371 |     count = (startBits + 31) >> 5; | 
 | 372 |  | 
 | 373 |     bv->storageSize = count; | 
 | 374 |     bv->expandable = expandable; | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 375 |     bv->storage = (u4*) oatNew(cUnit, count * sizeof(u4), true, | 
 | 376 |                                kAllocGrowableBitMap); | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 377 | #ifdef WITH_MEMSTATS | 
 | 378 |     bv->kind = kind; | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 379 |     cUnit->mstats->bitMapSizes[kind] += count * sizeof(u4); | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 380 | #endif | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 381 |     return bv; | 
 | 382 | } | 
 | 383 |  | 
 | 384 | /* | 
 | 385 |  * Determine whether or not the specified bit is set. | 
 | 386 |  */ | 
 | 387 | bool oatIsBitSet(const ArenaBitVector* pBits, unsigned int num) | 
 | 388 | { | 
| buzbee | ed3e930 | 2011-09-23 17:34:19 -0700 | [diff] [blame] | 389 |     DCHECK_LT(num, pBits->storageSize * sizeof(u4) * 8); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 390 |  | 
| buzbee | 67bc236 | 2011-10-11 18:08:40 -0700 | [diff] [blame] | 391 |     unsigned int val = pBits->storage[num >> 5] & checkMasks[num & 0x1f]; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 392 |     return (val != 0); | 
 | 393 | } | 
 | 394 |  | 
 | 395 | /* | 
 | 396 |  * Mark all bits bit as "clear". | 
 | 397 |  */ | 
 | 398 | void 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 |  */ | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 412 | bool oatSetBit(CompilationUnit* cUnit, ArenaBitVector* pBits, unsigned int num) | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 413 | { | 
 | 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; | 
| buzbee | ed3e930 | 2011-09-23 17:34:19 -0700 | [diff] [blame] | 421 |         DCHECK_GT(newSize, pBits->storageSize); | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 422 |         u4 *newStorage = (u4*)oatNew(cUnit, newSize * sizeof(u4), false, | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 423 |                                      kAllocGrowableBitMap); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 424 |         memcpy(newStorage, pBits->storage, pBits->storageSize * sizeof(u4)); | 
 | 425 |         memset(&newStorage[pBits->storageSize], 0, | 
 | 426 |                (newSize - pBits->storageSize) * sizeof(u4)); | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 427 | #ifdef WITH_MEMSTATS | 
| buzbee | ba938cb | 2012-02-03 14:47:55 -0800 | [diff] [blame] | 428 |         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]++; | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 432 | #endif | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 433 |         pBits->storage = newStorage; | 
 | 434 |         pBits->storageSize = newSize; | 
 | 435 |     } | 
 | 436 |  | 
| buzbee | 67bc236 | 2011-10-11 18:08:40 -0700 | [diff] [blame] | 437 |     pBits->storage[num >> 5] |= checkMasks[num & 0x1f]; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 438 |     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 |  */ | 
 | 449 | bool 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 |  | 
| buzbee | 67bc236 | 2011-10-11 18:08:40 -0700 | [diff] [blame] | 455 |     pBits->storage[num >> 5] &= ~checkMasks[num & 0x1f]; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 456 |     return true; | 
 | 457 | } | 
 | 458 |  | 
 | 459 | /* | 
 | 460 |  * If set is true, mark all bits as 1. Otherwise mark all bits as 0. | 
 | 461 |  */ | 
 | 462 | void oatMarkAllBits(ArenaBitVector* pBits, bool set) | 
 | 463 | { | 
 | 464 |     int value = set ? -1 : 0; | 
 | 465 |     memset(pBits->storage, value, pBits->storageSize * (int)sizeof(u4)); | 
 | 466 | } | 
 | 467 |  | 
 | 468 | void 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 |  | 
 | 480 | void oatAbort(CompilationUnit* cUnit) | 
 | 481 | { | 
 | 482 |     LOG(FATAL) << "Compiler aborting"; | 
 | 483 | } | 
 | 484 |  | 
 | 485 | void 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 */ | 
 | 502 | void 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 |  */ | 
| buzbee | 31a4a6f | 2012-02-28 15:36:15 -0800 | [diff] [blame] | 513 | void checkSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2) | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 514 | { | 
 | 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 |  */ | 
 | 525 | void 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 |  | 
 | 537 | bool oatIntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1, | 
 | 538 |                             const ArenaBitVector* src2) | 
 | 539 | { | 
| buzbee | aad7201 | 2011-09-21 21:52:09 -0700 | [diff] [blame] | 540 |     DCHECK(src1 != NULL); | 
 | 541 |     DCHECK(src2 != NULL); | 
 | 542 |     if (dest->storageSize != src1->storageSize || | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 543 |         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 |  */ | 
 | 558 | bool oatUnifyBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1, | 
 | 559 |                         const ArenaBitVector* src2) | 
 | 560 | { | 
| buzbee | aad7201 | 2011-09-21 21:52:09 -0700 | [diff] [blame] | 561 |     DCHECK(src1 != NULL); | 
 | 562 |     DCHECK(src2 != NULL); | 
 | 563 |     if (dest->storageSize != src1->storageSize || | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 564 |         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 | /* | 
 | 577 |  * Compare two bit vectors and return true if difference is seen. | 
 | 578 |  */ | 
 | 579 | bool oatCompareBitVectors(const ArenaBitVector* src1, | 
 | 580 |                           const ArenaBitVector* src2) | 
 | 581 | { | 
 | 582 |     if (src1->storageSize != src2->storageSize || | 
 | 583 |         src1->expandable != src2->expandable) | 
 | 584 |         return true; | 
 | 585 |  | 
 | 586 |     unsigned int idx; | 
 | 587 |     for (idx = 0; idx < src1->storageSize; idx++) { | 
 | 588 |         if (src1->storage[idx] != src2->storage[idx]) return true; | 
 | 589 |     } | 
 | 590 |     return false; | 
 | 591 | } | 
 | 592 |  | 
 | 593 | /* | 
 | 594 |  * Count the number of bits that are set. | 
 | 595 |  */ | 
 | 596 | int oatCountSetBits(const ArenaBitVector* pBits) | 
 | 597 | { | 
 | 598 |     unsigned int word; | 
 | 599 |     unsigned int count = 0; | 
 | 600 |  | 
 | 601 |     for (word = 0; word < pBits->storageSize; word++) { | 
 | 602 |         u4 val = pBits->storage[word]; | 
 | 603 |  | 
 | 604 |         if (val != 0) { | 
 | 605 |             if (val == 0xffffffff) { | 
 | 606 |                 count += 32; | 
 | 607 |             } else { | 
 | 608 |                 /* count the number of '1' bits */ | 
 | 609 |                 while (val != 0) { | 
 | 610 |                     val &= val - 1; | 
 | 611 |                     count++; | 
 | 612 |                 } | 
 | 613 |             } | 
 | 614 |         } | 
 | 615 |     } | 
 | 616 |  | 
 | 617 |     return count; | 
 | 618 | } | 
 | 619 |  | 
 | 620 | /* Return the next position set to 1. -1 means end-of-element reached */ | 
 | 621 | int oatBitVectorIteratorNext(ArenaBitVectorIterator* iterator) | 
 | 622 | { | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 623 |     ArenaBitVector* pBits = iterator->pBits; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 624 |     u4 bitIndex = iterator->idx; | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 625 |     u4 bitSize = iterator->bitSize; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 626 |  | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 627 |     DCHECK_EQ(bitSize, pBits->storageSize * sizeof(u4) * 8); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 628 |  | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 629 |     if (bitIndex >= bitSize) return -1; | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 630 |  | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 631 |     u4 wordIndex = bitIndex >> 5; | 
 | 632 |     u4 endWordIndex = bitSize >> 5; | 
 | 633 |     u4* storage = pBits->storage; | 
 | 634 |     u4 word = storage[wordIndex++]; | 
| buzbee | 5b53710 | 2012-01-17 17:33:47 -0800 | [diff] [blame] | 635 |  | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 636 |     // Mask out any bits in the first word we've already considered | 
 | 637 |     word &= ~((1 << (bitIndex & 0x1f))-1); | 
 | 638 |  | 
 | 639 |     for (; wordIndex <= endWordIndex;) { | 
 | 640 |         u4 bitPos = bitIndex & 0x1f; | 
| buzbee | 67bc236 | 2011-10-11 18:08:40 -0700 | [diff] [blame] | 641 |         if (word == 0) { | 
| buzbee | 67bc236 | 2011-10-11 18:08:40 -0700 | [diff] [blame] | 642 |             bitIndex += (32 - bitPos); | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 643 |             word = storage[wordIndex++]; | 
 | 644 |             continue; | 
 | 645 |         } | 
 | 646 |         for (; bitPos < 32; bitPos++) { | 
 | 647 |             if (word & (1 << bitPos)) { | 
 | 648 |                 iterator->idx = bitIndex + 1; | 
 | 649 |                 return bitIndex; | 
 | 650 |             } | 
| buzbee | 67bc236 | 2011-10-11 18:08:40 -0700 | [diff] [blame] | 651 |             bitIndex++; | 
 | 652 |         } | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 653 |         word = storage[wordIndex++]; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 654 |     } | 
| buzbee | 5abfa3e | 2012-01-31 17:01:43 -0800 | [diff] [blame] | 655 |     iterator->idx = iterator->bitSize; | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 656 |     return -1; | 
 | 657 | } | 
 | 658 |  | 
 | 659 | /* | 
 | 660 |  * Mark specified number of bits as "set". Cannot set all bits like ClearAll | 
 | 661 |  * since there might be unused bits - setting those to one will confuse the | 
 | 662 |  * iterator. | 
 | 663 |  */ | 
 | 664 | void oatSetInitialBits(ArenaBitVector* pBits, unsigned int numBits) | 
 | 665 | { | 
 | 666 |     unsigned int idx; | 
| buzbee | ed3e930 | 2011-09-23 17:34:19 -0700 | [diff] [blame] | 667 |     DCHECK_LE(((numBits + 31) >> 5), pBits->storageSize); | 
| buzbee | 67bf885 | 2011-08-17 17:51:35 -0700 | [diff] [blame] | 668 |     for (idx = 0; idx < (numBits >> 5); idx++) { | 
 | 669 |         pBits->storage[idx] = -1; | 
 | 670 |     } | 
 | 671 |     unsigned int remNumBits = numBits & 0x1f; | 
 | 672 |     if (remNumBits) { | 
 | 673 |         pBits->storage[idx] = (1 << remNumBits) - 1; | 
 | 674 |     } | 
 | 675 | } | 
 | 676 |  | 
 | 677 | void oatGetBlockName(BasicBlock* bb, char* name) | 
 | 678 | { | 
 | 679 |     switch (bb->blockType) { | 
 | 680 |         case kEntryBlock: | 
 | 681 |             snprintf(name, BLOCK_NAME_LEN, "entry"); | 
 | 682 |             break; | 
 | 683 |         case kExitBlock: | 
 | 684 |             snprintf(name, BLOCK_NAME_LEN, "exit"); | 
 | 685 |             break; | 
 | 686 |         case kDalvikByteCode: | 
 | 687 |             snprintf(name, BLOCK_NAME_LEN, "block%04x", bb->startOffset); | 
 | 688 |             break; | 
 | 689 |         case kExceptionHandling: | 
 | 690 |             snprintf(name, BLOCK_NAME_LEN, "exception%04x", bb->startOffset); | 
 | 691 |             break; | 
 | 692 |         default: | 
 | 693 |             snprintf(name, BLOCK_NAME_LEN, "??"); | 
 | 694 |             break; | 
 | 695 |     } | 
 | 696 | } | 
| buzbee | ed3e930 | 2011-09-23 17:34:19 -0700 | [diff] [blame] | 697 |  | 
 | 698 | const char* oatGetShortyFromTargetIdx(CompilationUnit *cUnit, int targetIdx) | 
 | 699 | { | 
| Elliott Hughes | 11d1b0c | 2012-01-23 16:57:47 -0800 | [diff] [blame] | 700 |     const DexFile::MethodId& methodId = cUnit->dex_file->GetMethodId(targetIdx); | 
| Ian Rogers | a3760aa | 2011-11-14 14:32:37 -0800 | [diff] [blame] | 701 |     return cUnit->dex_file->GetShorty(methodId.proto_idx_); | 
| buzbee | ed3e930 | 2011-09-23 17:34:19 -0700 | [diff] [blame] | 702 | } | 
| Elliott Hughes | 11d1b0c | 2012-01-23 16:57:47 -0800 | [diff] [blame] | 703 |  | 
 | 704 | }  // namespace art |