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