diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index a46be0af239..6942fe0563f 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -2436,6 +2436,16 @@ C2V_VMENTRY_0(jint, arrayIndexScale, (JNIEnv* env, jobject, jchar type_char)) return type2aelembytes(type); C2V_END +C2V_VMENTRY(void, clearOopHandle, (JNIEnv* env, jobject, jlong oop_handle)) + if (oop_handle == 0L) { + JVMCI_THROW(NullPointerException); + } + // Assert before nulling out, for better debugging. + assert(JVMCIRuntime::is_oop_handle(oop_handle), "precondition"); + oop* oop_ptr = (oop*) oop_handle; + NativeAccess<>::oop_store(oop_ptr, (oop) nullptr); +C2V_END + C2V_VMENTRY(void, releaseClearedOopHandles, (JNIEnv* env, jobject)) JVMCIENV->runtime()->release_cleared_oop_handles(); C2V_END @@ -3260,6 +3270,7 @@ JNINativeMethod CompilerToVM::methods[] = { {CC "readArrayElement", CC "(" OBJECTCONSTANT "I)Ljava/lang/Object;", FN_PTR(readArrayElement)}, {CC "arrayBaseOffset", CC "(C)I", FN_PTR(arrayBaseOffset)}, {CC "arrayIndexScale", CC "(C)I", FN_PTR(arrayIndexScale)}, + {CC "clearOopHandle", CC "(J)V", FN_PTR(clearOopHandle)}, {CC "releaseClearedOopHandles", CC "()V", FN_PTR(releaseClearedOopHandles)}, {CC "registerNativeMethods", CC "(" CLASS ")[J", FN_PTR(registerNativeMethods)}, {CC "isCurrentThreadAttached", CC "()Z", FN_PTR(isCurrentThreadAttached)}, diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index afa19ce5850..68177fa8acd 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -887,6 +887,13 @@ jlong JVMCIRuntime::make_oop_handle(const Handle& obj) { return reinterpret_cast(ptr); } +#ifdef ASSERT +bool JVMCIRuntime::is_oop_handle(jlong handle) { + const oop* ptr = (oop*) handle; + return object_handles()->allocation_status(ptr) == OopStorage::ALLOCATED_ENTRY; +} +#endif + int JVMCIRuntime::release_and_clear_oop_handles() { guarantee(_num_attached_threads == cannot_be_attached, "only call during JVMCI runtime shutdown"); int released = release_cleared_oop_handles(); diff --git a/src/hotspot/share/jvmci/jvmciRuntime.hpp b/src/hotspot/share/jvmci/jvmciRuntime.hpp index 1d51f0ee31d..a3f464cd724 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.hpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.hpp @@ -317,11 +317,12 @@ class JVMCIRuntime: public CHeapObj { // used when creating an IndirectHotSpotObjectConstantImpl in the // shared library JavaVM. jlong make_oop_handle(const Handle& obj); +#ifdef ASSERT + static bool is_oop_handle(jlong handle); +#endif // Releases all the non-null entries in _oop_handles whose referent is null. // Returns the number of handles released by this call. - // The method also resets _last_found_oop_handle_index to -1 - // and _null_oop_handles to 0. int release_cleared_oop_handles(); // Allocation and management of metadata handles. diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java index a70624e0aad..f3bf7f7cf1b 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java @@ -1300,6 +1300,11 @@ final class CompilerToVM { native boolean isTrustedForIntrinsics(HotSpotResolvedObjectTypeImpl klass, long klassPointer); + /** + * Clears the oop handle in {@code handle}. + */ + native void clearOopHandle(long handle); + /** * Releases all oop handles whose referent is null. */ diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java index b89aae78aeb..33c6fde3b18 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java @@ -155,10 +155,11 @@ final class IndirectHotSpotObjectConstantImpl extends HotSpotObjectConstantImpl /** * Sets the referent of {@code handle} to 0 so that it will be reclaimed when calling - * {@link CompilerToVM#releaseClearedOopHandles}. + * {@link CompilerToVM#releaseClearedOopHandles}. This must be done with a VM call so + * that the JNI handle is cleared at a safepoint. */ static void clearHandle(long handle) { - UNSAFE.putLong(handle, 0); + runtime().compilerToVm.clearOopHandle(handle); } @Override