240 iterate();
241 }
242
243 int num_oops() { return _num_oops; }
244 };
245
246 bool OopMapCacheEntry::verify_mask(CellTypeState* vars, CellTypeState* stack, int max_locals, int stack_top) {
247 // Check mask includes map
248 VerifyClosure blk(this);
249 iterate_oop(&blk);
250 if (blk.failed()) return false;
251
252 // Check if map is generated correctly
253 // (Use ?: operator to make sure all 'true' & 'false' are represented exactly the same so we can use == afterwards)
254 const bool log = log_is_enabled(Trace, interpreter, oopmap);
255 LogStream st(Log(interpreter, oopmap)::trace());
256
257 if (log) st.print("Locals (%d): ", max_locals);
258 for(int i = 0; i < max_locals; i++) {
259 bool v1 = is_oop(i) ? true : false;
260 bool v2 = vars[i].is_reference() ? true : false;
261 assert(v1 == v2, "locals oop mask generation error");
262 if (log) st.print("%d", v1 ? 1 : 0);
263 }
264 if (log) st.cr();
265
266 if (log) st.print("Stack (%d): ", stack_top);
267 for(int j = 0; j < stack_top; j++) {
268 bool v1 = is_oop(max_locals + j) ? true : false;
269 bool v2 = stack[j].is_reference() ? true : false;
270 assert(v1 == v2, "stack oop mask generation error");
271 if (log) st.print("%d", v1 ? 1 : 0);
272 }
273 if (log) st.cr();
274 return true;
275 }
276
277 void OopMapCacheEntry::allocate_bit_mask() {
278 if (mask_size() > small_mask_limit) {
279 assert(_bit_mask[0] == 0, "bit mask should be new or just flushed");
280 _bit_mask[0] = (intptr_t)
281 NEW_C_HEAP_ARRAY(uintptr_t, mask_word_size(), mtClass);
282 }
283 }
284
285 void OopMapCacheEntry::deallocate_bit_mask() {
286 if (mask_size() > small_mask_limit && _bit_mask[0] != 0) {
287 assert(!Thread::current()->resource_area()->contains((void*)_bit_mask[0]),
288 "This bit mask should not be in the resource area");
289 FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0]);
333 int word_index = 0;
334 uintptr_t value = 0;
335 uintptr_t mask = 1;
336
337 _num_oops = 0;
338 CellTypeState* cell = vars;
339 for (int entry_index = 0; entry_index < n_entries; entry_index++, mask <<= bits_per_entry, cell++) {
340 // store last word
341 if (mask == 0) {
342 bit_mask()[word_index++] = value;
343 value = 0;
344 mask = 1;
345 }
346
347 // switch to stack when done with locals
348 if (entry_index == max_locals) {
349 cell = stack;
350 }
351
352 // set oop bit
353 if ( cell->is_reference()) {
354 value |= (mask << oop_bit_number );
355 _num_oops++;
356 }
357
358 // set dead bit
359 if (!cell->is_live()) {
360 value |= (mask << dead_bit_number);
361 assert(!cell->is_reference(), "dead value marked as oop");
362 }
363 }
364
365 // make sure last word is stored
366 bit_mask()[word_index] = value;
367
368 // verify bit mask
369 assert(verify_mask(vars, stack, max_locals, stack_top), "mask could not be verified");
370 }
371
372 void OopMapCacheEntry::flush() {
373 deallocate_bit_mask();
|
240 iterate();
241 }
242
243 int num_oops() { return _num_oops; }
244 };
245
246 bool OopMapCacheEntry::verify_mask(CellTypeState* vars, CellTypeState* stack, int max_locals, int stack_top) {
247 // Check mask includes map
248 VerifyClosure blk(this);
249 iterate_oop(&blk);
250 if (blk.failed()) return false;
251
252 // Check if map is generated correctly
253 // (Use ?: operator to make sure all 'true' & 'false' are represented exactly the same so we can use == afterwards)
254 const bool log = log_is_enabled(Trace, interpreter, oopmap);
255 LogStream st(Log(interpreter, oopmap)::trace());
256
257 if (log) st.print("Locals (%d): ", max_locals);
258 for(int i = 0; i < max_locals; i++) {
259 bool v1 = is_oop(i) ? true : false;
260 bool v2 = vars[i].is_reference();
261 assert(v1 == v2, "locals oop mask generation error");
262 if (log) st.print("%d", v1 ? 1 : 0);
263 }
264 if (log) st.cr();
265
266 if (log) st.print("Stack (%d): ", stack_top);
267 for(int j = 0; j < stack_top; j++) {
268 bool v1 = is_oop(max_locals + j) ? true : false;
269 bool v2 = stack[j].is_reference();
270 assert(v1 == v2, "stack oop mask generation error");
271 if (log) st.print("%d", v1 ? 1 : 0);
272 }
273 if (log) st.cr();
274 return true;
275 }
276
277 void OopMapCacheEntry::allocate_bit_mask() {
278 if (mask_size() > small_mask_limit) {
279 assert(_bit_mask[0] == 0, "bit mask should be new or just flushed");
280 _bit_mask[0] = (intptr_t)
281 NEW_C_HEAP_ARRAY(uintptr_t, mask_word_size(), mtClass);
282 }
283 }
284
285 void OopMapCacheEntry::deallocate_bit_mask() {
286 if (mask_size() > small_mask_limit && _bit_mask[0] != 0) {
287 assert(!Thread::current()->resource_area()->contains((void*)_bit_mask[0]),
288 "This bit mask should not be in the resource area");
289 FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0]);
333 int word_index = 0;
334 uintptr_t value = 0;
335 uintptr_t mask = 1;
336
337 _num_oops = 0;
338 CellTypeState* cell = vars;
339 for (int entry_index = 0; entry_index < n_entries; entry_index++, mask <<= bits_per_entry, cell++) {
340 // store last word
341 if (mask == 0) {
342 bit_mask()[word_index++] = value;
343 value = 0;
344 mask = 1;
345 }
346
347 // switch to stack when done with locals
348 if (entry_index == max_locals) {
349 cell = stack;
350 }
351
352 // set oop bit
353 if (cell->is_reference()) {
354 value |= (mask << oop_bit_number );
355 _num_oops++;
356 }
357
358 // set dead bit
359 if (!cell->is_live()) {
360 value |= (mask << dead_bit_number);
361 assert(!cell->is_reference(), "dead value marked as oop");
362 }
363 }
364
365 // make sure last word is stored
366 bit_mask()[word_index] = value;
367
368 // verify bit mask
369 assert(verify_mask(vars, stack, max_locals, stack_top), "mask could not be verified");
370 }
371
372 void OopMapCacheEntry::flush() {
373 deallocate_bit_mask();
|