RFR: 8188055: (ref) Add Reference::refersTo predicate

Per Liden pliden at openjdk.java.net
Mon Oct 5 11:04:38 UTC 2020


On Sun, 4 Oct 2020 03:59:59 GMT, Kim Barrett <kbarrett at openjdk.org> wrote:

> Finally returning to this review that was started in April 2020.  I've
> recast it as a github PR.  I think the security concern raised by Gil
> has been adequately answered.
> https://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2020-April/029203.html
> https://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2020-July/030401.html
> https://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2020-August/030677.html
> https://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2020-September/030793.html
> 
> Please review a new function: java.lang.ref.Reference.refersTo.
> 
> This function is needed to test the referent of a Reference object without
> artificially extending the lifetime of the referent object, as may happen
> when calling Reference.get.  Some garbage collectors require extending the
> lifetime of a weak referent when accessed, in order to maintain collector
> invariants.  Lifetime extension may occur with any collector when the
> Reference is a SoftReference, as calling get indicates recent access.  This
> new function also allows testing the referent of a PhantomReference, which
> can't be accessed by calling get.
> 
> The new function uses native methods whose implementations are in the VM so
> they can use the Access API.  It is the intent that these methods will be
> intrinsified by optimizing compilers like C2 or graal, but that hasn't been
> implemented yet.  Bear that in mind before rushing off to change existing
> uses of Reference.get.
> 
> There are two native methods involved, one in Reference and an override in
> PhantomReference, both package private in java.lang.ref. The reason for this
> split is to simplify the intrinsification. This is a change from the version
> from April 2020; that version had a single native method in Reference,
> implemented using the ON_UNKNOWN_OOP_REF Access reference strength category.
> However, adding support for that category in the compilers adds significant
> implementation effort and complexity. Splitting avoids that complexity.
> 
> Testing:
> mach5 tier1
> Locally (linux-x64) verified the new test passes with various garbage collectors.

test/hotspot/jtreg/gc/TestReferenceRefersTo.java line 179:

> 177:             // For some collectors, calling get() will keep testObject4 alive.
> 178:             // For example, SATB collectors or ZGC, but not collectors using
> 179:             // incremental update barriers like CMS.

Remove obsolete CMS comment?

test/hotspot/jtreg/gc/TestReferenceRefersTo.java line 65:

> 63:
> 64:     private static WeakReference<TestObject> testWeak2 = null;
> 65:     private static WeakReference<TestObject> testWeak3 = null;

It looks like test*2 and test*3 test the same thing in both tests, so test*3 could be removed, and test*4 could be
renamed test*3.

src/hotspot/share/prims/jvm.cpp line 3446:

> 3444:   oop referent = HeapAccess<on_ref | AS_NO_KEEPALIVE>::oop_load_at(ref_oop, offset);
> 3445:   return referent == JNIHandles::resolve(o);
> 3446: }

How about moving the inner logic to java_lang_ref_{Reference,PhantomReference}::refers_to() functions?

src/hotspot/share/prims/jvm.cpp line 3451:

> 3449:   JVMWrapper("JVM_ReferenceRefersTo");
> 3450:   return referenceRefersTo<ON_WEAK_OOP_REF>(ref, o);
> 3451: JVM_END

... and let this be something like:

JVM_ENTRY(jboolean, JVM_ReferenceRefersTo(JNIEnv* env, jobject ref, jobject o))
  JVMWrapper("JVM_ReferenceRefersTo");
  oop ref_oop = JNIHandles::resolve_non_null(ref);
  oop cmp_oop = JNIHandles::resolve(o);
  return java_lang_ref_Reference::refers_to(ref_oop, cmp_oop);
JVM_END

src/hotspot/share/prims/jvm.cpp line 3460:

> 3458:   JVMWrapper("JVM_PhantomReferenceRefersTo");
> 3459:   return referenceRefersTo<ON_PHANTOM_OOP_REF>(ref, o);
> 3460: JVM_END

... and let this be something like:

JVM_ENTRY(jboolean, JVM_PhantomReferenceRefersTo(JNIEnv* env, jobject ref, jobject o))
  JVMWrapper("JVM_ReferenceRefersTo");
  oop ref_oop = JNIHandles::resolve_non_null(ref);
  oop cmp_oop = JNIHandles::resolve(o);
  return java_lang_ref_PhantomReference::refers_to(ref_oop, cmp_oop);
JVM_END

-------------

PR: https://git.openjdk.java.net/jdk/pull/498


More information about the core-libs-dev mailing list