362 363 // handle derived pointers first (otherwise base pointer may be 364 // changed before derived pointer offset has been collected) 365 OopMapValue omv; 366 { 367 OopMapStream oms(map,OopMapValue::derived_oop_value); 368 if (!oms.is_done()) { 369 #ifndef TIERED 370 COMPILER1_PRESENT(ShouldNotReachHere();) 371 #endif // !TIERED 372 // Protect the operation on the derived pointers. This 373 // protects the addition of derived pointers to the shared 374 // derived pointer table in DerivedPointerTable::add(). 375 MutexLockerEx x(DerivedPointerTableGC_lock, Mutex::_no_safepoint_check_flag); 376 do { 377 omv = oms.current(); 378 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map); 379 if ( loc != NULL ) { 380 oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map); 381 oop *derived_loc = loc; 382 derived_oop_fn(base_loc, derived_loc); 383 } 384 oms.next(); 385 } while (!oms.is_done()); 386 } 387 } 388 389 // We want coop, value and oop oop_types 390 int mask = OopMapValue::oop_value | OopMapValue::value_value | OopMapValue::narrowoop_value; 391 { 392 for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) { 393 omv = oms.current(); 394 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map); 395 if ( loc != NULL ) { 396 if ( omv.type() == OopMapValue::oop_value ) { 397 #ifdef ASSERT 398 if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) || 399 !Universe::heap()->is_in_or_null(*loc)) { 400 tty->print_cr("# Found non oop pointer. Dumping state at failure"); 401 // try to dump out some helpful debugging information 402 trace_codeblob_maps(fr, reg_map); 403 omv.print(); 404 tty->print_cr("register r"); 405 omv.reg()->print(); 406 tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc); 407 // do the real assert. 408 assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer"); 409 } 410 #endif // ASSERT 411 oop_fn->do_oop(loc); 412 } else if ( omv.type() == OopMapValue::value_value ) { 413 value_fn->do_oop(loc); 414 } else if ( omv.type() == OopMapValue::narrowoop_value ) { 415 narrowOop *nl = (narrowOop*)loc; 416 #ifndef VM_LITTLE_ENDIAN 417 if (!omv.reg()->is_stack()) { 418 // compressed oops in registers only take up 4 bytes of an 419 // 8 byte register but they are in the wrong part of the 420 // word so adjust loc to point at the right place. 421 nl = (narrowOop*)((address)nl + 4); 422 } 423 #endif 424 oop_fn->do_oop(nl); 425 } 426 } 427 } 428 } 429 } 430 431 432 // Update callee-saved register info for the following frame | 362 363 // handle derived pointers first (otherwise base pointer may be 364 // changed before derived pointer offset has been collected) 365 OopMapValue omv; 366 { 367 OopMapStream oms(map,OopMapValue::derived_oop_value); 368 if (!oms.is_done()) { 369 #ifndef TIERED 370 COMPILER1_PRESENT(ShouldNotReachHere();) 371 #endif // !TIERED 372 // Protect the operation on the derived pointers. This 373 // protects the addition of derived pointers to the shared 374 // derived pointer table in DerivedPointerTable::add(). 375 MutexLockerEx x(DerivedPointerTableGC_lock, Mutex::_no_safepoint_check_flag); 376 do { 377 omv = oms.current(); 378 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map); 379 if ( loc != NULL ) { 380 oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map); 381 oop *derived_loc = loc; 382 #ifdef _LP64 383 if (Universe::narrow_oop_base() == (address)(void*)(*base_loc)) { 384 // Compiled code may produce decoded oop = narrow_oop_base 385 // when a narrow oop implicit null check is used. 386 // The narrow_oop_base could be NULL or be the address 387 // of the page below heap. Skip both cases since nobody 388 // is interesting in NULL. 389 } else 390 #endif 391 derived_oop_fn(base_loc, derived_loc); 392 } 393 oms.next(); 394 } while (!oms.is_done()); 395 } 396 } 397 398 // We want coop, value and oop oop_types 399 int mask = OopMapValue::oop_value | OopMapValue::value_value | OopMapValue::narrowoop_value; 400 { 401 for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) { 402 omv = oms.current(); 403 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map); 404 if ( loc != NULL ) { 405 if ( omv.type() == OopMapValue::oop_value ) { 406 #ifdef _LP64 407 if (Universe::narrow_oop_base() == (address)(void*)(*loc)) { 408 // Compiled code may produce decoded oop = narrow_oop_base 409 // when a narrow oop implicit null check is used. 410 // The narrow_oop_base could be NULL or be the address 411 // of the page below heap. Skip both cases since nobody 412 // is interesting in NULL. 413 continue; 414 } 415 #endif 416 #ifdef ASSERT 417 if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) || 418 !Universe::heap()->is_in_or_null(*loc)) { 419 tty->print_cr("# Found non oop pointer. Dumping state at failure"); 420 // try to dump out some helpful debugging information 421 trace_codeblob_maps(fr, reg_map); 422 omv.print(); 423 tty->print_cr("register r"); 424 omv.reg()->print(); 425 tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc); 426 // do the real assert. 427 assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer"); 428 } 429 #endif // ASSERT 430 oop_fn->do_oop(loc); 431 } else if ( omv.type() == OopMapValue::value_value ) { 432 assert((*loc) == (oop)NULL || Universe::narrow_oop_base() != (address)(void*)(*loc), 433 "found non valid value pointer"); 434 value_fn->do_oop(loc); 435 } else if ( omv.type() == OopMapValue::narrowoop_value ) { 436 narrowOop *nl = (narrowOop*)loc; 437 #ifndef VM_LITTLE_ENDIAN 438 if (!omv.reg()->is_stack()) { 439 // compressed oops in registers only take up 4 bytes of an 440 // 8 byte register but they are in the wrong part of the 441 // word so adjust loc to point at the right place. 442 nl = (narrowOop*)((address)nl + 4); 443 } 444 #endif 445 oop_fn->do_oop(nl); 446 } 447 } 448 } 449 } 450 } 451 452 453 // Update callee-saved register info for the following frame |