Skip to content

Commit 6023f6b

Browse files
author
Kim Barrett
committed
8188055: (ref) Add Reference::refersTo predicate
Reviewed-by: mchung, pliden, rriggs, dholmes, ihse, smarks, alanb
1 parent ab9192e commit 6023f6b

File tree

13 files changed

+501
-13
lines changed

13 files changed

+501
-13
lines changed

make/hotspot/symbols/symbols-unix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,13 @@ JVM_NativePath
171171
JVM_NewArray
172172
JVM_NewInstanceFromConstructor
173173
JVM_NewMultiArray
174+
JVM_PhantomReferenceRefersTo
174175
JVM_RaiseSignal
175176
JVM_RawMonitorCreate
176177
JVM_RawMonitorDestroy
177178
JVM_RawMonitorEnter
178179
JVM_RawMonitorExit
180+
JVM_ReferenceRefersTo
179181
JVM_RegisterLambdaProxyClassForArchiving
180182
JVM_RegisterSignal
181183
JVM_ReleaseUTF

src/hotspot/share/classfile/javaClasses.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -904,8 +904,9 @@ class java_lang_ref_Reference: AllStatic {
904904

905905
public:
906906
// Accessors
907-
static inline oop referent(oop ref);
908-
static inline void set_referent(oop ref, oop value);
907+
static inline oop weak_referent_no_keepalive(oop ref);
908+
static inline oop phantom_referent_no_keepalive(oop ref);
909+
static inline oop unknown_referent_no_keepalive(oop ref);
909910
static inline void set_referent_raw(oop ref, oop value);
910911
static inline HeapWord* referent_addr_raw(oop ref);
911912
static inline oop next(oop ref);

src/hotspot/share/classfile/javaClasses.inline.hpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,17 @@ bool java_lang_String::is_instance_inlined(oop obj) {
100100
}
101101

102102
// Accessors
103-
oop java_lang_ref_Reference::referent(oop ref) {
104-
return ref->obj_field(_referent_offset);
103+
104+
oop java_lang_ref_Reference::weak_referent_no_keepalive(oop ref) {
105+
return ref->obj_field_access<ON_WEAK_OOP_REF | AS_NO_KEEPALIVE>(_referent_offset);
106+
}
107+
108+
oop java_lang_ref_Reference::phantom_referent_no_keepalive(oop ref) {
109+
return ref->obj_field_access<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>(_referent_offset);
105110
}
106111

107-
void java_lang_ref_Reference::set_referent(oop ref, oop value) {
108-
ref->obj_field_put(_referent_offset, value);
112+
oop java_lang_ref_Reference::unknown_referent_no_keepalive(oop ref) {
113+
return ref->obj_field_access<ON_UNKNOWN_OOP_REF | AS_NO_KEEPALIVE>(_referent_offset);
109114
}
110115

111116
void java_lang_ref_Reference::set_referent_raw(oop ref, oop value) {

src/hotspot/share/gc/shared/referenceProcessor.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) {
262262
_next_discovered = discovered;
263263

264264
_referent_addr = java_lang_ref_Reference::referent_addr_raw(_current_discovered);
265-
_referent = java_lang_ref_Reference::referent(_current_discovered);
265+
_referent = java_lang_ref_Reference::unknown_referent_no_keepalive(_current_discovered);
266266
assert(Universe::heap()->is_in_or_null(_referent),
267267
"Wrong oop found in java.lang.Reference object");
268268
assert(allow_null_referent ?
@@ -1058,7 +1058,7 @@ ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list,
10581058
// cleared concurrently by mutators during (or after) discovery.
10591059
void ReferenceProcessor::verify_referent(oop obj) {
10601060
bool da = discovery_is_atomic();
1061-
oop referent = java_lang_ref_Reference::referent(obj);
1061+
oop referent = java_lang_ref_Reference::unknown_referent_no_keepalive(obj);
10621062
assert(da ? oopDesc::is_oop(referent) : oopDesc::is_oop_or_null(referent),
10631063
"Bad referent " INTPTR_FORMAT " found in Reference "
10641064
INTPTR_FORMAT " during %satomic discovery ",
@@ -1119,7 +1119,8 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
11191119
// known to be strongly reachable.
11201120
if (is_alive_non_header() != NULL) {
11211121
verify_referent(obj);
1122-
if (is_alive_non_header()->do_object_b(java_lang_ref_Reference::referent(obj))) {
1122+
oop referent = java_lang_ref_Reference::unknown_referent_no_keepalive(obj);
1123+
if (is_alive_non_header()->do_object_b(referent)) {
11231124
return false; // referent is reachable
11241125
}
11251126
}
@@ -1169,7 +1170,7 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
11691170
// .. we are an atomic collector and referent is in our span
11701171
if (is_subject_to_discovery(obj) ||
11711172
(discovery_is_atomic() &&
1172-
is_subject_to_discovery(java_lang_ref_Reference::referent(obj)))) {
1173+
is_subject_to_discovery(java_lang_ref_Reference::unknown_referent_no_keepalive(obj)))) {
11731174
} else {
11741175
return false;
11751176
}

src/hotspot/share/include/jvm.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,15 @@ JVM_HasReferencePendingList(JNIEnv *env);
330330
JNIEXPORT void JNICALL
331331
JVM_WaitForReferencePendingList(JNIEnv *env);
332332

333+
JNIEXPORT jboolean JNICALL
334+
JVM_ReferenceRefersTo(JNIEnv *env, jobject ref, jobject o);
335+
336+
/*
337+
* java.lang.ref.PhantomReference
338+
*/
339+
JNIEXPORT jboolean JNICALL
340+
JVM_PhantomReferenceRefersTo(JNIEnv *env, jobject ref, jobject o);
341+
333342
/*
334343
* java.io.ObjectInputStream
335344
*/

src/hotspot/share/oops/instanceRefKlass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ void InstanceRefKlass::update_nonstatic_oop_maps(Klass* k) {
7979
void InstanceRefKlass::oop_verify_on(oop obj, outputStream* st) {
8080
InstanceKlass::oop_verify_on(obj, st);
8181
// Verify referent field
82-
oop referent = java_lang_ref_Reference::referent(obj);
82+
oop referent = java_lang_ref_Reference::unknown_referent_no_keepalive(obj);
8383
if (referent != NULL) {
8484
guarantee(oopDesc::is_oop(referent), "referent field heap failed");
8585
}

src/hotspot/share/prims/jvm.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3439,6 +3439,24 @@ JVM_ENTRY(void, JVM_WaitForReferencePendingList(JNIEnv* env))
34393439
}
34403440
JVM_END
34413441

3442+
JVM_ENTRY(jboolean, JVM_ReferenceRefersTo(JNIEnv* env, jobject ref, jobject o))
3443+
JVMWrapper("JVM_ReferenceRefersTo");
3444+
oop ref_oop = JNIHandles::resolve_non_null(ref);
3445+
oop referent = java_lang_ref_Reference::weak_referent_no_keepalive(ref_oop);
3446+
return referent == JNIHandles::resolve(o);
3447+
JVM_END
3448+
3449+
3450+
// java.lang.ref.PhantomReference //////////////////////////////////////////////////
3451+
3452+
3453+
JVM_ENTRY(jboolean, JVM_PhantomReferenceRefersTo(JNIEnv* env, jobject ref, jobject o))
3454+
JVMWrapper("JVM_PhantomReferenceRefersTo");
3455+
oop ref_oop = JNIHandles::resolve_non_null(ref);
3456+
oop referent = java_lang_ref_Reference::phantom_referent_no_keepalive(ref_oop);
3457+
return referent == JNIHandles::resolve(o);
3458+
JVM_END
3459+
34423460

34433461
// ObjectInputStream ///////////////////////////////////////////////////////////////
34443462

src/java.base/share/classes/java/lang/ref/PhantomReference.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -60,6 +60,14 @@ public T get() {
6060
return null;
6161
}
6262

63+
/* Override the implementation of Reference.refersTo.
64+
* Phantom references are weaker than finalization, so the referent
65+
* access needs to be handled differently for garbage collectors that
66+
* do reference processing concurrently.
67+
*/
68+
@Override
69+
native final boolean refersTo0(Object o);
70+
6371
/**
6472
* Creates a new phantom reference that refers to the given object and
6573
* is registered with the given queue.

src/java.base/share/classes/java/lang/ref/Reference.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,14 +325,40 @@ public void runFinalization() {
325325
* been cleared, either by the program or by the garbage collector, then
326326
* this method returns {@code null}.
327327
*
328+
* @apiNote
329+
* This method returns a strong reference to the referent. This may cause
330+
* the garbage collector to treat it as strongly reachable until some later
331+
* collection cycle. The {@link #refersTo(Object) refersTo} method can be
332+
* used to avoid such strengthening when testing whether some object is
333+
* the referent of a reference object; that is, use {@code ref.refersTo(obj)}
334+
* rather than {@code ref.get() == obj}.
335+
*
328336
* @return The object to which this reference refers, or
329337
* {@code null} if this reference object has been cleared
338+
* @see refersTo
330339
*/
331340
@IntrinsicCandidate
332341
public T get() {
333342
return this.referent;
334343
}
335344

345+
/**
346+
* Tests if the referent of this reference object is {@code obj}.
347+
* Using a {@code null} {@code obj} returns {@code true} if the
348+
* reference object has been cleared.
349+
*
350+
* @param obj the object to compare with this reference object's referent
351+
* @return {@code true} if {@code obj} is the referent of this reference object
352+
* @since 16
353+
*/
354+
public final boolean refersTo(T obj) {
355+
return refersTo0(obj);
356+
}
357+
358+
/* Implementation of refersTo(), overridden for phantom references.
359+
*/
360+
native boolean refersTo0(Object o);
361+
336362
/**
337363
* Clears this reference object. Invoking this method will not cause this
338364
* object to be enqueued.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
#include "jvm.h"
27+
#include "java_lang_ref_PhantomReference.h"
28+
29+
JNIEXPORT jboolean JNICALL
30+
Java_java_lang_ref_PhantomReference_refersTo0(JNIEnv *env, jobject ref, jobject o)
31+
{
32+
return JVM_PhantomReferenceRefersTo(env, ref, o);
33+
}

0 commit comments

Comments
 (0)