From caf7887f270737948fc3d77cec691c1d44652412 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Thu, 15 Sep 2022 10:14:14 +0200 Subject: [PATCH 1/4] make TestEnableJVMCIProduct pass on GraalVM (GR-38476) --- test/hotspot/jtreg/compiler/jvmci/TestEnableJVMCIProduct.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/jvmci/TestEnableJVMCIProduct.java b/test/hotspot/jtreg/compiler/jvmci/TestEnableJVMCIProduct.java index 85471c120b8..5975f604a0d 100644 --- a/test/hotspot/jtreg/compiler/jvmci/TestEnableJVMCIProduct.java +++ b/test/hotspot/jtreg/compiler/jvmci/TestEnableJVMCIProduct.java @@ -67,7 +67,7 @@ public static void main(String[] args) throws Exception { new Expectation("EnableJVMCI", "false", "command line"), new Expectation("UseJVMCICompiler", "false", "default")); test("-XX:+EnableJVMCIProduct", - new Expectation("EnableJVMCIProduct", "true", "command line"), + new Expectation("EnableJVMCIProduct", "true", "(command line|jimage)"), new Expectation("EnableJVMCI", "true", "default"), new Expectation("UseJVMCICompiler", "true", "default")); } From 5c7d7234bb7677b5b7afd96ff31309fc3a80be88 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Thu, 15 Sep 2022 10:23:47 +0200 Subject: [PATCH 2/4] make PrintInlining test pass on GraalVM (GR-38478) --- test/hotspot/jtreg/compiler/inlining/PrintInlining.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/inlining/PrintInlining.java b/test/hotspot/jtreg/compiler/inlining/PrintInlining.java index a0975dee673..10985f11143 100644 --- a/test/hotspot/jtreg/compiler/inlining/PrintInlining.java +++ b/test/hotspot/jtreg/compiler/inlining/PrintInlining.java @@ -34,6 +34,8 @@ package compiler.inlining; +import java.util.regex.Pattern; + import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; @@ -45,6 +47,7 @@ static void test(String option) throws Exception { "-server", "-XX:-TieredCompilation", "-Xbatch", "-XX:-UseOnStackReplacement", "-XX:CompileCommand=dontinline,*::bar", "-XX:CompileCommand=compileonly,*::foo", + "-XX:+PrintFlagsFinal", "-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions", option, Launcher.class.getName()); @@ -52,8 +55,10 @@ static void test(String option) throws Exception { analyzer.shouldHaveExitValue(0); + boolean usesJVMCICompiler = Pattern.compile("bool +UseJVMCICompiler += true", Pattern.MULTILINE).matcher(analyzer.getStdout()).find(); + // The test is applicable only to C2 (present in Server VM). - if (analyzer.getStderr().contains("Server VM")) { + if (analyzer.getStderr().contains("Server VM") && !usesJVMCICompiler) { analyzer.outputTo(System.out); if (analyzer.asLines().stream() .filter(s -> s.matches(".*A::bar.+virtual call.*")) From 9260e89a7f05444c6679496808f44778f8d2dc21 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Thu, 15 Sep 2022 10:27:48 +0200 Subject: [PATCH 3/4] make InlineAccessors test pass on GraalVM (GR-38479) --- test/hotspot/jtreg/compiler/inlining/InlineAccessors.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/inlining/InlineAccessors.java b/test/hotspot/jtreg/compiler/inlining/InlineAccessors.java index 0d4da50cfc5..5deef97f999 100644 --- a/test/hotspot/jtreg/compiler/inlining/InlineAccessors.java +++ b/test/hotspot/jtreg/compiler/inlining/InlineAccessors.java @@ -33,6 +33,8 @@ package compiler.inlining; +import java.util.regex.Pattern; + import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; @@ -41,6 +43,7 @@ public static void main(String[] args) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-XX:+IgnoreUnrecognizedVMOptions", "-showversion", "-server", "-XX:-TieredCompilation", "-Xbatch", + "-XX:+PrintFlagsFinal", "-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining", Launcher.class.getName()); @@ -48,8 +51,10 @@ public static void main(String[] args) throws Exception { analyzer.shouldHaveExitValue(0); + boolean usesJVMCICompiler = Pattern.compile("bool +UseJVMCICompiler += true", Pattern.MULTILINE).matcher(analyzer.getStdout()).find(); + // The test is applicable only to C2 (present in Server VM). - if (analyzer.getStderr().contains("Server VM")) { + if (analyzer.getStderr().contains("Server VM") && !usesJVMCICompiler) { analyzer.shouldContain("InlineAccessors::setBool (6 bytes) accessor"); analyzer.shouldContain("InlineAccessors::setByte (6 bytes) accessor"); analyzer.shouldContain("InlineAccessors::setChar (6 bytes) accessor"); From 84cdab257a8fd0a8f19730daed62a81aebc52da8 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Thu, 15 Sep 2022 22:03:41 +0200 Subject: [PATCH 4/4] re-use slots in JVMCIRuntime::_oop_handles --- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 10 +- src/hotspot/share/jvmci/jvmciRuntime.cpp | 158 ++++++++++-------- src/hotspot/share/jvmci/jvmciRuntime.hpp | 17 +- .../src/jdk/vm/ci/hotspot/Cleaner.java | 14 +- .../src/jdk/vm/ci/hotspot/CompilerToVM.java | 5 +- .../src/jdk/vm/ci/hotspot/HandleCleaner.java | 9 +- .../hotspot/HotSpotObjectConstantScope.java | 1 + .../vm/ci/hotspot/HotSpotSpeculationLog.java | 3 +- .../IndirectHotSpotObjectConstantImpl.java | 12 +- 9 files changed, 128 insertions(+), 101 deletions(-) diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 7d9607e28f6..beb44f162c5 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -2235,11 +2235,9 @@ C2V_VMENTRY_0(jint, arrayIndexScale, (JNIEnv* env, jobject, jchar type_char)) return type2aelembytes(type); C2V_END -C2V_VMENTRY(void, deleteGlobalHandle, (JNIEnv* env, jobject, jlong handle)) - if (handle != 0) { - JVMCIENV->runtime()->destroy_oop_handle(handle); - } -} +C2V_VMENTRY(void, releaseClearedOopHandles, (JNIEnv* env, jobject)) + JVMCIENV->runtime()->release_cleared_oop_handles(); +C2V_END static void requireJVMCINativeLibrary(JVMCI_TRAPS) { if (!UseJVMCINativeLibrary) { @@ -2939,7 +2937,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 "deleteGlobalHandle", CC "(J)V", FN_PTR(deleteGlobalHandle)}, + {CC "releaseClearedOopHandles", CC "()V", FN_PTR(releaseClearedOopHandles)}, {CC "registerNativeMethods", CC "(" CLASS ")[J", FN_PTR(registerNativeMethods)}, {CC "isCurrentThreadAttached", CC "()Z", FN_PTR(isCurrentThreadAttached)}, {CC "getCurrentJavaThread", CC "()J", FN_PTR(getCurrentJavaThread)}, diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index 6385aead722..0d8a61c014e 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -838,94 +838,107 @@ static OopStorage* object_handles() { jlong JVMCIRuntime::make_oop_handle(const Handle& obj) { assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC"); assert(oopDesc::is_oop(obj()), "not an oop"); - oop* ptr = object_handles()->allocate(); - jlong res = 0; - if (ptr != nullptr) { - assert(*ptr == nullptr, "invariant"); - NativeAccess<>::oop_store(ptr, obj()); - res = (jlong) ptr; - } else { - vm_exit_out_of_memory(sizeof(oop), OOM_MALLOC_ERROR, - "Cannot create JVMCI oop handle"); - } + + oop* ptr = OopHandle(object_handles(), obj()).ptr_raw(); MutexLocker ml(_lock); _oop_handles.append(ptr); - return res; + return (jlong) ptr; } -bool JVMCIRuntime::probe_oop_handle(jlong handle, int index) { - oop* key = (oop*) handle; - if (key == _oop_handles.at(index)) { - _last_found_oop_handle_index = index; - return true; +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(); + if (_oop_handles.length() != 0) { + for (int i = 0; i < _oop_handles.length(); i++) { + oop* oop_ptr = _oop_handles.at(i); + guarantee(oop_ptr != nullptr, "release_cleared_oop_handles left null entry in _oop_handles"); + guarantee(*oop_ptr != nullptr, "unexpected cleared handle"); + // Satisfy OopHandles::release precondition that all + // handles being released are null. + NativeAccess<>::oop_store(oop_ptr, (oop) NULL); + } + + // Do the bulk release + object_handles()->release(_oop_handles.adr_at(0), _oop_handles.length()); + released += _oop_handles.length(); } - return false; + _oop_handles.clear(); + return released; } -int JVMCIRuntime::find_oop_handle(jlong handle) { - int len = _oop_handles.length(); - int next = _last_found_oop_handle_index + 1; - int prev = MAX2(_last_found_oop_handle_index, 0) - 1; +static bool is_referent_non_null(oop* handle) { + return handle != nullptr && *handle != nullptr; +} - // Search "outwards" from the index of the last found - // entry. Experimentation shows that this significantly - // reduces the amount of searching performed. - do { - if (next < len) { - if (probe_oop_handle(handle, next)) { - return next; - } - next++; - } - if (prev >= 0) { - if (probe_oop_handle(handle, prev)) { - return prev; - } - prev--; - } - } while (next - (prev + 1) < len); - return -1; +// Swaps the elements in `array` at index `a` and index `b` +static void swap(GrowableArray* array, int a, int b) { + oop* tmp = array->at(a); + array->at_put(a, array->at(b)); + array->at_put(b, tmp); } -int JVMCIRuntime::release_and_clear_globals() { - int released = 0; +int JVMCIRuntime::release_cleared_oop_handles() { + // Despite this lock, it's possible for another thread + // to clear a handle's referent concurrently (e.g., a thread + // executing IndirectHotSpotObjectConstantImpl.clear()). + // This is benign - it means there can still be cleared + // handles in _oop_handles when this method returns. + MutexLocker ml(_lock); + + int next = 0; if (_oop_handles.length() != 0) { - // Squash non-null JNI handles to front of _oop_handles for - // the bulk release operation + // Key for _oop_handles contents in example below: + // H: handle with non-null referent + // h: handle with clear (i.e., null) referent + // -: null entry + + // Shuffle all handles with non-null referents to the front of the list + // Example: Before: 0HHh-Hh- + // After: HHHh--h- for (int i = 0; i < _oop_handles.length(); i++) { - oop* oop_ptr = _oop_handles.at(i); - if (oop_ptr != nullptr) { - // Satisfy OopHandles::release precondition that all - // handles being released are null. - NativeAccess<>::oop_store(oop_ptr, (oop) NULL); + oop* handle = _oop_handles.at(i); + if (is_referent_non_null(handle)) { + if (i != next && !is_referent_non_null(_oop_handles.at(next))) { + // Swap elements at index `next` and `i` + swap(&_oop_handles, next, i); + } + next++; + } + } - _oop_handles.at_put(released++, oop_ptr); + // `next` is now the index of the first null handle or handle with a null referent + int num_alive = next; + + // Shuffle all null handles to the end of the list + // Example: Before: HHHh--h- + // After: HHHhh--- + // num_alive: 3 + for (int i = next; i < _oop_handles.length(); i++) { + oop* handle = _oop_handles.at(i); + if (handle != nullptr) { + if (i != next && _oop_handles.at(next) == nullptr) { + // Swap elements at index `next` and `i` + swap(&_oop_handles, next, i); + } + next++; } } - // Do the bulk release - object_handles()->release(_oop_handles.adr_at(0), released); - } - _oop_handles.clear(); - _last_found_oop_handle_index = -1; - return released; -} + int to_release = next - num_alive; -void JVMCIRuntime::destroy_oop_handle(jlong handle) { - // Assert before nulling out, for better debugging. - assert(is_oop_handle(handle), "precondition"); - oop* oop_ptr = (oop*) handle; - NativeAccess<>::oop_store(oop_ptr, (oop) nullptr); - object_handles()->release(oop_ptr); + // `next` is now the index of the first null handle + // Example: to_release: 2 - MutexLocker ml(_lock); - int index = find_oop_handle(handle); - guarantee(index != -1, "global not allocated in JVMCI runtime %d: " INTPTR_FORMAT, id(), handle); - _oop_handles.at_put(index, nullptr); -} + // Bulk release the handles with a null referent + object_handles()->release(_oop_handles.adr_at(num_alive), to_release); -bool JVMCIRuntime::is_oop_handle(jlong handle) { - const oop* ptr = (oop*) handle; - return object_handles()->allocation_status(ptr) == OopStorage::ALLOCATED_ENTRY; + // Truncate oop handles to only those with a non-null referent + JVMCI_event_1("compacted oop handles in JVMCI runtime %d from %d to %d", _id, _oop_handles.length(), num_alive); + _oop_handles.trunc_to(num_alive); + // Example: HHH + + return to_release; + } + return 0; } jmetadata JVMCIRuntime::allocate_handle(const methodHandle& handle) { @@ -983,8 +996,7 @@ JVMCIRuntime::JVMCIRuntime(JVMCIRuntime* next, int id, bool for_compile_broker) _metadata_handles(new MetadataHandles()), _oop_handles(100, mtJVMCI), _num_attached_threads(0), - _for_compile_broker(for_compile_broker), - _last_found_oop_handle_index(-1) + _for_compile_broker(for_compile_broker) { if (id == -1) { _lock = JVMCIRuntime_lock; @@ -1164,7 +1176,7 @@ bool JVMCIRuntime::detach_thread(JavaThread* thread, const char* reason, bool ca // that could be using them. Handles for the Java JVMCI runtime // are never released as we cannot guarantee all compiler threads // using it have been stopped. - int released = release_and_clear_globals(); + int released = release_and_clear_oop_handles(); JVMCI_event_1("releasing handles for JVMCI runtime %d: oop handles=%d, metadata handles={total=%d, live=%d, blocks=%d}", _id, released, diff --git a/src/hotspot/share/jvmci/jvmciRuntime.hpp b/src/hotspot/share/jvmci/jvmciRuntime.hpp index ccabbffdf7d..d4db09691bc 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.hpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.hpp @@ -226,14 +226,9 @@ class JVMCIRuntime: public CHeapObj { // JVMCI_lock must be held by current thread static JVMCIRuntime* select_runtime_in_shutdown(JavaThread* thread); - // Helpers for destroy_oop_handle - int _last_found_oop_handle_index; - bool probe_oop_handle(jlong handle, int index); - int find_oop_handle(jlong handle); - // Releases all the non-null entries in _oop_handles and then clears - // the list. Returns the number of non-null entries prior to clearing. - int release_and_clear_globals(); + // the list. Returns the number released handles. + int release_and_clear_oop_handles(); public: JVMCIRuntime(JVMCIRuntime* next, int id, bool for_compile_broker); @@ -280,10 +275,12 @@ class JVMCIRuntime: public CHeapObj { // used when creating an IndirectHotSpotObjectConstantImpl in the // shared library JavaVM. jlong make_oop_handle(const Handle& obj); - bool is_oop_handle(jlong handle); - // Called from IndirectHotSpotObjectConstantImpl.clear(Object) - void destroy_oop_handle(jlong handle); + // 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. jmetadata allocate_handle(const methodHandle& handle); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Cleaner.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Cleaner.java index edc848c8d4a..1a88ec342f6 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Cleaner.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Cleaner.java @@ -97,19 +97,29 @@ private static synchronized void remove(Cleaner cl) { /** * Performs the cleanup action now that this object's referent has become weakly reachable. + * + * @returns true if the clean up action cleared the referent of an oop handle and requires a + * subsequent call to {@link CompilerToVM#releaseClearedOopHandles()} to reclaim the + * resources of the handle itself */ - abstract void doCleanup(); + abstract boolean doCleanup(); /** * Remove the cleaners whose referents have become weakly reachable. */ static void clean() { Cleaner c = (Cleaner) queue.poll(); + boolean oopHandleCleared = false; while (c != null) { remove(c); - c.doCleanup(); + if (c.doCleanup()) { + oopHandleCleared = true; + } c = (Cleaner) queue.poll(); } + if (oopHandleCleared) { + CompilerToVM.compilerToVM().releaseClearedOopHandles(); + } } /** diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java index 315765cb31e..b3a112ffe08 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java @@ -1167,10 +1167,9 @@ boolean isTrustedForIntrinsics(HotSpotResolvedObjectTypeImpl klass) { native boolean isTrustedForIntrinsics(HotSpotResolvedObjectTypeImpl klass, long klassPointer); /** - * Releases the resources backing the global JNI {@code handle}. This is equivalent to the - * {@code DeleteGlobalRef} JNI function. + * Releases all oop handles whose referent is null. */ - native void deleteGlobalHandle(long handle); + native void releaseClearedOopHandles(); /** * Gets the failed speculations pointed to by {@code *failedSpeculationsAddress}. diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HandleCleaner.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HandleCleaner.java index 1a9b244c441..558e5fccf80 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HandleCleaner.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HandleCleaner.java @@ -57,18 +57,17 @@ private HandleCleaner(Object wrapper, long handle, boolean isJObject) { * Releases the resource associated with {@code this.handle}. */ @Override - void doCleanup() { + boolean doCleanup() { if (isJObject) { - // The sentinel value used to denote a free handle is - // an object on the HotSpot heap so we call into the - // VM to set the target of an object handle to this value. - CompilerToVM.compilerToVM().deleteGlobalHandle(handle); + IndirectHotSpotObjectConstantImpl.clearHandle(handle); + return true; } else { // Setting the target of a jmetadata handle to 0 enables // the handle to be reused. See MetadataHandles in // metadataHandles.hpp for more info. long value = UNSAFE.getLong(null, handle); UNSAFE.compareAndSetLong(null, handle, value, 0); + return false; } } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java index 0ef506000fe..867593d9def 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java @@ -115,6 +115,7 @@ public void close() { obj.clear(localScopeDescription); } foreignObjects = null; + CompilerToVM.compilerToVM().releaseClearedOopHandles(); } CURRENT.set(parent); } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java index 776ec01c3d3..481686b0f4e 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java @@ -354,12 +354,13 @@ private static final class LogCleaner extends Cleaner { } @Override - void doCleanup() { + boolean doCleanup() { long pointer = UnsafeAccess.UNSAFE.getAddress(address); if (pointer != 0) { compilerToVM().releaseFailedSpeculations(address); } UnsafeAccess.UNSAFE.freeMemory(address); + return false; } final long address; diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java index 3d65879fc41..b43859fe5d4 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java @@ -23,6 +23,7 @@ package jdk.vm.ci.hotspot; import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; +import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; import java.io.ByteArrayOutputStream; import java.io.PrintStream; @@ -144,13 +145,22 @@ public HotSpotResolvedObjectType getType() { */ void clear(Object scopeDescription) { checkHandle(); - CompilerToVM.compilerToVM().deleteGlobalHandle(objectHandle); if (rawAudit == null) { rawAudit = scopeDescription; } + + clearHandle(objectHandle); objectHandle = 0L; } + /** + * Sets the referent of {@code handle} to 0 so that it will be reclaimed when calling + * {@link CompilerToVM#releaseClearedOopHandles}. + */ + static void clearHandle(long handle) { + UNSAFE.putLong(handle, 0); + } + @Override public JavaConstant compress() { assert !compressed;