blob: 71c97139e5502f4f6befb64abbc23e25e6edbb7e [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"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070018#include "dex_file-inl.h"
buzbee67bf8852011-08-17 17:51:35 -070019
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080020namespace art {
21
buzbee5abfa3e2012-01-31 17:01:43 -080022#ifdef WITH_MEMSTATS
Elliott Hughes719ace42012-03-09 18:06:03 -080023struct Memstats {
buzbeefa57c472012-11-21 12:06:18 -080024 uint32_t alloc_stats[kNumAllocKinds];
25 int list_sizes[kNumListKinds];
26 int list_wasted[kNumListKinds];
27 int list_grows[kNumListKinds];
28 int list_max_elems[kNumListKinds];
29 int bit_map_sizes[kNumBitMapKinds];
30 int bit_map_wasted[kNumBitMapKinds];
31 int bit_map_grows[kNumBitMapKinds];
Elliott Hughes719ace42012-03-09 18:06:03 -080032};
buzbee5abfa3e2012-01-31 17:01:43 -080033
buzbeefa57c472012-11-21 12:06:18 -080034const char* alloc_names[kNumAllocKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070035 "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 ",
buzbee5abfa3e2012-01-31 17:01:43 -080048};
49
buzbeefa57c472012-11-21 12:06:18 -080050const char* list_names[kNumListKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070051 "Misc ",
buzbeefa57c472012-11-21 12:06:18 -080052 "block_list ",
Bill Buzbeea114add2012-05-03 15:00:40 -070053 "SSAtoDalvik ",
buzbeefa57c472012-11-21 12:06:18 -080054 "dfs_order ",
55 "dfs_post_order ",
56 "dom_post_order_traversal ",
57 "throw_launch_pads ",
58 "suspend_launch_pads ",
59 "switch_tables ",
60 "fill_array_data ",
Bill Buzbeea114add2012-05-03 15:00:40 -070061 "SuccessorBlocks ",
62 "Predecessors ",
buzbee5abfa3e2012-01-31 17:01:43 -080063};
64
buzbeefa57c472012-11-21 12:06:18 -080065const char* bit_map_names[kNumBitMapKinds] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070066 "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 ",
buzbee5abfa3e2012-01-31 17:01:43 -080082};
83#endif
84
buzbeeeaf09bc2012-11-15 14:51:41 -080085#define kArenaBitVectorGrowth 4 /* increase by 4 uint32_ts when limit hit */
buzbee67bf8852011-08-17 17:51:35 -070086
87/* Allocate the initial memory block for arena-based allocation */
buzbeefa57c472012-11-21 12:06:18 -080088bool HeapInit(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -070089{
buzbeefa57c472012-11-21 12:06:18 -080090 DCHECK(cu->arena_head == NULL);
91 cu->arena_head =
buzbeecbd6d442012-11-17 14:11:25 -080092 static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + ARENA_DEFAULT_SIZE));
buzbeefa57c472012-11-21 12:06:18 -080093 if (cu->arena_head == NULL) {
Bill Buzbeea114add2012-05-03 15:00:40 -070094 LOG(FATAL) << "No memory left to create compiler heap memory";
95 }
buzbeefa57c472012-11-21 12:06:18 -080096 cu->arena_head->block_size = ARENA_DEFAULT_SIZE;
97 cu->current_arena = cu->arena_head;
98 cu->current_arena->bytes_allocated = 0;
99 cu->current_arena->next = NULL;
100 cu->num_arena_blocks = 1;
buzbeeba938cb2012-02-03 14:47:55 -0800101#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800102 cu->mstats = (Memstats*) NewMem(cu, sizeof(Memstats), true,
Bill Buzbeea114add2012-05-03 15:00:40 -0700103 kAllocDebugInfo);
buzbeeba938cb2012-02-03 14:47:55 -0800104#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700105 return true;
buzbee67bf8852011-08-17 17:51:35 -0700106}
107
108/* Arena-based malloc for compilation tasks */
buzbeefa57c472012-11-21 12:06:18 -0800109void* NewMem(CompilationUnit* cu, size_t size, bool zero, oat_alloc_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700110{
Bill Buzbeea114add2012-05-03 15:00:40 -0700111 size = (size + 3) & ~3;
buzbee5abfa3e2012-01-31 17:01:43 -0800112#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800113 if (cu->mstats != NULL) {
114 cu->mstats->alloc_stats[kind] += size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700115 }
buzbee5abfa3e2012-01-31 17:01:43 -0800116#endif
buzbee67bf8852011-08-17 17:51:35 -0700117retry:
Bill Buzbeea114add2012-05-03 15:00:40 -0700118 /* Normal case - space is available in the current page */
buzbeefa57c472012-11-21 12:06:18 -0800119 if (size + cu->current_arena->bytes_allocated <=
120 cu->current_arena->block_size) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700121 void *ptr;
buzbeefa57c472012-11-21 12:06:18 -0800122 ptr = &cu->current_arena->ptr[cu->current_arena->bytes_allocated];
123 cu->current_arena->bytes_allocated += size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700124 if (zero) {
125 memset(ptr, 0, size);
126 }
127 return ptr;
128 } else {
129 /*
130 * See if there are previously allocated arena blocks before the last
131 * reset
132 */
buzbeefa57c472012-11-21 12:06:18 -0800133 if (cu->current_arena->next) {
134 cu->current_arena = cu->current_arena->next;
135 cu->current_arena->bytes_allocated = 0;
buzbee67bf8852011-08-17 17:51:35 -0700136 goto retry;
137 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700138
buzbeefa57c472012-11-21 12:06:18 -0800139 size_t block_size = (size < ARENA_DEFAULT_SIZE) ? ARENA_DEFAULT_SIZE : size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700140 /* Time to allocate a new arena */
buzbeefa57c472012-11-21 12:06:18 -0800141 ArenaMemBlock *new_arena =
142 static_cast<ArenaMemBlock*>(malloc(sizeof(ArenaMemBlock) + block_size));
143 if (new_arena == NULL) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700144 LOG(FATAL) << "Arena allocation failure";
145 }
buzbeefa57c472012-11-21 12:06:18 -0800146 new_arena->block_size = block_size;
147 new_arena->bytes_allocated = 0;
148 new_arena->next = NULL;
149 cu->current_arena->next = new_arena;
150 cu->current_arena = new_arena;
151 cu->num_arena_blocks++;
152 if (cu->num_arena_blocks > 20000) {
153 LOG(INFO) << "Total arena pages: " << cu->num_arena_blocks;
Bill Buzbeea114add2012-05-03 15:00:40 -0700154 }
155 goto retry;
156 }
buzbee67bf8852011-08-17 17:51:35 -0700157}
158
159/* Reclaim all the arena blocks allocated so far */
buzbeefa57c472012-11-21 12:06:18 -0800160void ArenaReset(CompilationUnit* cu)
buzbee67bf8852011-08-17 17:51:35 -0700161{
buzbeefa57c472012-11-21 12:06:18 -0800162 ArenaMemBlock* head = cu->arena_head;
Bill Buzbeea114add2012-05-03 15:00:40 -0700163 while (head != NULL) {
164 ArenaMemBlock* p = head;
165 head = head->next;
166 free(p);
167 }
buzbeefa57c472012-11-21 12:06:18 -0800168 cu->arena_head = NULL;
169 cu->current_arena = NULL;
buzbee67bf8852011-08-17 17:51:35 -0700170}
171
172/* Growable List initialization */
buzbeefa57c472012-11-21 12:06:18 -0800173void CompilerInitGrowableList(CompilationUnit* cu, GrowableList* g_list,
174 size_t init_length, oat_list_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700175{
buzbeefa57c472012-11-21 12:06:18 -0800176 g_list->num_allocated = init_length;
177 g_list->num_used = 0;
178 g_list->elem_list = static_cast<uintptr_t *>(NewMem(cu, sizeof(intptr_t) * init_length,
buzbeecbd6d442012-11-17 14:11:25 -0800179 true, kAllocGrowableList));
buzbee5abfa3e2012-01-31 17:01:43 -0800180#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800181 cu->mstats->list_sizes[kind] += sizeof(uintptr_t) * init_length;
182 g_list->kind = kind;
183 if (static_cast<int>(init_length) > cu->mstats->list_max_elems[kind]) {
184 cu->mstats->list_max_elems[kind] = init_length;
Bill Buzbeea114add2012-05-03 15:00:40 -0700185 }
buzbee5abfa3e2012-01-31 17:01:43 -0800186#endif
buzbee67bf8852011-08-17 17:51:35 -0700187}
188
buzbee311ca162013-02-28 15:56:43 -0800189void ReallocGrowableList(CompilationUnit* cu, GrowableList* g_list, size_t new_length)
190{
191 if (new_length > g_list->num_allocated) {
192 uintptr_t *new_array =
193 static_cast<uintptr_t*>(NewMem(cu, sizeof(uintptr_t) * new_length, true,
194 kAllocGrowableList));
195 memcpy(new_array, g_list->elem_list, sizeof(uintptr_t) * g_list->num_allocated);
196 g_list->num_allocated = new_length;
197 g_list->elem_list = new_array;
198 }
199}
200
buzbee67bf8852011-08-17 17:51:35 -0700201/* Expand the capacity of a growable list */
buzbeefa57c472012-11-21 12:06:18 -0800202static void ExpandGrowableList(CompilationUnit* cu, GrowableList* g_list)
buzbee67bf8852011-08-17 17:51:35 -0700203{
buzbeefa57c472012-11-21 12:06:18 -0800204 int new_length = g_list->num_allocated;
205 if (new_length < 128) {
206 new_length <<= 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700207 } else {
buzbeefa57c472012-11-21 12:06:18 -0800208 new_length += 128;
Bill Buzbeea114add2012-05-03 15:00:40 -0700209 }
buzbeefa57c472012-11-21 12:06:18 -0800210 uintptr_t *new_array =
211 static_cast<uintptr_t*>(NewMem(cu, sizeof(uintptr_t) * new_length, true,
buzbeecbd6d442012-11-17 14:11:25 -0800212 kAllocGrowableList));
buzbeefa57c472012-11-21 12:06:18 -0800213 memcpy(new_array, g_list->elem_list, sizeof(uintptr_t) * g_list->num_allocated);
buzbee5abfa3e2012-01-31 17:01:43 -0800214#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800215 cu->mstats->list_sizes[g_list->kind] += sizeof(uintptr_t) * new_length;
216 cu->mstats->list_wasted[g_list->kind] +=
217 sizeof(uintptr_t) * g_list->num_allocated;
218 cu->mstats->list_grows[g_list->kind]++;
219 if (new_length > cu->mstats->list_max_elems[g_list->kind]) {
220 cu->mstats->list_max_elems[g_list->kind] = new_length;
Bill Buzbeea114add2012-05-03 15:00:40 -0700221 }
buzbee5abfa3e2012-01-31 17:01:43 -0800222#endif
buzbeefa57c472012-11-21 12:06:18 -0800223 g_list->num_allocated = new_length;
224 g_list->elem_list = new_array;
buzbee67bf8852011-08-17 17:51:35 -0700225}
226
227/* Insert a new element into the growable list */
buzbeefa57c472012-11-21 12:06:18 -0800228void InsertGrowableList(CompilationUnit* cu, GrowableList* g_list,
buzbeecbd6d442012-11-17 14:11:25 -0800229 uintptr_t elem)
buzbee67bf8852011-08-17 17:51:35 -0700230{
buzbeefa57c472012-11-21 12:06:18 -0800231 DCHECK_NE(g_list->num_allocated, 0U);
232 if (g_list->num_used == g_list->num_allocated) {
233 ExpandGrowableList(cu, g_list);
Bill Buzbeea114add2012-05-03 15:00:40 -0700234 }
buzbeefa57c472012-11-21 12:06:18 -0800235 g_list->elem_list[g_list->num_used++] = elem;
buzbee67bf8852011-08-17 17:51:35 -0700236}
237
buzbee5abfa3e2012-01-31 17:01:43 -0800238/* Delete an element from a growable list. Element must be present */
buzbeefa57c472012-11-21 12:06:18 -0800239void DeleteGrowableList(GrowableList* g_list, uintptr_t elem)
buzbee5abfa3e2012-01-31 17:01:43 -0800240{
Bill Buzbeea114add2012-05-03 15:00:40 -0700241 bool found = false;
buzbeefa57c472012-11-21 12:06:18 -0800242 for (unsigned int i = 0; i < g_list->num_used; i++) {
243 if (!found && g_list->elem_list[i] == elem) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700244 found = true;
buzbee5abfa3e2012-01-31 17:01:43 -0800245 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700246 if (found) {
buzbeefa57c472012-11-21 12:06:18 -0800247 g_list->elem_list[i] = g_list->elem_list[i+1];
Bill Buzbeea114add2012-05-03 15:00:40 -0700248 }
249 }
250 DCHECK_EQ(found, true);
buzbeefa57c472012-11-21 12:06:18 -0800251 g_list->num_used--;
buzbee5abfa3e2012-01-31 17:01:43 -0800252}
253
buzbeefa57c472012-11-21 12:06:18 -0800254void GrowableListIteratorInit(GrowableList* g_list,
Bill Buzbeea114add2012-05-03 15:00:40 -0700255 GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700256{
buzbeefa57c472012-11-21 12:06:18 -0800257 iterator->list = g_list;
Bill Buzbeea114add2012-05-03 15:00:40 -0700258 iterator->idx = 0;
buzbeefa57c472012-11-21 12:06:18 -0800259 iterator->size = g_list->num_used;
buzbee67bf8852011-08-17 17:51:35 -0700260}
261
buzbee52a77fc2012-11-20 19:50:46 -0800262uintptr_t GrowableListIteratorNext(GrowableListIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700263{
buzbeefa57c472012-11-21 12:06:18 -0800264 DCHECK_EQ(iterator->size, iterator->list->num_used);
Bill Buzbeea114add2012-05-03 15:00:40 -0700265 if (iterator->idx == iterator->size) return 0;
buzbeefa57c472012-11-21 12:06:18 -0800266 return iterator->list->elem_list[iterator->idx++];
buzbee67bf8852011-08-17 17:51:35 -0700267}
268
buzbeefa57c472012-11-21 12:06:18 -0800269uintptr_t GrowableListGetElement(const GrowableList* g_list, size_t idx)
buzbee67bf8852011-08-17 17:51:35 -0700270{
buzbeefa57c472012-11-21 12:06:18 -0800271 DCHECK_LT(idx, g_list->num_used);
272 return g_list->elem_list[idx];
buzbee67bf8852011-08-17 17:51:35 -0700273}
274
buzbee5abfa3e2012-01-31 17:01:43 -0800275#ifdef WITH_MEMSTATS
276/* Dump memory usage stats */
buzbeefa57c472012-11-21 12:06:18 -0800277void DumpMemStats(CompilationUnit* cu)
buzbee5abfa3e2012-01-31 17:01:43 -0800278{
buzbeeeaf09bc2012-11-15 14:51:41 -0800279 uint32_t total = 0;
Bill Buzbeea114add2012-05-03 15:00:40 -0700280 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800281 total += cu->mstats->alloc_stats[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700282 }
283 if (total > (10 * 1024 * 1024)) {
284 LOG(INFO) << "MEMUSAGE: " << total << " : "
buzbeefa57c472012-11-21 12:06:18 -0800285 << PrettyMethod(cu->method_idx, *cu->dex_file);
buzbee311ca162013-02-28 15:56:43 -0800286 LOG(INFO) << "insns_size: " << cu->code_item->insns_size_in_code_units_;
Bill Buzbeea114add2012-05-03 15:00:40 -0700287 LOG(INFO) << "===== Overall allocations";
288 for (int i = 0; i < kNumAllocKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800289 LOG(INFO) << alloc_names[i] << std::setw(10) <<
290 cu->mstats->alloc_stats[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700291 }
292 LOG(INFO) << "===== GrowableList allocations";
293 for (int i = 0; i < kNumListKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800294 LOG(INFO) << list_names[i]
295 << " S:" << cu->mstats->list_sizes[i]
296 << ", W:" << cu->mstats->list_wasted[i]
297 << ", G:" << cu->mstats->list_grows[i]
298 << ", E:" << cu->mstats->list_max_elems[i];
Bill Buzbeea114add2012-05-03 15:00:40 -0700299 }
300 LOG(INFO) << "===== GrowableBitMap allocations";
301 for (int i = 0; i < kNumBitMapKinds; i++) {
buzbeefa57c472012-11-21 12:06:18 -0800302 LOG(INFO) << bit_map_names[i]
303 << " S:" << cu->mstats->bit_map_sizes[i]
304 << ", W:" << cu->mstats->bit_map_wasted[i]
305 << ", G:" << cu->mstats->bit_map_grows[i];
buzbee5abfa3e2012-01-31 17:01:43 -0800306 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700307 }
buzbee5abfa3e2012-01-31 17:01:43 -0800308}
309#endif
310
buzbeefa57c472012-11-21 12:06:18 -0800311static uint32_t check_masks[32] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700312 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
313 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
314 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
315 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000,
316 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000,
317 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
318 0x40000000, 0x80000000 };
buzbee67bc2362011-10-11 18:08:40 -0700319
buzbee67bf8852011-08-17 17:51:35 -0700320/*
321 * Allocate a bit vector with enough space to hold at least the specified
322 * number of bits.
323 *
324 * NOTE: memory is allocated from the compiler arena.
325 */
buzbeefa57c472012-11-21 12:06:18 -0800326ArenaBitVector* AllocBitVector(CompilationUnit* cu,
327 unsigned int start_bits, bool expandable,
328 oat_bit_map_kind kind)
buzbee67bf8852011-08-17 17:51:35 -0700329{
Bill Buzbeea114add2012-05-03 15:00:40 -0700330 ArenaBitVector* bv;
331 unsigned int count;
buzbee67bf8852011-08-17 17:51:35 -0700332
Bill Buzbeea114add2012-05-03 15:00:40 -0700333 DCHECK_EQ(sizeof(bv->storage[0]), 4U); /* assuming 32-bit units */
buzbee67bf8852011-08-17 17:51:35 -0700334
buzbeefa57c472012-11-21 12:06:18 -0800335 bv = static_cast<ArenaBitVector*>(NewMem(cu, sizeof(ArenaBitVector), false,
buzbeecbd6d442012-11-17 14:11:25 -0800336 kAllocGrowableBitMap));
buzbee67bf8852011-08-17 17:51:35 -0700337
buzbeefa57c472012-11-21 12:06:18 -0800338 count = (start_bits + 31) >> 5;
buzbee67bf8852011-08-17 17:51:35 -0700339
buzbeefa57c472012-11-21 12:06:18 -0800340 bv->storage_size = count;
Bill Buzbeea114add2012-05-03 15:00:40 -0700341 bv->expandable = expandable;
buzbeefa57c472012-11-21 12:06:18 -0800342 bv->storage = static_cast<uint32_t*>(NewMem(cu, count * sizeof(uint32_t), true,
buzbeeeaf09bc2012-11-15 14:51:41 -0800343 kAllocGrowableBitMap));
buzbee5abfa3e2012-01-31 17:01:43 -0800344#ifdef WITH_MEMSTATS
Bill Buzbeea114add2012-05-03 15:00:40 -0700345 bv->kind = kind;
buzbeefa57c472012-11-21 12:06:18 -0800346 cu->mstats->bit_map_sizes[kind] += count * sizeof(uint32_t);
buzbee5abfa3e2012-01-31 17:01:43 -0800347#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700348 return bv;
buzbee67bf8852011-08-17 17:51:35 -0700349}
350
351/*
352 * Determine whether or not the specified bit is set.
353 */
buzbeefa57c472012-11-21 12:06:18 -0800354bool IsBitSet(const ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700355{
buzbeefa57c472012-11-21 12:06:18 -0800356 DCHECK_LT(num, p_bits->storage_size * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700357
buzbeefa57c472012-11-21 12:06:18 -0800358 unsigned int val = p_bits->storage[num >> 5] & check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700359 return (val != 0);
buzbee67bf8852011-08-17 17:51:35 -0700360}
361
362/*
363 * Mark all bits bit as "clear".
364 */
buzbeefa57c472012-11-21 12:06:18 -0800365void ClearAllBits(ArenaBitVector* p_bits)
buzbee67bf8852011-08-17 17:51:35 -0700366{
buzbeefa57c472012-11-21 12:06:18 -0800367 unsigned int count = p_bits->storage_size;
368 memset(p_bits->storage, 0, count * sizeof(uint32_t));
buzbee67bf8852011-08-17 17:51:35 -0700369}
370
371/*
372 * Mark the specified bit as "set".
373 *
374 * Returns "false" if the bit is outside the range of the vector and we're
375 * not allowed to expand.
376 *
377 * NOTE: memory is allocated from the compiler arena.
378 */
buzbeefa57c472012-11-21 12:06:18 -0800379bool SetBit(CompilationUnit* cu, ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700380{
buzbeefa57c472012-11-21 12:06:18 -0800381 if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
382 if (!p_bits->expandable) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700383 LOG(FATAL) << "Can't expand";
buzbee67bf8852011-08-17 17:51:35 -0700384 }
385
Bill Buzbeea114add2012-05-03 15:00:40 -0700386 /* Round up to word boundaries for "num+1" bits */
buzbeefa57c472012-11-21 12:06:18 -0800387 unsigned int new_size = (num + 1 + 31) >> 5;
388 DCHECK_GT(new_size, p_bits->storage_size);
389 uint32_t *new_storage = static_cast<uint32_t*>(NewMem(cu, new_size * sizeof(uint32_t), false,
buzbeeeaf09bc2012-11-15 14:51:41 -0800390 kAllocGrowableBitMap));
buzbeefa57c472012-11-21 12:06:18 -0800391 memcpy(new_storage, p_bits->storage, p_bits->storage_size * sizeof(uint32_t));
392 memset(&new_storage[p_bits->storage_size], 0,
393 (new_size - p_bits->storage_size) * sizeof(uint32_t));
Bill Buzbeea114add2012-05-03 15:00:40 -0700394#ifdef WITH_MEMSTATS
buzbeefa57c472012-11-21 12:06:18 -0800395 cu->mstats->bit_map_wasted[p_bits->kind] +=
396 p_bits->storage_size * sizeof(uint32_t);
397 cu->mstats->bit_map_sizes[p_bits->kind] += new_size * sizeof(uint32_t);
398 cu->mstats->bit_map_grows[p_bits->kind]++;
Bill Buzbeea114add2012-05-03 15:00:40 -0700399#endif
buzbeefa57c472012-11-21 12:06:18 -0800400 p_bits->storage = new_storage;
401 p_bits->storage_size = new_size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700402 }
403
buzbeefa57c472012-11-21 12:06:18 -0800404 p_bits->storage[num >> 5] |= check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700405 return true;
buzbee67bf8852011-08-17 17:51:35 -0700406}
407
408/*
409 * Mark the specified bit as "unset".
410 *
411 * Returns "false" if the bit is outside the range of the vector and we're
412 * not allowed to expand.
413 *
414 * NOTE: memory is allocated from the compiler arena.
415 */
buzbeefa57c472012-11-21 12:06:18 -0800416bool ClearBit(ArenaBitVector* p_bits, unsigned int num)
buzbee67bf8852011-08-17 17:51:35 -0700417{
buzbeefa57c472012-11-21 12:06:18 -0800418 if (num >= p_bits->storage_size * sizeof(uint32_t) * 8) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700419 LOG(FATAL) << "Attempt to clear a bit not set in the vector yet";;
420 }
buzbee67bf8852011-08-17 17:51:35 -0700421
buzbeefa57c472012-11-21 12:06:18 -0800422 p_bits->storage[num >> 5] &= ~check_masks[num & 0x1f];
Bill Buzbeea114add2012-05-03 15:00:40 -0700423 return true;
buzbee67bf8852011-08-17 17:51:35 -0700424}
425
buzbee67bf8852011-08-17 17:51:35 -0700426/* Initialize the iterator structure */
buzbeefa57c472012-11-21 12:06:18 -0800427void BitVectorIteratorInit(ArenaBitVector* p_bits,
Bill Buzbeea114add2012-05-03 15:00:40 -0700428 ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700429{
buzbeefa57c472012-11-21 12:06:18 -0800430 iterator->p_bits = p_bits;
431 iterator->bit_size = p_bits->storage_size * sizeof(uint32_t) * 8;
Bill Buzbeea114add2012-05-03 15:00:40 -0700432 iterator->idx = 0;
buzbee67bf8852011-08-17 17:51:35 -0700433}
434
435/*
436 * If the vector sizes don't match, log an error and abort.
437 */
buzbee52a77fc2012-11-20 19:50:46 -0800438static void CheckSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
buzbee67bf8852011-08-17 17:51:35 -0700439{
buzbeefa57c472012-11-21 12:06:18 -0800440 if (bv1->storage_size != bv2->storage_size) {
441 LOG(FATAL) << "Mismatched vector sizes (" << bv1->storage_size
442 << ", " << bv2->storage_size << ")";
Bill Buzbeea114add2012-05-03 15:00:40 -0700443 }
buzbee67bf8852011-08-17 17:51:35 -0700444}
445
446/*
447 * Copy a whole vector to the other. Only do that when the both vectors have
448 * the same size.
449 */
buzbee52a77fc2012-11-20 19:50:46 -0800450void CopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src)
buzbee67bf8852011-08-17 17:51:35 -0700451{
Bill Buzbeea114add2012-05-03 15:00:40 -0700452 /* if dest is expandable and < src, we could expand dest to match */
buzbee52a77fc2012-11-20 19:50:46 -0800453 CheckSizes(dest, src);
buzbee67bf8852011-08-17 17:51:35 -0700454
buzbeefa57c472012-11-21 12:06:18 -0800455 memcpy(dest->storage, src->storage, sizeof(uint32_t) * dest->storage_size);
buzbee67bf8852011-08-17 17:51:35 -0700456}
457
458/*
459 * Intersect two bit vectors and store the result to the dest vector.
460 */
461
buzbee52a77fc2012-11-20 19:50:46 -0800462bool IntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700463 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700464{
Bill Buzbeea114add2012-05-03 15:00:40 -0700465 DCHECK(src1 != NULL);
466 DCHECK(src2 != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800467 if (dest->storage_size != src1->storage_size ||
468 dest->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700469 dest->expandable != src1->expandable ||
470 dest->expandable != src2->expandable)
471 return false;
buzbee67bf8852011-08-17 17:51:35 -0700472
Bill Buzbeea114add2012-05-03 15:00:40 -0700473 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800474 for (idx = 0; idx < dest->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700475 dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
476 }
477 return true;
buzbee67bf8852011-08-17 17:51:35 -0700478}
479
480/*
481 * Unify two bit vectors and store the result to the dest vector.
482 */
buzbee52a77fc2012-11-20 19:50:46 -0800483bool UnifyBitVetors(ArenaBitVector* dest, const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700484 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700485{
Bill Buzbeea114add2012-05-03 15:00:40 -0700486 DCHECK(src1 != NULL);
487 DCHECK(src2 != NULL);
buzbeefa57c472012-11-21 12:06:18 -0800488 if (dest->storage_size != src1->storage_size ||
489 dest->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700490 dest->expandable != src1->expandable ||
491 dest->expandable != src2->expandable)
492 return false;
buzbee67bf8852011-08-17 17:51:35 -0700493
Bill Buzbeea114add2012-05-03 15:00:40 -0700494 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800495 for (idx = 0; idx < dest->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700496 dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
497 }
498 return true;
buzbee67bf8852011-08-17 17:51:35 -0700499}
500
501/*
buzbeee1965672012-03-11 18:39:19 -0700502 * Return true if any bits collide. Vectors must be same size.
503 */
buzbee52a77fc2012-11-20 19:50:46 -0800504bool TestBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700505 const ArenaBitVector* src2)
buzbeee1965672012-03-11 18:39:19 -0700506{
buzbeefa57c472012-11-21 12:06:18 -0800507 DCHECK_EQ(src1->storage_size, src2->storage_size);
508 for (uint32_t idx = 0; idx < src1->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700509 if (src1->storage[idx] & src2->storage[idx]) return true;
510 }
511 return false;
buzbeee1965672012-03-11 18:39:19 -0700512}
513
514/*
buzbee67bf8852011-08-17 17:51:35 -0700515 * Compare two bit vectors and return true if difference is seen.
516 */
buzbee52a77fc2012-11-20 19:50:46 -0800517bool CompareBitVectors(const ArenaBitVector* src1,
Bill Buzbeea114add2012-05-03 15:00:40 -0700518 const ArenaBitVector* src2)
buzbee67bf8852011-08-17 17:51:35 -0700519{
buzbeefa57c472012-11-21 12:06:18 -0800520 if (src1->storage_size != src2->storage_size ||
Bill Buzbeea114add2012-05-03 15:00:40 -0700521 src1->expandable != src2->expandable)
522 return true;
buzbee67bf8852011-08-17 17:51:35 -0700523
Bill Buzbeea114add2012-05-03 15:00:40 -0700524 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800525 for (idx = 0; idx < src1->storage_size; idx++) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700526 if (src1->storage[idx] != src2->storage[idx]) return true;
527 }
528 return false;
buzbee67bf8852011-08-17 17:51:35 -0700529}
530
531/*
532 * Count the number of bits that are set.
533 */
buzbeefa57c472012-11-21 12:06:18 -0800534int CountSetBits(const ArenaBitVector* p_bits)
buzbee67bf8852011-08-17 17:51:35 -0700535{
Bill Buzbeea114add2012-05-03 15:00:40 -0700536 unsigned int word;
537 unsigned int count = 0;
buzbee67bf8852011-08-17 17:51:35 -0700538
buzbeefa57c472012-11-21 12:06:18 -0800539 for (word = 0; word < p_bits->storage_size; word++) {
540 uint32_t val = p_bits->storage[word];
buzbee67bf8852011-08-17 17:51:35 -0700541
Bill Buzbeea114add2012-05-03 15:00:40 -0700542 if (val != 0) {
543 if (val == 0xffffffff) {
544 count += 32;
545 } else {
546 /* count the number of '1' bits */
547 while (val != 0) {
548 val &= val - 1;
549 count++;
buzbee67bf8852011-08-17 17:51:35 -0700550 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700551 }
buzbee67bf8852011-08-17 17:51:35 -0700552 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700553 }
buzbee67bf8852011-08-17 17:51:35 -0700554
Bill Buzbeea114add2012-05-03 15:00:40 -0700555 return count;
buzbee67bf8852011-08-17 17:51:35 -0700556}
557
558/* Return the next position set to 1. -1 means end-of-element reached */
buzbee52a77fc2012-11-20 19:50:46 -0800559int BitVectorIteratorNext(ArenaBitVectorIterator* iterator)
buzbee67bf8852011-08-17 17:51:35 -0700560{
buzbeefa57c472012-11-21 12:06:18 -0800561 ArenaBitVector* p_bits = iterator->p_bits;
562 uint32_t bit_index = iterator->idx;
563 uint32_t bit_size = iterator->bit_size;
buzbee67bf8852011-08-17 17:51:35 -0700564
buzbeefa57c472012-11-21 12:06:18 -0800565 DCHECK_EQ(bit_size, p_bits->storage_size * sizeof(uint32_t) * 8);
buzbee67bf8852011-08-17 17:51:35 -0700566
buzbeefa57c472012-11-21 12:06:18 -0800567 if (bit_index >= bit_size) return -1;
buzbee5b537102012-01-17 17:33:47 -0800568
buzbeefa57c472012-11-21 12:06:18 -0800569 uint32_t word_index = bit_index >> 5;
570 uint32_t end_word_index = bit_size >> 5;
571 uint32_t* storage = p_bits->storage;
572 uint32_t word = storage[word_index++];
buzbee5b537102012-01-17 17:33:47 -0800573
Bill Buzbeea114add2012-05-03 15:00:40 -0700574 // Mask out any bits in the first word we've already considered
buzbeefa57c472012-11-21 12:06:18 -0800575 word &= ~((1 << (bit_index & 0x1f))-1);
buzbee5abfa3e2012-01-31 17:01:43 -0800576
buzbeefa57c472012-11-21 12:06:18 -0800577 for (; word_index <= end_word_index;) {
578 uint32_t bit_pos = bit_index & 0x1f;
Bill Buzbeea114add2012-05-03 15:00:40 -0700579 if (word == 0) {
buzbeefa57c472012-11-21 12:06:18 -0800580 bit_index += (32 - bit_pos);
581 word = storage[word_index++];
Bill Buzbeea114add2012-05-03 15:00:40 -0700582 continue;
buzbee67bf8852011-08-17 17:51:35 -0700583 }
buzbeefa57c472012-11-21 12:06:18 -0800584 for (; bit_pos < 32; bit_pos++) {
585 if (word & (1 << bit_pos)) {
586 iterator->idx = bit_index + 1;
587 return bit_index;
Bill Buzbeea114add2012-05-03 15:00:40 -0700588 }
buzbeefa57c472012-11-21 12:06:18 -0800589 bit_index++;
Bill Buzbeea114add2012-05-03 15:00:40 -0700590 }
buzbeefa57c472012-11-21 12:06:18 -0800591 word = storage[word_index++];
Bill Buzbeea114add2012-05-03 15:00:40 -0700592 }
buzbeefa57c472012-11-21 12:06:18 -0800593 iterator->idx = iterator->bit_size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700594 return -1;
buzbee67bf8852011-08-17 17:51:35 -0700595}
596
597/*
598 * Mark specified number of bits as "set". Cannot set all bits like ClearAll
599 * since there might be unused bits - setting those to one will confuse the
600 * iterator.
601 */
buzbeefa57c472012-11-21 12:06:18 -0800602void SetInitialBits(ArenaBitVector* p_bits, unsigned int num_bits)
buzbee67bf8852011-08-17 17:51:35 -0700603{
Bill Buzbeea114add2012-05-03 15:00:40 -0700604 unsigned int idx;
buzbeefa57c472012-11-21 12:06:18 -0800605 DCHECK_LE(((num_bits + 31) >> 5), p_bits->storage_size);
606 for (idx = 0; idx < (num_bits >> 5); idx++) {
607 p_bits->storage[idx] = -1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700608 }
buzbeefa57c472012-11-21 12:06:18 -0800609 unsigned int rem_num_bits = num_bits & 0x1f;
610 if (rem_num_bits) {
611 p_bits->storage[idx] = (1 << rem_num_bits) - 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700612 }
buzbee67bf8852011-08-17 17:51:35 -0700613}
614
buzbee02031b12012-11-23 09:41:35 -0800615/* Allocate a new basic block */
616BasicBlock* NewMemBB(CompilationUnit* cu, BBType block_type, int block_id)
617{
618 BasicBlock* bb = static_cast<BasicBlock*>(NewMem(cu, sizeof(BasicBlock), true, kAllocBB));
619 bb->block_type = block_type;
620 bb->id = block_id;
621 bb->predecessors = static_cast<GrowableList*>
622 (NewMem(cu, sizeof(GrowableList), false, kAllocPredecessors));
623 CompilerInitGrowableList(cu, bb->predecessors,
624 (block_type == kExitBlock) ? 2048 : 2,
625 kListPredecessors);
buzbee1fd33462013-03-25 13:40:45 -0700626 cu->mir_graph->block_id_map_.Put(block_id, block_id);
buzbee02031b12012-11-23 09:41:35 -0800627 return bb;
628}
629
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800630} // namespace art