229 tty->print_cr("}");
230 }
231
232 class MaskFillerForNative: public NativeSignatureIterator {
233 private:
234 uintptr_t * _mask; // the bit mask to be filled
235 int _size; // the mask size in bits
236
237 void set_one(int i) {
238 i *= InterpreterOopMap::bits_per_entry;
239 assert(0 <= i && i < _size, "offset out of bounds");
240 _mask[i / BitsPerWord] |= (((uintptr_t) 1 << InterpreterOopMap::oop_bit_number) << (i % BitsPerWord));
241 }
242
243 public:
244 void pass_int() { /* ignore */ }
245 void pass_long() { /* ignore */ }
246 void pass_float() { /* ignore */ }
247 void pass_double() { /* ignore */ }
248 void pass_object() { set_one(offset()); }
249
250 MaskFillerForNative(const methodHandle& method, uintptr_t* mask, int size) : NativeSignatureIterator(method) {
251 _mask = mask;
252 _size = size;
253 // initialize with 0
254 int i = (size + BitsPerWord - 1) / BitsPerWord;
255 while (i-- > 0) _mask[i] = 0;
256 }
257
258 void generate() {
259 NativeSignatureIterator::iterate();
260 }
261 };
262
263 bool OopMapCacheEntry::verify_mask(CellTypeState* vars, CellTypeState* stack, int max_locals, int stack_top) {
264 // Check mask includes map
265 VerifyClosure blk(this);
266 iterate_oop(&blk);
267 if (blk.failed()) return false;
268
269 // Check if map is generated correctly
270 // (Use ?: operator to make sure all 'true' & 'false' are represented exactly the same so we can use == afterwards)
271 Log(interpreter, oopmap) logv;
272 LogStream st(logv.trace());
273
274 st.print("Locals (%d): ", max_locals);
275 for(int i = 0; i < max_locals; i++) {
276 bool v1 = is_oop(i) ? true : false;
277 bool v2 = vars[i].is_reference() ? true : false;
278 assert(v1 == v2, "locals oop mask generation error");
279 st.print("%d", v1 ? 1 : 0);
280 }
281 st.cr();
282
283 st.print("Stack (%d): ", stack_top);
284 for(int j = 0; j < stack_top; j++) {
285 bool v1 = is_oop(max_locals + j) ? true : false;
286 bool v2 = stack[j].is_reference() ? true : false;
287 assert(v1 == v2, "stack oop mask generation error");
288 st.print("%d", v1 ? 1 : 0);
289 }
290 st.cr();
291 return true;
292 }
293
294 void OopMapCacheEntry::allocate_bit_mask() {
295 if (mask_size() > small_mask_limit) {
296 assert(_bit_mask[0] == 0, "bit mask should be new or just flushed");
297 _bit_mask[0] = (intptr_t)
298 NEW_C_HEAP_ARRAY(uintptr_t, mask_word_size(), mtClass);
299 }
300 }
301
302 void OopMapCacheEntry::deallocate_bit_mask() {
303 if (mask_size() > small_mask_limit && _bit_mask[0] != 0) {
304 assert(!Thread::current()->resource_area()->contains((void*)_bit_mask[0]),
305 "This bit mask should not be in the resource area");
306 FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0]);
348 // compute bits
349 int word_index = 0;
350 uintptr_t value = 0;
351 uintptr_t mask = 1;
352
353 CellTypeState* cell = vars;
354 for (int entry_index = 0; entry_index < n_entries; entry_index++, mask <<= bits_per_entry, cell++) {
355 // store last word
356 if (mask == 0) {
357 bit_mask()[word_index++] = value;
358 value = 0;
359 mask = 1;
360 }
361
362 // switch to stack when done with locals
363 if (entry_index == max_locals) {
364 cell = stack;
365 }
366
367 // set oop bit
368 if ( cell->is_reference()) {
369 value |= (mask << oop_bit_number );
370 }
371
372 // set dead bit
373 if (!cell->is_live()) {
374 value |= (mask << dead_bit_number);
375 assert(!cell->is_reference(), "dead value marked as oop");
376 }
377 }
378
379 // make sure last word is stored
380 bit_mask()[word_index] = value;
381
382 // verify bit mask
383 assert(verify_mask(vars, stack, max_locals, stack_top), "mask could not be verified");
384 }
385
386 void OopMapCacheEntry::flush() {
387 deallocate_bit_mask();
388 initialize();
|
229 tty->print_cr("}");
230 }
231
232 class MaskFillerForNative: public NativeSignatureIterator {
233 private:
234 uintptr_t * _mask; // the bit mask to be filled
235 int _size; // the mask size in bits
236
237 void set_one(int i) {
238 i *= InterpreterOopMap::bits_per_entry;
239 assert(0 <= i && i < _size, "offset out of bounds");
240 _mask[i / BitsPerWord] |= (((uintptr_t) 1 << InterpreterOopMap::oop_bit_number) << (i % BitsPerWord));
241 }
242
243 public:
244 void pass_int() { /* ignore */ }
245 void pass_long() { /* ignore */ }
246 void pass_float() { /* ignore */ }
247 void pass_double() { /* ignore */ }
248 void pass_object() { set_one(offset()); }
249 void pass_valuetype() { set_one(offset()); }
250
251 MaskFillerForNative(const methodHandle& method, uintptr_t* mask, int size) : NativeSignatureIterator(method) {
252 _mask = mask;
253 _size = size;
254 // initialize with 0
255 int i = (size + BitsPerWord - 1) / BitsPerWord;
256 while (i-- > 0) _mask[i] = 0;
257 }
258
259 void generate() {
260 NativeSignatureIterator::iterate();
261 }
262 };
263
264 bool OopMapCacheEntry::verify_mask(CellTypeState* vars, CellTypeState* stack, int max_locals, int stack_top) {
265 // Check mask includes map
266 VerifyClosure blk(this);
267 iterate_oop(&blk);
268 if (blk.failed()) return false;
269
270 // Check if map is generated correctly
271 // (Use ?: operator to make sure all 'true' & 'false' are represented exactly the same so we can use == afterwards)
272 Log(interpreter, oopmap) logv;
273 LogStream st(logv.trace());
274
275 st.print("Locals (%d): ", max_locals);
276 for(int i = 0; i < max_locals; i++) {
277 bool v1 = is_oop(i) ? true : false;
278 bool v2 = vars[i].is_reference();
279 assert(v1 == v2, "locals oop mask generation error");
280 st.print("%d", v1 ? 1 : 0);
281 }
282 st.cr();
283
284 st.print("Stack (%d): ", stack_top);
285 for(int j = 0; j < stack_top; j++) {
286 bool v1 = is_oop(max_locals + j) ? true : false;
287 bool v2 = stack[j].is_reference();
288 assert(v1 == v2, "stack oop mask generation error");
289 st.print("%d", v1 ? 1 : 0);
290 }
291 st.cr();
292 return true;
293 }
294
295 void OopMapCacheEntry::allocate_bit_mask() {
296 if (mask_size() > small_mask_limit) {
297 assert(_bit_mask[0] == 0, "bit mask should be new or just flushed");
298 _bit_mask[0] = (intptr_t)
299 NEW_C_HEAP_ARRAY(uintptr_t, mask_word_size(), mtClass);
300 }
301 }
302
303 void OopMapCacheEntry::deallocate_bit_mask() {
304 if (mask_size() > small_mask_limit && _bit_mask[0] != 0) {
305 assert(!Thread::current()->resource_area()->contains((void*)_bit_mask[0]),
306 "This bit mask should not be in the resource area");
307 FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0]);
349 // compute bits
350 int word_index = 0;
351 uintptr_t value = 0;
352 uintptr_t mask = 1;
353
354 CellTypeState* cell = vars;
355 for (int entry_index = 0; entry_index < n_entries; entry_index++, mask <<= bits_per_entry, cell++) {
356 // store last word
357 if (mask == 0) {
358 bit_mask()[word_index++] = value;
359 value = 0;
360 mask = 1;
361 }
362
363 // switch to stack when done with locals
364 if (entry_index == max_locals) {
365 cell = stack;
366 }
367
368 // set oop bit
369 if (cell->is_reference()) {
370 value |= (mask << oop_bit_number );
371 }
372
373 // set dead bit
374 if (!cell->is_live()) {
375 value |= (mask << dead_bit_number);
376 assert(!cell->is_reference(), "dead value marked as oop");
377 }
378 }
379
380 // make sure last word is stored
381 bit_mask()[word_index] = value;
382
383 // verify bit mask
384 assert(verify_mask(vars, stack, max_locals, stack_top), "mask could not be verified");
385 }
386
387 void OopMapCacheEntry::flush() {
388 deallocate_bit_mask();
389 initialize();
|