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