< 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 >