# HG changeset patch # User pliden # Date 1545062117 -3600 # Node ID 7aa1a37b04a2c6b5c2070cccc970275567d38692 # Parent 041f1cbdae3e7b1ed3b12bc4e6bcb87a3da77f01 8215451: JNI IsSameObject should not keep objects alive Reviewed-by: eosterlund, kbarrett diff -r 041f1cbdae3e -r 7aa1a37b04a2 src/hotspot/share/prims/jni.cpp --- a/src/hotspot/share/prims/jni.cpp Mon Dec 17 08:25:57 2018 +0100 +++ b/src/hotspot/share/prims/jni.cpp Mon Dec 17 16:55:17 2018 +0100 @@ -823,9 +823,7 @@ HOTSPOT_JNI_ISSAMEOBJECT_ENTRY(env, r1, r2); - oop a = JNIHandles::resolve(r1); - oop b = JNIHandles::resolve(r2); - jboolean ret = oopDesc::equals(a, b) ? JNI_TRUE : JNI_FALSE; + jboolean ret = JNIHandles::is_same_object(r1, r2) ? JNI_TRUE : JNI_FALSE; HOTSPOT_JNI_ISSAMEOBJECT_RETURN(ret); return ret; diff -r 041f1cbdae3e -r 7aa1a37b04a2 src/hotspot/share/runtime/jniHandles.cpp --- a/src/hotspot/share/runtime/jniHandles.cpp Mon Dec 17 08:25:57 2018 +0100 +++ b/src/hotspot/share/runtime/jniHandles.cpp Mon Dec 17 16:55:17 2018 +0100 @@ -152,17 +152,11 @@ oop JNIHandles::resolve_external_guard(jobject handle) { oop result = NULL; if (handle != NULL) { - result = resolve_impl(handle); + result = resolve_impl<0 /* decorators */, true /* external_guard */>(handle); } return result; } -oop JNIHandles::resolve_jweak(jweak handle) { - assert(handle != NULL, "precondition"); - assert(is_jweak(handle), "precondition"); - return NativeAccess::oop_load(jweak_ptr(handle)); -} - bool JNIHandles::is_global_weak_cleared(jweak handle) { assert(handle != NULL, "precondition"); assert(is_jweak(handle), "not a weak handle"); diff -r 041f1cbdae3e -r 7aa1a37b04a2 src/hotspot/share/runtime/jniHandles.hpp --- a/src/hotspot/share/runtime/jniHandles.hpp Mon Dec 17 08:25:57 2018 +0100 +++ b/src/hotspot/share/runtime/jniHandles.hpp Mon Dec 17 16:55:17 2018 +0100 @@ -42,8 +42,10 @@ inline static oop* jobject_ptr(jobject handle); // NOT jweak! inline static oop* jweak_ptr(jobject handle); - template inline static oop resolve_impl(jobject handle); - static oop resolve_jweak(jweak handle); + template inline static oop resolve_impl(jobject handle); + + // Resolve handle into oop, without keeping the object alive + inline static oop resolve_no_keepalive(jobject handle); // This method is not inlined in order to avoid circular includes between // this header file and thread.hpp. @@ -70,6 +72,9 @@ // Resolve externally provided handle into oop with some guards static oop resolve_external_guard(jobject handle); + // Check for equality without keeping objects alive + static bool is_same_object(jobject handle1, jobject handle2); + // Local handles static jobject make_local(oop obj); static jobject make_local(JNIEnv* env, oop obj); // Fast version when env is known diff -r 041f1cbdae3e -r 7aa1a37b04a2 src/hotspot/share/runtime/jniHandles.inline.hpp --- a/src/hotspot/share/runtime/jniHandles.inline.hpp Mon Dec 17 08:25:57 2018 +0100 +++ b/src/hotspot/share/runtime/jniHandles.inline.hpp Mon Dec 17 16:55:17 2018 +0100 @@ -49,15 +49,15 @@ } // external_guard is true if called from resolve_external_guard. -template +template inline oop JNIHandles::resolve_impl(jobject handle) { assert(handle != NULL, "precondition"); assert(!current_thread_in_native(), "must not be in native"); oop result; if (is_jweak(handle)) { // Unlikely - result = resolve_jweak(handle); + result = NativeAccess::oop_load(jweak_ptr(handle)); } else { - result = NativeAccess<>::oop_load(jobject_ptr(handle)); + result = NativeAccess::oop_load(jobject_ptr(handle)); // Construction of jobjects canonicalize a null value into a null // jobject, so for non-jweak the pointee should never be null. assert(external_guard || result != NULL, "Invalid JNI handle"); @@ -68,14 +68,28 @@ inline oop JNIHandles::resolve(jobject handle) { oop result = NULL; if (handle != NULL) { - result = resolve_impl(handle); + result = resolve_impl<0 /* decorators */, false /* external_guard */>(handle); } return result; } +inline oop JNIHandles::resolve_no_keepalive(jobject handle) { + oop result = NULL; + if (handle != NULL) { + result = resolve_impl(handle); + } + return result; +} + +inline bool JNIHandles::is_same_object(jobject handle1, jobject handle2) { + oop obj1 = resolve_no_keepalive(handle1); + oop obj2 = resolve_no_keepalive(handle2); + return oopDesc::equals(obj1, obj2); +} + inline oop JNIHandles::resolve_non_null(jobject handle) { assert(handle != NULL, "JNI handle should not be null"); - oop result = resolve_impl(handle); + oop result = resolve_impl<0 /* decorators */, false /* external_guard */>(handle); assert(result != NULL, "NULL read from jni handle"); return result; } diff -r 041f1cbdae3e -r 7aa1a37b04a2 test/hotspot/jtreg/serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorThreadTest.java --- a/test/hotspot/jtreg/serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorThreadTest.java Mon Dec 17 08:25:57 2018 +0100 +++ b/test/hotspot/jtreg/serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorThreadTest.java Mon Dec 17 16:55:17 2018 +0100 @@ -30,7 +30,6 @@ * @summary Verifies the JVMTI Heap Monitor Thread information sanity. * @compile HeapMonitorThreadTest.java * @run main/othervm/native -Xmx512m -agentlib:HeapMonitorTest MyPackage.HeapMonitorThreadTest - * @requires !vm.gc.Z */ import java.util.List;