changeset 21147:2b03d4ce9bce

merge
author Michael Haupt <michael.haupt@oracle.com>
date Wed, 29 Apr 2015 10:29:00 +0200
parents 33ff6b03fad1 (current diff) 4c3cc6a12df2 (diff)
children a0b348543802
files
diffstat 8 files changed, 141 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/LoadJavaMirrorWithKlassTest.java	Wed Apr 29 08:31:28 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/LoadJavaMirrorWithKlassTest.java	Wed Apr 29 10:29:00 2015 +0200
@@ -64,8 +64,8 @@
     @Override
     protected boolean checkLowTierGraph(StructuredGraph graph) {
         for (ConstantNode constantNode : graph.getNodes().filter(ConstantNode.class)) {
-            assert constantNode.asJavaConstant() == null || constantNode.asJavaConstant().getKind() != Kind.Object : "Found unexpected object constant " + constantNode +
-                            ", this should have been removed by the LoadJavaMirrorWithKlassPhase.";
+            assert constantNode.asJavaConstant() == null || constantNode.asJavaConstant().getKind() != Kind.Object || constantNode.asJavaConstant().isDefaultForKind() : "Found unexpected object constant " +
+                            constantNode + ", this should have been removed by the LoadJavaMirrorWithKlassPhase.";
         }
         return true;
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Wed Apr 29 08:31:28 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Wed Apr 29 10:29:00 2015 +0200
@@ -427,7 +427,7 @@
     }
 
     public static BytecodePosition processSimpleInfopoint(Invoke invoke, SimpleInfopointNode infopointNode, BytecodePosition incomingPos) {
-        BytecodePosition pos = incomingPos != null ? incomingPos : new BytecodePosition(toBytecodePosition(invoke.stateAfter()).getCaller(), invoke.asNode().graph().method(), invoke.bci());
+        BytecodePosition pos = incomingPos != null ? incomingPos : new BytecodePosition(toBytecodePosition(invoke.stateAfter().outerFrameState()), invoke.asNode().graph().method(), invoke.bci());
         infopointNode.addCaller(pos);
         return pos;
     }
--- a/src/share/vm/code/nmethod.cpp	Wed Apr 29 08:31:28 2015 +0200
+++ b/src/share/vm/code/nmethod.cpp	Wed Apr 29 10:29:00 2015 +0200
@@ -1463,16 +1463,6 @@
     _method = NULL;            // Clear the method of this dead nmethod
   }
 
-#ifdef GRAAL
-  // The method can only be unloaded after the pointer to the installed code
-  // Java wrapper is no longer alive. Here we need to clear out this weak
-  // reference to the dead object.
-  if (_graal_installed_code != NULL) {
-    InstalledCode::set_address(_graal_installed_code, 0);
-    _graal_installed_code = NULL;
-  }
-#endif
-
   // Make the class unloaded - i.e., change state and notify sweeper
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   if (is_in_use()) {
@@ -1485,6 +1475,18 @@
   // Unregister must be done before the state change
   Universe::heap()->unregister_nmethod(this);
 
+#ifdef GRAAL
+  // The method can only be unloaded after the pointer to the installed code
+  // Java wrapper is no longer alive. Here we need to clear out this weak
+  // reference to the dead object. Nulling out the reference has to happen
+  // after the method is unregistered since the original value may be still
+  // tracked by the rset.
+  if (_graal_installed_code != NULL) {
+    InstalledCode::set_address(_graal_installed_code, 0);
+    _graal_installed_code = NULL;
+  }
+#endif
+
   _state = unloaded;
 
   // Log the unloading.
@@ -1916,27 +1918,6 @@
     unloading_occurred = true;
   }
 
-#ifdef GRAAL
-  // Follow Graal method
-  if (_graal_installed_code != NULL) {
-    if (_graal_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_graal_installed_code)) {
-      if (!is_alive->do_object_b(_graal_installed_code)) {
-        _graal_installed_code = NULL;
-      }
-    } else {
-      if (can_unload(is_alive, (oop*)&_graal_installed_code, unloading_occurred)) {
-        return;
-      }
-    }
-  }
-
-  if (_speculation_log != NULL) {
-    if (!is_alive->do_object_b(_speculation_log)) {
-      _speculation_log = NULL;
-    }
-  }
-#endif
-
   // Exception cache
   clean_exception_cache(is_alive);
 
@@ -1983,6 +1964,33 @@
     }
   }
 
+#ifdef GRAAL
+  // Follow Graal method
+  BarrierSet* bs = Universe::heap()->barrier_set();
+  if (_graal_installed_code != NULL) {
+    if (_graal_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_graal_installed_code)) {
+      if (!is_alive->do_object_b(_graal_installed_code)) {
+        bs->write_ref_nmethod_pre(&_graal_installed_code, this);
+        _graal_installed_code = NULL;
+        bs->write_ref_nmethod_post(&_graal_installed_code, this);
+      }
+    } else {
+      if (can_unload(is_alive, (oop*)&_graal_installed_code, unloading_occurred)) {
+        return;
+      }
+    }
+  }
+
+  if (_speculation_log != NULL) {
+    if (!is_alive->do_object_b(_speculation_log)) {
+      bs->write_ref_nmethod_pre(&_speculation_log, this);
+      _speculation_log = NULL;
+      bs->write_ref_nmethod_post(&_speculation_log, this);
+    }
+  }
+#endif
+
+
   // Ensure that all metadata is still alive
   verify_metadata_loaders(low_boundary, is_alive);
 }
@@ -2182,6 +2190,32 @@
     return postponed;
   }
 
+#ifdef GRAAL
+  // Follow Graal method
+  BarrierSet* bs = Universe::heap()->barrier_set();
+  if (_graal_installed_code != NULL) {
+    if (_graal_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_graal_installed_code)) {
+      if (!is_alive->do_object_b(_graal_installed_code)) {
+        bs->write_ref_nmethod_pre(&_graal_installed_code, this);
+        _graal_installed_code = NULL;
+        bs->write_ref_nmethod_post(&_graal_installed_code, this);
+      }
+    } else {
+      if (can_unload(is_alive, (oop*)&_graal_installed_code, unloading_occurred)) {
+        is_unloaded = true;
+      }
+    }
+  }
+
+  if (_speculation_log != NULL) {
+    if (!is_alive->do_object_b(_speculation_log)) {
+      bs->write_ref_nmethod_pre(&_speculation_log, this);
+      _speculation_log = NULL;
+      bs->write_ref_nmethod_post(&_speculation_log, this);
+    }
+  }
+#endif
+
   // Ensure that all metadata is still alive
   verify_metadata_loaders(low_boundary, is_alive);
 
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Apr 29 08:31:28 2015 +0200
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Apr 29 10:29:00 2015 +0200
@@ -4830,11 +4830,14 @@
   bool during_im = _g1h->g1_policy()->during_initial_mark_pause();
   bool trace_metadata = during_im && ClassUnloadingWithConcurrentMark;
 
+  // Without eager nmethod unloading, we need to treat all oops in code cache as strong during the initial mark
+  bool trace_codecache = during_im && !ClassUnloadingWithConcurrentMark;
+
   BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots);
   BufferingOopClosure buf_scan_non_heap_weak_roots(scan_non_heap_weak_roots);
 
   process_roots(false, // no scoping; this is parallel code
-                SharedHeap::SO_None,
+                trace_codecache ? SharedHeap::SO_AllCodeCache : SharedHeap::SO_None,
                 &buf_scan_non_heap_roots,
                 &buf_scan_non_heap_weak_roots,
                 scan_strong_clds,
--- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Wed Apr 29 08:31:28 2015 +0200
+++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Wed Apr 29 10:29:00 2015 +0200
@@ -255,3 +255,60 @@
     }
   }
 }
+
+void G1SATBCardTableModRefBS::write_ref_nmethod_pre(oop* dst, nmethod* nm) {
+  oop obj = oopDesc::load_heap_oop(dst);
+  if (obj != NULL) {
+    G1CollectedHeap* g1h = (G1CollectedHeap*)Universe::heap();
+    HeapRegion* hr = g1h->heap_region_containing(obj);
+    assert(!hr->continuesHumongous(),
+           err_msg("trying to add code root "INTPTR_FORMAT" in continuation of humongous region "HR_FORMAT
+                   " starting at "HR_FORMAT,
+                   (intptr_t)nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+    hr->add_strong_code_root(nm);
+  }
+}
+
+class G1EnsureLastRefToRegion : public OopClosure {
+  G1CollectedHeap* _g1h;
+  HeapRegion* _hr;
+  oop* _dst;
+
+  bool _value;
+public:
+  G1EnsureLastRefToRegion(G1CollectedHeap* g1h, HeapRegion* hr, oop* dst) :
+    _g1h(g1h), _hr(hr), _dst(dst), _value(true) {}
+
+  void do_oop(oop* p) {
+    if (_value && p != _dst) {
+      oop obj = oopDesc::load_heap_oop(p);
+      if (obj != NULL) {
+        HeapRegion* hr = _g1h->heap_region_containing(obj);
+        if (hr == _hr) {
+          // Another reference to the same region.
+          _value = false;
+        }
+      }
+    }
+  }
+  void do_oop(narrowOop* p) { ShouldNotReachHere(); }
+  bool value() const        { return _value;  }
+};
+
+void G1SATBCardTableModRefBS::write_ref_nmethod_post(oop* dst, nmethod* nm) {
+  oop obj = oopDesc::load_heap_oop(dst);
+  if (obj != NULL) {
+    G1CollectedHeap* g1h = (G1CollectedHeap*)Universe::heap();
+    HeapRegion* hr = g1h->heap_region_containing(obj);
+    assert(!hr->continuesHumongous(),
+           err_msg("trying to remove code root "INTPTR_FORMAT" in continuation of humongous region "HR_FORMAT
+                   " starting at "HR_FORMAT,
+                   (intptr_t)nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+    G1EnsureLastRefToRegion ensure_last_ref(g1h, hr, dst);
+    nm->oops_do(&ensure_last_ref);
+    if (ensure_last_ref.value()) {
+      // Last reference to this region, remove the nmethod from the rset.
+      hr->remove_strong_code_root(nm);
+    }
+  }
+}
--- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp	Wed Apr 29 08:31:28 2015 +0200
+++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp	Wed Apr 29 10:29:00 2015 +0200
@@ -126,6 +126,9 @@
     jbyte val = _byte_map[card_index];
     return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
   }
+  void write_ref_nmethod_pre(oop* dst, nmethod* nm);
+  void write_ref_nmethod_post(oop* dst, nmethod* nm);
+
 };
 
 class G1SATBCardTableLoggingModRefBSChangedListener : public G1MappingChangedListener {
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Wed Apr 29 08:31:28 2015 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed Apr 29 10:29:00 2015 +0200
@@ -509,7 +509,12 @@
         HotSpotInstalledCode::set_codeSize(installed_code_handle, cb->code_size());
       }
       nmethod* nm = cb->as_nmethod_or_null();
-      assert(nm == NULL || !installed_code_handle->is_scavengable() || nm->on_scavenge_root_list(), "nm should be scavengable if installed_code is scavengable");
+      if (nm != NULL && installed_code_handle->is_scavengable()) {
+        assert(nm->detect_scavenge_root_oops(), "nm should be scavengable if installed_code is scavengable");
+        if (!UseG1GC) {
+          assert(nm->on_scavenge_root_list(), "nm should be on scavengable list");
+        }
+      }
     }
   }
   return result;
--- a/src/share/vm/memory/barrierSet.hpp	Wed Apr 29 08:31:28 2015 +0200
+++ b/src/share/vm/memory/barrierSet.hpp	Wed Apr 29 10:29:00 2015 +0200
@@ -145,6 +145,9 @@
   static void static_write_ref_array_pre(HeapWord* start, size_t count);
   static void static_write_ref_array_post(HeapWord* start, size_t count);
 
+  virtual void write_ref_nmethod_pre(oop* dst, nmethod* nm) {}
+  virtual void write_ref_nmethod_post(oop* dst, nmethod* nm) {}
+
 protected:
   virtual void write_ref_array_work(MemRegion mr) = 0;
 public: