8223794: applications/kitchensink/Kitchensink.java crash bad oop with Graal
authorkvn
Thu, 20 Jun 2019 10:32:25 -0700
changeset 55454 8892555795cd
parent 55453 65916ade7fa2
child 55455 76647c08ce0c
8223794: applications/kitchensink/Kitchensink.java crash bad oop with Graal Summary: added new nmethod::oop_at_phantom() method for JVMCI to notify GC that oop should be kept alive Reviewed-by: dlong, eosterlund
src/hotspot/share/code/nmethod.cpp
src/hotspot/share/code/nmethod.hpp
src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
src/hotspot/share/jvmci/jvmciRuntime.cpp
src/hotspot/share/jvmci/jvmciRuntime.hpp
--- a/src/hotspot/share/code/nmethod.cpp	Thu Jun 20 07:56:28 2019 -0700
+++ b/src/hotspot/share/code/nmethod.cpp	Thu Jun 20 10:32:25 2019 -0700
@@ -1473,6 +1473,13 @@
   return NativeAccess<AS_NO_KEEPALIVE>::oop_load(oop_addr_at(index));
 }
 
+oop nmethod::oop_at_phantom(int index) const {
+  if (index == 0) {
+    return NULL;
+  }
+  return NativeAccess<ON_PHANTOM_OOP_REF>::oop_load(oop_addr_at(index));
+}
+
 //
 // Notify all classes this nmethod is dependent on that it is no
 // longer dependent. This should only be called in two situations.
--- a/src/hotspot/share/code/nmethod.hpp	Thu Jun 20 07:56:28 2019 -0700
+++ b/src/hotspot/share/code/nmethod.hpp	Thu Jun 20 10:32:25 2019 -0700
@@ -392,6 +392,7 @@
   // Support for oops in scopes and relocs:
   // Note: index 0 is reserved for null.
   oop   oop_at(int index) const;
+  oop   oop_at_phantom(int index) const; // phantom reference
   oop*  oop_addr_at(int index) const {  // for GC
     // relocation indexes are biased by 1 (because 0 is reserved)
     assert(index > 0 && index <= oops_count(), "must be a valid non-zero index");
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Thu Jun 20 07:56:28 2019 -0700
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Thu Jun 20 10:32:25 2019 -0700
@@ -2416,7 +2416,7 @@
         if (peerEnv->is_hotspot()) {
           // Only the mirror in the HotSpot heap is accessible
           // through JVMCINMethodData
-          oop nmethod_mirror = data->get_nmethod_mirror(nm);
+          oop nmethod_mirror = data->get_nmethod_mirror(nm, /* phantom_ref */ true);
           if (nmethod_mirror != NULL) {
             result = HotSpotJVMCI::wrap(nmethod_mirror);
           }
@@ -2443,7 +2443,7 @@
           if (data == NULL) {
             JVMCI_THROW_MSG_0(IllegalArgumentException, "Cannot set HotSpotNmethod mirror for default nmethod");
           }
-          if (data->get_nmethod_mirror(nm) != NULL) {
+          if (data->get_nmethod_mirror(nm, /* phantom_ref */ false) != NULL) {
             JVMCI_THROW_MSG_0(IllegalArgumentException, "Cannot overwrite existing HotSpotNmethod mirror for nmethod");
           }
           oop nmethod_mirror = HotSpotJVMCI::resolve(result);
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Thu Jun 20 07:56:28 2019 -0700
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Thu Jun 20 10:32:25 2019 -0700
@@ -700,11 +700,15 @@
   FailedSpeculation::add_failed_speculation(nm, _failed_speculations, data, length);
 }
 
-oop JVMCINMethodData::get_nmethod_mirror(nmethod* nm) {
+oop JVMCINMethodData::get_nmethod_mirror(nmethod* nm, bool phantom_ref) {
   if (_nmethod_mirror_index == -1) {
     return NULL;
   }
-  return nm->oop_at(_nmethod_mirror_index);
+  if (phantom_ref) {
+    return nm->oop_at_phantom(_nmethod_mirror_index);
+  } else {
+    return nm->oop_at(_nmethod_mirror_index);
+  }
 }
 
 void JVMCINMethodData::set_nmethod_mirror(nmethod* nm, oop new_mirror) {
@@ -728,7 +732,7 @@
 }
 
 void JVMCINMethodData::invalidate_nmethod_mirror(nmethod* nm) {
-  oop nmethod_mirror = get_nmethod_mirror(nm);
+  oop nmethod_mirror = get_nmethod_mirror(nm, /* phantom_ref */ true);
   if (nmethod_mirror == NULL) {
     return;
   }
@@ -1530,7 +1534,7 @@
         JVMCINMethodData* data = nm->jvmci_nmethod_data();
         assert(data != NULL, "must be");
         if (install_default) {
-          assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm) == NULL, "must be");
+          assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm, /* phantom_ref */ false) == NULL, "must be");
           if (entry_bci == InvocationEntryBci) {
             if (TieredCompilation) {
               // If there is an old version we're done with it
@@ -1565,7 +1569,7 @@
             InstanceKlass::cast(method->method_holder())->add_osr_nmethod(nm);
           }
         } else {
-          assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm) == HotSpotJVMCI::resolve(nmethod_mirror), "must be");
+          assert(!nmethod_mirror.is_hotspot() || data->get_nmethod_mirror(nm, /* phantom_ref */ false) == HotSpotJVMCI::resolve(nmethod_mirror), "must be");
         }
         nm->make_in_use();
       }
--- a/src/hotspot/share/jvmci/jvmciRuntime.hpp	Thu Jun 20 07:56:28 2019 -0700
+++ b/src/hotspot/share/jvmci/jvmciRuntime.hpp	Thu Jun 20 10:32:25 2019 -0700
@@ -74,7 +74,7 @@
   void invalidate_nmethod_mirror(nmethod* nm);
 
   // Gets the mirror from nm's oops table.
-  oop get_nmethod_mirror(nmethod* nm);
+  oop get_nmethod_mirror(nmethod* nm, bool phantom_ref);
 
   // Sets the mirror in nm's oops table.
   void set_nmethod_mirror(nmethod* nm, oop mirror);