< prev index next >
src/hotspot/share/compiler/oopMap.cpp
Print this page
rev 50307 : [mq]: cont
@@ -263,18 +263,20 @@
OopMap* m = at(i);
assert( m->offset() == pc_offset, "oopmap not found" );
return m;
}
-static void add_derived_oop(oop* base, oop* derived) {
+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,46 +303,17 @@
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::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);
}
-
-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)
+static void walk_derived_pointers1(OopMapStream& oms, const frame *fr, const RegisterMap *reg_map, DerivedOopClosure* derived_oop_fn) {
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;
@@ -349,27 +322,76 @@
// 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);
+ 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,19 +400,23 @@
// 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)) {
+ 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,10 +434,15 @@
#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 >