< prev index next >
src/hotspot/share/compiler/oopMap.cpp
Print this page
rev 50307 : [mq]: cont
*** 263,280 ****
OopMap* m = at(i);
assert( m->offset() == pc_offset, "oopmap not found" );
return m;
}
! static void add_derived_oop(oop* base, oop* derived) {
#if !defined(TIERED) && !INCLUDE_JVMCI
COMPILER1_PRESENT(ShouldNotReachHere();)
#endif // !defined(TIERED) && !INCLUDE_JVMCI
#if COMPILER2_OR_JVMCI
DerivedPointerTable::add(derived, base);
#endif // COMPILER2_OR_JVMCI
! }
#ifndef PRODUCT
static void trace_codeblob_maps(const frame *fr, const RegisterMap *reg_map) {
// Print oopmap and regmap
--- 263,282 ----
OopMap* m = at(i);
assert( m->offset() == pc_offset, "oopmap not found" );
return m;
}
! class AddDerivedOop : public DerivedOopClosure {
! virtual void do_derived_oop(oop* base, oop* derived) {
#if !defined(TIERED) && !INCLUDE_JVMCI
COMPILER1_PRESENT(ShouldNotReachHere();)
#endif // !defined(TIERED) && !INCLUDE_JVMCI
#if COMPILER2_OR_JVMCI
DerivedPointerTable::add(derived, base);
#endif // COMPILER2_OR_JVMCI
! }
! } add_derived_oop;
#ifndef PRODUCT
static void trace_codeblob_maps(const frame *fr, const RegisterMap *reg_map) {
// Print oopmap and regmap
*** 301,346 ****
tty->print_cr("------ ");
}
#endif // PRODUCT
! void OopMapSet::oops_do(const frame *fr, const RegisterMap* reg_map, OopClosure* f) {
! // add derived oops to a table
! all_do(fr, reg_map, f, add_derived_oop, &do_nothing_cl);
}
!
! void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
! OopClosure* oop_fn, void derived_oop_fn(oop*, oop*),
! OopClosure* value_fn) {
! CodeBlob* cb = fr->cb();
! assert(cb != NULL, "no codeblob");
!
! NOT_PRODUCT(if (TraceCodeBlobStacks) trace_codeblob_maps(fr, reg_map);)
!
! const ImmutableOopMapSet* maps = cb->oop_maps();
! const ImmutableOopMap* map = cb->oop_map_for_return_address(fr->pc());
! assert(map != NULL, "no ptr map found");
!
! // handle derived pointers first (otherwise base pointer may be
! // changed before derived pointer offset has been collected)
OopMapValue omv;
- {
- OopMapStream oms(map,OopMapValue::derived_oop_value);
- if (!oms.is_done()) {
- #ifndef TIERED
- COMPILER1_PRESENT(ShouldNotReachHere();)
- #if INCLUDE_JVMCI
- if (UseJVMCICompiler) {
- ShouldNotReachHere();
- }
- #endif
- #endif // !TIERED
- // Protect the operation on the derived pointers. This
- // protects the addition of derived pointers to the shared
- // derived pointer table in DerivedPointerTable::add().
- MutexLockerEx x(DerivedPointerTableGC_lock, Mutex::_no_safepoint_check_flag);
do {
omv = oms.current();
oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
guarantee(loc != NULL, "missing saved register");
oop *derived_loc = loc;
--- 303,319 ----
tty->print_cr("------ ");
}
#endif // PRODUCT
! void OopMapSet::oops_do(const frame *fr, const RegisterMap* reg_map, OopClosure* f, DerivedOopClosure* df) {
! // add_derived_oop: add derived oops to a table
! all_do(fr, reg_map, f, df != NULL ? df : &add_derived_oop, &do_nothing_cl);
}
! static void walk_derived_pointers1(OopMapStream& oms, const frame *fr, const RegisterMap *reg_map, DerivedOopClosure* derived_oop_fn) {
OopMapValue omv;
do {
omv = oms.current();
oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
guarantee(loc != NULL, "missing saved register");
oop *derived_loc = loc;
*** 349,375 ****
// equal to Universe::narrow_oop_base when a narrow oop
// implicit null check is used in compiled code.
// The narrow_oop_base could be NULL or be the address
// of the page below heap depending on compressed oops mode.
if (base_loc != NULL && *base_loc != (oop)NULL && !Universe::is_narrow_oop_base(*base_loc)) {
! derived_oop_fn(base_loc, derived_loc);
}
oms.next();
} while (!oms.is_done());
}
}
// We want coop and oop oop_types
int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value;
{
for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
omv = oms.current();
oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
// It should be an error if no location can be found for a
// register mentioned as contained an oop of some kind. Maybe
// this was allowed previously because value_value items might
// be missing?
guarantee(loc != NULL, "missing saved register");
if ( omv.type() == OopMapValue::oop_value ) {
oop val = *loc;
if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
// Ignore NULL oops and decoded NULL narrow oops which
--- 322,397 ----
// equal to Universe::narrow_oop_base when a narrow oop
// implicit null check is used in compiled code.
// The narrow_oop_base could be NULL or be the address
// of the page below heap depending on compressed oops mode.
if (base_loc != NULL && *base_loc != (oop)NULL && !Universe::is_narrow_oop_base(*base_loc)) {
! derived_oop_fn->do_derived_oop(base_loc, derived_loc);
}
oms.next();
} while (!oms.is_done());
+ }
+
+ static void walk_derived_pointers(const frame *fr, const ImmutableOopMap* map, const RegisterMap *reg_map,
+ DerivedOopClosure* derived_oop_fn) {
+ OopMapStream oms(map,OopMapValue::derived_oop_value);
+ if (!oms.is_done()) {
+ #ifndef TIERED
+ COMPILER1_PRESENT(ShouldNotReachHere();)
+ #if INCLUDE_JVMCI
+ if (UseJVMCICompiler) {
+ ShouldNotReachHere();
+ }
+ #endif
+ #endif // !TIERED
+
+ if (derived_oop_fn == &add_derived_oop) { // TODO: UGLY
+ // Protect the operation on the derived pointers. This
+ // protects the addition of derived pointers to the shared
+ // derived pointer table in DerivedPointerTable::add().
+ MutexLockerEx x(DerivedPointerTableGC_lock, Mutex::_no_safepoint_check_flag);
+ walk_derived_pointers1(oms, fr, reg_map, derived_oop_fn);
+ } else {
+ walk_derived_pointers1(oms, fr, reg_map, derived_oop_fn);
}
}
+ }
+ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
+ OopClosure* oop_fn, DerivedOopClosure* derived_oop_fn,
+ OopClosure* value_fn) {
+ CodeBlob* cb = fr->cb();
+ assert(cb != NULL, "no codeblob");
+
+ NOT_PRODUCT(if (TraceCodeBlobStacks) trace_codeblob_maps(fr, reg_map);)
+
+ const ImmutableOopMapSet* maps = cb->oop_maps();
+ const ImmutableOopMap* map = cb->oop_map_for_return_address(fr->pc());
+ assert(map != NULL, "no ptr map found");
+
+ // handle derived pointers first (otherwise base pointer may be
+ // changed before derived pointer offset has been collected)
+ if (reg_map->validate_oops())
+ walk_derived_pointers(fr, map, reg_map, derived_oop_fn);
+
+ OopMapValue omv;
// We want coop and oop oop_types
int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value;
{
for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
omv = oms.current();
oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
// It should be an error if no location can be found for a
// register mentioned as contained an oop of some kind. Maybe
// this was allowed previously because value_value items might
// be missing?
+ #ifdef ASSERT
+ if (loc == NULL) {
+ VMReg reg = omv.reg();
+ tty->print_cr("missing saved register: reg: %ld %s loc: %p", reg->value(), reg->name(), loc);
+ fr->print_on(tty);
+ }
+ #endif
guarantee(loc != NULL, "missing saved register");
if ( omv.type() == OopMapValue::oop_value ) {
oop val = *loc;
if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) {
// Ignore NULL oops and decoded NULL narrow oops which
*** 378,396 ****
// The narrow_oop_base could be NULL or be the address
// of the page below heap depending on compressed oops mode.
continue;
}
#ifdef ASSERT
! if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
! !Universe::heap()->is_in_or_null(*loc)) {
tty->print_cr("# Found non oop pointer. Dumping state at failure");
// try to dump out some helpful debugging information
trace_codeblob_maps(fr, reg_map);
omv.print();
tty->print_cr("register r");
omv.reg()->print();
tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
// do the real assert.
assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
}
#endif // ASSERT
oop_fn->do_oop(loc);
--- 400,422 ----
// The narrow_oop_base could be NULL or be the address
// of the page below heap depending on compressed oops mode.
continue;
}
#ifdef ASSERT
! if (reg_map->validate_oops() &&
! ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
! !Universe::heap()->is_in_or_null(*loc))) {
tty->print_cr("# Found non oop pointer. Dumping state at failure");
// try to dump out some helpful debugging information
trace_codeblob_maps(fr, reg_map);
omv.print();
tty->print_cr("register r");
omv.reg()->print();
tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
+ // os::print_location(tty, (intptr_t)*loc);
+ tty->print("pc: "); os::print_location(tty, (intptr_t)fr->pc());
+ fr->print_value_on(tty, NULL);
// do the real assert.
assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
}
#endif // ASSERT
oop_fn->do_oop(loc);
*** 408,417 ****
--- 434,448 ----
#endif
oop_fn->do_oop(nl);
}
}
}
+
+ // When thawing continuation frames, we want to walk derived pointers
+ // after walking oops
+ if (!reg_map->validate_oops())
+ walk_derived_pointers(fr, map, reg_map, derived_oop_fn);
}
// Update callee-saved register info for the following frame
void OopMapSet::update_register_map(const frame *fr, RegisterMap *reg_map) {
< prev index next >