248
249
250 OopMap* OopMapSet::find_map_at_offset(int pc_offset) const {
251 int i, len = om_count();
252 assert( len > 0, "must have pointer maps" );
253
254 // Scan through oopmaps. Stop when current offset is either equal or greater
255 // than the one we are looking for.
256 for( i = 0; i < len; i++) {
257 if( at(i)->offset() >= pc_offset )
258 break;
259 }
260
261 assert( i < len, "oopmap not found" );
262
263 OopMap* m = at(i);
264 assert( m->offset() == pc_offset, "oopmap not found" );
265 return m;
266 }
267
268 static void add_derived_oop(oop* base, oop* derived) {
269 #if !defined(TIERED) && !INCLUDE_JVMCI
270 COMPILER1_PRESENT(ShouldNotReachHere();)
271 #endif // !defined(TIERED) && !INCLUDE_JVMCI
272 #if COMPILER2_OR_JVMCI
273 DerivedPointerTable::add(derived, base);
274 #endif // COMPILER2_OR_JVMCI
275 }
276
277
278 #ifndef PRODUCT
279 static void trace_codeblob_maps(const frame *fr, const RegisterMap *reg_map) {
280 // Print oopmap and regmap
281 tty->print_cr("------ ");
282 CodeBlob* cb = fr->cb();
283 const ImmutableOopMapSet* maps = cb->oop_maps();
284 const ImmutableOopMap* map = cb->oop_map_for_return_address(fr->pc());
285 map->print();
286 if( cb->is_nmethod() ) {
287 nmethod* nm = (nmethod*)cb;
288 // native wrappers have no scope data, it is implied
289 if (nm->is_native_method()) {
290 tty->print("bci: 0 (native)");
291 } else {
292 ScopeDesc* scope = nm->scope_desc_at(fr->pc());
293 tty->print("bci: %d ",scope->bci());
294 }
295 }
296 tty->cr();
297 fr->print_on(tty);
298 tty->print(" ");
299 cb->print_value_on(tty); tty->cr();
300 reg_map->print();
301 tty->print_cr("------ ");
302
303 }
304 #endif // PRODUCT
305
306 void OopMapSet::oops_do(const frame *fr, const RegisterMap* reg_map, OopClosure* f) {
307 // add derived oops to a table
308 all_do(fr, reg_map, f, add_derived_oop, &do_nothing_cl);
309 }
310
311
312 void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
313 OopClosure* oop_fn, void derived_oop_fn(oop*, oop*),
314 OopClosure* value_fn) {
315 CodeBlob* cb = fr->cb();
316 assert(cb != NULL, "no codeblob");
317
318 NOT_PRODUCT(if (TraceCodeBlobStacks) trace_codeblob_maps(fr, reg_map);)
319
320 const ImmutableOopMapSet* maps = cb->oop_maps();
321 const ImmutableOopMap* map = cb->oop_map_for_return_address(fr->pc());
322 assert(map != NULL, "no ptr map found");
323
324 // handle derived pointers first (otherwise base pointer may be
325 // changed before derived pointer offset has been collected)
326 OopMapValue omv;
327 {
328 OopMapStream oms(map,OopMapValue::derived_oop_value);
329 if (!oms.is_done()) {
330 #ifndef TIERED
331 COMPILER1_PRESENT(ShouldNotReachHere();)
332 #if INCLUDE_JVMCI
333 if (UseJVMCICompiler) {
334 ShouldNotReachHere();
335 }
336 #endif
337 #endif // !TIERED
338 // Protect the operation on the derived pointers. This
339 // protects the addition of derived pointers to the shared
340 // derived pointer table in DerivedPointerTable::add().
341 MutexLockerEx x(DerivedPointerTableGC_lock, Mutex::_no_safepoint_check_flag);
342 do {
343 omv = oms.current();
344 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
345 guarantee(loc != NULL, "missing saved register");
346 oop *derived_loc = loc;
347 oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
348 // Ignore NULL oops and decoded NULL narrow oops which
349 // equal to Universe::narrow_oop_base when a narrow oop
350 // implicit null check is used in compiled code.
351 // The narrow_oop_base could be NULL or be the address
352 // of the page below heap depending on compressed oops mode.
353 if (base_loc != NULL && *base_loc != (oop)NULL && !Universe::is_narrow_oop_base(*base_loc)) {
354 derived_oop_fn(base_loc, derived_loc);
355 }
356 oms.next();
357 } while (!oms.is_done());
358 }
359 }
360
361 // We want coop and oop oop_types
362 int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value;
363 {
364 for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
365 omv = oms.current();
366 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
367 // It should be an error if no location can be found for a
368 // register mentioned as contained an oop of some kind. Maybe
369 // this was allowed previously because value_value items might
370 // be missing?
371 guarantee(loc != NULL, "missing saved register");
372 if ( omv.type() == OopMapValue::oop_value ) {
373 oop val = *loc;
374 if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
375 // Ignore NULL oops and decoded NULL narrow oops which
376 // equal to Universe::narrow_oop_base when a narrow oop
377 // implicit null check is used in compiled code.
378 // The narrow_oop_base could be NULL or be the address
379 // of the page below heap depending on compressed oops mode.
380 continue;
381 }
382 #ifdef ASSERT
383 if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
384 !Universe::heap()->is_in_or_null(*loc)) {
385 tty->print_cr("# Found non oop pointer. Dumping state at failure");
386 // try to dump out some helpful debugging information
387 trace_codeblob_maps(fr, reg_map);
388 omv.print();
389 tty->print_cr("register r");
390 omv.reg()->print();
391 tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
392 // do the real assert.
393 assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
394 }
395 #endif // ASSERT
396 oop_fn->do_oop(loc);
397 } else if ( omv.type() == OopMapValue::narrowoop_value ) {
398 narrowOop *nl = (narrowOop*)loc;
399 #ifndef VM_LITTLE_ENDIAN
400 VMReg vmReg = omv.reg();
401 // Don't do this on SPARC float registers as they can be individually addressed
402 if (!vmReg->is_stack() SPARC_ONLY(&& !vmReg->is_FloatRegister())) {
403 // compressed oops in registers only take up 4 bytes of an
404 // 8 byte register but they are in the wrong part of the
405 // word so adjust loc to point at the right place.
406 nl = (narrowOop*)((address)nl + 4);
407 }
408 #endif
409 oop_fn->do_oop(nl);
410 }
411 }
412 }
413 }
414
415
416 // Update callee-saved register info for the following frame
417 void OopMapSet::update_register_map(const frame *fr, RegisterMap *reg_map) {
418 ResourceMark rm;
419 CodeBlob* cb = fr->cb();
420 assert(cb != NULL, "no codeblob");
421
422 // Any reg might be saved by a safepoint handler (see generate_handler_blob).
423 assert( reg_map->_update_for_id == NULL || fr->is_older(reg_map->_update_for_id),
424 "already updated this map; do not 'update' it twice!" );
425 debug_only(reg_map->_update_for_id = fr->id());
426
427 // Check if caller must update oop argument
428 assert((reg_map->include_argument_oops() ||
429 !cb->caller_must_gc_arguments(reg_map->thread())),
430 "include_argument_oops should already be set");
431
432 // Scan through oopmap and find location of all callee-saved registers
|
248
249
250 OopMap* OopMapSet::find_map_at_offset(int pc_offset) const {
251 int i, len = om_count();
252 assert( len > 0, "must have pointer maps" );
253
254 // Scan through oopmaps. Stop when current offset is either equal or greater
255 // than the one we are looking for.
256 for( i = 0; i < len; i++) {
257 if( at(i)->offset() >= pc_offset )
258 break;
259 }
260
261 assert( i < len, "oopmap not found" );
262
263 OopMap* m = at(i);
264 assert( m->offset() == pc_offset, "oopmap not found" );
265 return m;
266 }
267
268 class AddDerivedOop : public DerivedOopClosure {
269 virtual void do_derived_oop(oop* base, oop* derived) {
270 #if !defined(TIERED) && !INCLUDE_JVMCI
271 COMPILER1_PRESENT(ShouldNotReachHere();)
272 #endif // !defined(TIERED) && !INCLUDE_JVMCI
273 #if COMPILER2_OR_JVMCI
274 DerivedPointerTable::add(derived, base);
275 #endif // COMPILER2_OR_JVMCI
276 }
277 } add_derived_oop;
278
279
280 #ifndef PRODUCT
281 static void trace_codeblob_maps(const frame *fr, const RegisterMap *reg_map) {
282 // Print oopmap and regmap
283 tty->print_cr("------ ");
284 CodeBlob* cb = fr->cb();
285 const ImmutableOopMapSet* maps = cb->oop_maps();
286 const ImmutableOopMap* map = cb->oop_map_for_return_address(fr->pc());
287 map->print();
288 if( cb->is_nmethod() ) {
289 nmethod* nm = (nmethod*)cb;
290 // native wrappers have no scope data, it is implied
291 if (nm->is_native_method()) {
292 tty->print("bci: 0 (native)");
293 } else {
294 ScopeDesc* scope = nm->scope_desc_at(fr->pc());
295 tty->print("bci: %d ",scope->bci());
296 }
297 }
298 tty->cr();
299 fr->print_on(tty);
300 tty->print(" ");
301 cb->print_value_on(tty); tty->cr();
302 reg_map->print();
303 tty->print_cr("------ ");
304
305 }
306 #endif // PRODUCT
307
308 void OopMapSet::oops_do(const frame *fr, const RegisterMap* reg_map, OopClosure* f, DerivedOopClosure* df) {
309 // add_derived_oop: add derived oops to a table
310 all_do(fr, reg_map, f, df != NULL ? df : &add_derived_oop, &do_nothing_cl);
311 }
312
313 static void walk_derived_pointers1(OopMapStream& oms, const frame *fr, const RegisterMap *reg_map, DerivedOopClosure* derived_oop_fn) {
314 OopMapValue omv;
315 do {
316 omv = oms.current();
317 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
318 guarantee(loc != NULL, "missing saved register");
319 oop *derived_loc = loc;
320 oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
321 // Ignore NULL oops and decoded NULL narrow oops which
322 // equal to Universe::narrow_oop_base when a narrow oop
323 // implicit null check is used in compiled code.
324 // The narrow_oop_base could be NULL or be the address
325 // of the page below heap depending on compressed oops mode.
326 if (base_loc != NULL && *base_loc != (oop)NULL && !Universe::is_narrow_oop_base(*base_loc)) {
327 derived_oop_fn->do_derived_oop(base_loc, derived_loc);
328 }
329 oms.next();
330 } while (!oms.is_done());
331 }
332
333 static void walk_derived_pointers(const frame *fr, const ImmutableOopMap* map, const RegisterMap *reg_map,
334 DerivedOopClosure* derived_oop_fn) {
335 OopMapStream oms(map,OopMapValue::derived_oop_value);
336 if (!oms.is_done()) {
337 #ifndef TIERED
338 COMPILER1_PRESENT(ShouldNotReachHere();)
339 #if INCLUDE_JVMCI
340 if (UseJVMCICompiler) {
341 ShouldNotReachHere();
342 }
343 #endif
344 #endif // !TIERED
345
346 if (derived_oop_fn == &add_derived_oop) { // TODO: UGLY
347 // Protect the operation on the derived pointers. This
348 // protects the addition of derived pointers to the shared
349 // derived pointer table in DerivedPointerTable::add().
350 MutexLockerEx x(DerivedPointerTableGC_lock, Mutex::_no_safepoint_check_flag);
351 walk_derived_pointers1(oms, fr, reg_map, derived_oop_fn);
352 } else {
353 walk_derived_pointers1(oms, fr, reg_map, derived_oop_fn);
354 }
355 }
356 }
357
358 void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
359 OopClosure* oop_fn, DerivedOopClosure* derived_oop_fn,
360 OopClosure* value_fn) {
361 CodeBlob* cb = fr->cb();
362 assert(cb != NULL, "no codeblob");
363
364 NOT_PRODUCT(if (TraceCodeBlobStacks) trace_codeblob_maps(fr, reg_map);)
365
366 const ImmutableOopMapSet* maps = cb->oop_maps();
367 const ImmutableOopMap* map = cb->oop_map_for_return_address(fr->pc());
368 assert(map != NULL, "no ptr map found");
369
370 // handle derived pointers first (otherwise base pointer may be
371 // changed before derived pointer offset has been collected)
372 if (reg_map->validate_oops())
373 walk_derived_pointers(fr, map, reg_map, derived_oop_fn);
374
375 OopMapValue omv;
376 // We want coop and oop oop_types
377 int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value;
378 {
379 for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
380 omv = oms.current();
381 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
382 // It should be an error if no location can be found for a
383 // register mentioned as contained an oop of some kind. Maybe
384 // this was allowed previously because value_value items might
385 // be missing?
386 #ifdef ASSERT
387 if (loc == NULL) {
388 VMReg reg = omv.reg();
389 tty->print_cr("missing saved register: reg: %ld %s loc: %p", reg->value(), reg->name(), loc);
390 fr->print_on(tty);
391 }
392 #endif
393 guarantee(loc != NULL, "missing saved register");
394 if ( omv.type() == OopMapValue::oop_value ) {
395 oop val = *loc;
396 if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
397 // Ignore NULL oops and decoded NULL narrow oops which
398 // equal to Universe::narrow_oop_base when a narrow oop
399 // implicit null check is used in compiled code.
400 // The narrow_oop_base could be NULL or be the address
401 // of the page below heap depending on compressed oops mode.
402 continue;
403 }
404 #ifdef ASSERT
405 if (reg_map->validate_oops() &&
406 ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
407 !Universe::heap()->is_in_or_null(*loc))) {
408 tty->print_cr("# Found non oop pointer. Dumping state at failure");
409 // try to dump out some helpful debugging information
410 trace_codeblob_maps(fr, reg_map);
411 omv.print();
412 tty->print_cr("register r");
413 omv.reg()->print();
414 tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
415 // os::print_location(tty, (intptr_t)*loc);
416 tty->print("pc: "); os::print_location(tty, (intptr_t)fr->pc());
417 fr->print_value_on(tty, NULL);
418 // do the real assert.
419 assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
420 }
421 #endif // ASSERT
422 oop_fn->do_oop(loc);
423 } else if ( omv.type() == OopMapValue::narrowoop_value ) {
424 narrowOop *nl = (narrowOop*)loc;
425 #ifndef VM_LITTLE_ENDIAN
426 VMReg vmReg = omv.reg();
427 // Don't do this on SPARC float registers as they can be individually addressed
428 if (!vmReg->is_stack() SPARC_ONLY(&& !vmReg->is_FloatRegister())) {
429 // compressed oops in registers only take up 4 bytes of an
430 // 8 byte register but they are in the wrong part of the
431 // word so adjust loc to point at the right place.
432 nl = (narrowOop*)((address)nl + 4);
433 }
434 #endif
435 oop_fn->do_oop(nl);
436 }
437 }
438 }
439
440 // When thawing continuation frames, we want to walk derived pointers
441 // after walking oops
442 if (!reg_map->validate_oops())
443 walk_derived_pointers(fr, map, reg_map, derived_oop_fn);
444 }
445
446
447 // Update callee-saved register info for the following frame
448 void OopMapSet::update_register_map(const frame *fr, RegisterMap *reg_map) {
449 ResourceMark rm;
450 CodeBlob* cb = fr->cb();
451 assert(cb != NULL, "no codeblob");
452
453 // Any reg might be saved by a safepoint handler (see generate_handler_blob).
454 assert( reg_map->_update_for_id == NULL || fr->is_older(reg_map->_update_for_id),
455 "already updated this map; do not 'update' it twice!" );
456 debug_only(reg_map->_update_for_id = fr->id());
457
458 // Check if caller must update oop argument
459 assert((reg_map->include_argument_oops() ||
460 !cb->caller_must_gc_arguments(reg_map->thread())),
461 "include_argument_oops should already be set");
462
463 // Scan through oopmap and find location of all callee-saved registers
|