265
266 void generate() {
267 iterate();
268 }
269 };
270
271 bool OopMapCacheEntry::verify_mask(CellTypeState* vars, CellTypeState* stack, int max_locals, int stack_top) {
272 // Check mask includes map
273 VerifyClosure blk(this);
274 iterate_oop(&blk);
275 if (blk.failed()) return false;
276
277 // Check if map is generated correctly
278 // (Use ?: operator to make sure all 'true' & 'false' are represented exactly the same so we can use == afterwards)
279 const bool log = log_is_enabled(Trace, interpreter, oopmap);
280 LogStream st(Log(interpreter, oopmap)::trace());
281
282 if (log) st.print("Locals (%d): ", max_locals);
283 for(int i = 0; i < max_locals; i++) {
284 bool v1 = is_oop(i) ? true : false;
285 bool v2 = vars[i].is_reference() ? true : false;
286 assert(v1 == v2, "locals oop mask generation error");
287 if (log) st.print("%d", v1 ? 1 : 0);
288 }
289 if (log) st.cr();
290
291 if (log) st.print("Stack (%d): ", stack_top);
292 for(int j = 0; j < stack_top; j++) {
293 bool v1 = is_oop(max_locals + j) ? true : false;
294 bool v2 = stack[j].is_reference() ? true : false;
295 assert(v1 == v2, "stack oop mask generation error");
296 if (log) st.print("%d", v1 ? 1 : 0);
297 }
298 if (log) st.cr();
299 return true;
300 }
301
302 void OopMapCacheEntry::allocate_bit_mask() {
303 if (mask_size() > small_mask_limit) {
304 assert(_bit_mask[0] == 0, "bit mask should be new or just flushed");
305 _bit_mask[0] = (intptr_t)
306 NEW_C_HEAP_ARRAY(uintptr_t, mask_word_size(), mtClass);
307 }
308 }
309
310 void OopMapCacheEntry::deallocate_bit_mask() {
311 if (mask_size() > small_mask_limit && _bit_mask[0] != 0) {
312 assert(!Thread::current()->resource_area()->contains((void*)_bit_mask[0]),
313 "This bit mask should not be in the resource area");
314 FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0]);
356 // compute bits
357 int word_index = 0;
358 uintptr_t value = 0;
359 uintptr_t mask = 1;
360
361 CellTypeState* cell = vars;
362 for (int entry_index = 0; entry_index < n_entries; entry_index++, mask <<= bits_per_entry, cell++) {
363 // store last word
364 if (mask == 0) {
365 bit_mask()[word_index++] = value;
366 value = 0;
367 mask = 1;
368 }
369
370 // switch to stack when done with locals
371 if (entry_index == max_locals) {
372 cell = stack;
373 }
374
375 // set oop bit
376 if ( cell->is_reference()) {
377 value |= (mask << oop_bit_number );
378 }
379
380 // set dead bit
381 if (!cell->is_live()) {
382 value |= (mask << dead_bit_number);
383 assert(!cell->is_reference(), "dead value marked as oop");
384 }
385 }
386
387 // make sure last word is stored
388 bit_mask()[word_index] = value;
389
390 // verify bit mask
391 assert(verify_mask(vars, stack, max_locals, stack_top), "mask could not be verified");
392 }
393
394 void OopMapCacheEntry::flush() {
395 deallocate_bit_mask();
396 initialize();
|
265
266 void generate() {
267 iterate();
268 }
269 };
270
271 bool OopMapCacheEntry::verify_mask(CellTypeState* vars, CellTypeState* stack, int max_locals, int stack_top) {
272 // Check mask includes map
273 VerifyClosure blk(this);
274 iterate_oop(&blk);
275 if (blk.failed()) return false;
276
277 // Check if map is generated correctly
278 // (Use ?: operator to make sure all 'true' & 'false' are represented exactly the same so we can use == afterwards)
279 const bool log = log_is_enabled(Trace, interpreter, oopmap);
280 LogStream st(Log(interpreter, oopmap)::trace());
281
282 if (log) st.print("Locals (%d): ", max_locals);
283 for(int i = 0; i < max_locals; i++) {
284 bool v1 = is_oop(i) ? true : false;
285 bool v2 = vars[i].is_reference();
286 assert(v1 == v2, "locals oop mask generation error");
287 if (log) st.print("%d", v1 ? 1 : 0);
288 }
289 if (log) st.cr();
290
291 if (log) st.print("Stack (%d): ", stack_top);
292 for(int j = 0; j < stack_top; j++) {
293 bool v1 = is_oop(max_locals + j) ? true : false;
294 bool v2 = stack[j].is_reference();
295 assert(v1 == v2, "stack oop mask generation error");
296 if (log) st.print("%d", v1 ? 1 : 0);
297 }
298 if (log) st.cr();
299 return true;
300 }
301
302 void OopMapCacheEntry::allocate_bit_mask() {
303 if (mask_size() > small_mask_limit) {
304 assert(_bit_mask[0] == 0, "bit mask should be new or just flushed");
305 _bit_mask[0] = (intptr_t)
306 NEW_C_HEAP_ARRAY(uintptr_t, mask_word_size(), mtClass);
307 }
308 }
309
310 void OopMapCacheEntry::deallocate_bit_mask() {
311 if (mask_size() > small_mask_limit && _bit_mask[0] != 0) {
312 assert(!Thread::current()->resource_area()->contains((void*)_bit_mask[0]),
313 "This bit mask should not be in the resource area");
314 FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0]);
356 // compute bits
357 int word_index = 0;
358 uintptr_t value = 0;
359 uintptr_t mask = 1;
360
361 CellTypeState* cell = vars;
362 for (int entry_index = 0; entry_index < n_entries; entry_index++, mask <<= bits_per_entry, cell++) {
363 // store last word
364 if (mask == 0) {
365 bit_mask()[word_index++] = value;
366 value = 0;
367 mask = 1;
368 }
369
370 // switch to stack when done with locals
371 if (entry_index == max_locals) {
372 cell = stack;
373 }
374
375 // set oop bit
376 if (cell->is_reference()) {
377 value |= (mask << oop_bit_number );
378 }
379
380 // set dead bit
381 if (!cell->is_live()) {
382 value |= (mask << dead_bit_number);
383 assert(!cell->is_reference(), "dead value marked as oop");
384 }
385 }
386
387 // make sure last word is stored
388 bit_mask()[word_index] = value;
389
390 // verify bit mask
391 assert(verify_mask(vars, stack, max_locals, stack_top), "mask could not be verified");
392 }
393
394 void OopMapCacheEntry::flush() {
395 deallocate_bit_mask();
396 initialize();
|