Skip to content

Commit 24597f4

Browse files
author
duke
committed
Automatic merge of jdk:master into master
2 parents 86e3035 + 66943fe commit 24597f4

File tree

14 files changed

+295
-31
lines changed

14 files changed

+295
-31
lines changed

make/hotspot/symbols/symbols-unix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ JVM_RawMonitorCreate
177177
JVM_RawMonitorDestroy
178178
JVM_RawMonitorEnter
179179
JVM_RawMonitorExit
180+
JVM_ReferenceClear
180181
JVM_ReferenceRefersTo
181182
JVM_RegisterLambdaProxyClassForArchiving
182183
JVM_RegisterSignal

src/hotspot/share/gc/z/zBreakpoint.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,7 @@ void ZBreakpoint::at_after_marking_started() {
5757
void ZBreakpoint::at_before_marking_completed() {
5858
ConcurrentGCBreakpoints::at("BEFORE MARKING COMPLETED");
5959
}
60+
61+
void ZBreakpoint::at_after_reference_processing_started() {
62+
ConcurrentGCBreakpoints::at("AFTER CONCURRENT REFERENCE PROCESSING STARTED");
63+
}

src/hotspot/share/gc/z/zBreakpoint.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class ZBreakpoint : public AllStatic {
3737
static void at_after_gc();
3838
static void at_after_marking_started();
3939
static void at_before_marking_completed();
40+
static void at_after_reference_processing_started();
4041
};
4142

4243
#endif // SHARE_GC_Z_ZBREAKPOINT_HPP

src/hotspot/share/gc/z/zDriver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ void ZDriver::concurrent_mark_continue() {
322322

323323
void ZDriver::concurrent_process_non_strong_references() {
324324
ZStatTimer timer(ZPhaseConcurrentProcessNonStrongReferences);
325+
ZBreakpoint::at_after_reference_processing_started();
325326
ZHeap::heap()->process_non_strong_references();
326327
}
327328

src/hotspot/share/gc/z/zReferenceProcessor.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,12 +183,6 @@ bool ZReferenceProcessor::should_discover(oop reference, ReferenceType type) con
183183
}
184184

185185
bool ZReferenceProcessor::should_drop(oop reference, ReferenceType type) const {
186-
// This check is racing with a call to Reference.clear() from the application.
187-
// If the application clears the reference after this check it will still end
188-
// up on the pending list, and there's nothing we can do about that without
189-
// changing the Reference.clear() API. This check is also racing with a call
190-
// to Reference.enqueue() from the application, which is unproblematic, since
191-
// the application wants the reference to be enqueued anyway.
192186
const oop referent = reference_referent(reference);
193187
if (referent == NULL) {
194188
// Reference has been cleared, by a call to Reference.enqueue()

src/hotspot/share/include/jvm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ JVM_WaitForReferencePendingList(JNIEnv *env);
333333
JNIEXPORT jboolean JNICALL
334334
JVM_ReferenceRefersTo(JNIEnv *env, jobject ref, jobject o);
335335

336+
JNIEXPORT void JNICALL
337+
JVM_ReferenceClear(JNIEnv *env, jobject ref);
338+
336339
/*
337340
* java.lang.ref.PhantomReference
338341
*/

src/hotspot/share/prims/jvm.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3446,6 +3446,25 @@ JVM_ENTRY(jboolean, JVM_ReferenceRefersTo(JNIEnv* env, jobject ref, jobject o))
34463446
return referent == JNIHandles::resolve(o);
34473447
JVM_END
34483448

3449+
JVM_ENTRY(void, JVM_ReferenceClear(JNIEnv* env, jobject ref))
3450+
JVMWrapper("JVM_ReferenceClear");
3451+
oop ref_oop = JNIHandles::resolve_non_null(ref);
3452+
// FinalReference has it's own implementation of clear().
3453+
assert(!java_lang_ref_Reference::is_final(ref_oop), "precondition");
3454+
if (java_lang_ref_Reference::unknown_referent_no_keepalive(ref_oop) == NULL) {
3455+
// If the referent has already been cleared then done.
3456+
// However, if the referent is dead but has not yet been cleared by
3457+
// concurrent reference processing, it should NOT be cleared here.
3458+
// Instead, clearing should be left to the GC. Clearing it here could
3459+
// detectably lose an expected notification, which is impossible with
3460+
// STW reference processing. The clearing in enqueue() doesn't have
3461+
// this problem, since the enqueue covers the notification, but it's not
3462+
// worth the effort to handle that case specially.
3463+
return;
3464+
}
3465+
java_lang_ref_Reference::clear_referent(ref_oop);
3466+
JVM_END
3467+
34493468

34503469
// java.lang.ref.PhantomReference //////////////////////////////////////////////////
34513470

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2017, 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
@@ -34,6 +34,22 @@ public FinalReference(T referent, ReferenceQueue<? super T> q) {
3434
super(referent, q);
3535
}
3636

37+
/* May only be called when the reference is inactive, so no longer weak. */
38+
@Override
39+
public T get() {
40+
// Cannot call super.get() when active, as the GC could
41+
// deactivate immediately after the test.
42+
return getFromInactiveFinalReference();
43+
}
44+
45+
/* May only be called when the reference is inactive, so no longer weak.
46+
* Clearing while active would discard the finalization request.
47+
*/
48+
@Override
49+
public void clear() {
50+
clearInactiveFinalReference();
51+
}
52+
3753
@Override
3854
public boolean enqueue() {
3955
throw new InternalError("should never reach here");

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2018, 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
@@ -82,7 +82,7 @@ private void runFinalizer(JavaLangAccess jla) {
8282
}
8383

8484
try {
85-
Object finalizee = this.getInactive();
85+
Object finalizee = this.get();
8686
assert finalizee != null;
8787
if (!(finalizee instanceof java.lang.Enum)) {
8888
jla.invokeFinalize(finalizee);

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

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ public abstract class Reference<T> {
100100
* [active/unregistered] [1]
101101
*
102102
* Transitions:
103-
* clear
103+
* clear [2]
104104
* [active/registered] -------> [inactive/registered]
105105
* | |
106-
* | | enqueue [2]
106+
* | | enqueue
107107
* | GC enqueue [2] |
108108
* | -----------------|
109109
* | |
@@ -114,7 +114,7 @@ public abstract class Reference<T> {
114114
* v | |
115115
* [pending/enqueued] --- |
116116
* | | poll/remove
117-
* | poll/remove |
117+
* | poll/remove | + clear [4]
118118
* | |
119119
* v ReferenceHandler v
120120
* [pending/dequeued] ------> [inactive/dequeued]
@@ -140,12 +140,14 @@ public abstract class Reference<T> {
140140
* [1] Unregistered is not permitted for FinalReferences.
141141
*
142142
* [2] These transitions are not possible for FinalReferences, making
143-
* [pending/enqueued] and [pending/dequeued] unreachable, and
144-
* [inactive/registered] terminal.
143+
* [pending/enqueued], [pending/dequeued], and [inactive/registered]
144+
* unreachable.
145145
*
146146
* [3] The garbage collector may directly transition a Reference
147147
* from [active/unregistered] to [inactive/unregistered],
148148
* bypassing the pending-Reference list.
149+
*
150+
* [4] The queue handler for FinalReferences also clears the reference.
149151
*/
150152

151153
private T referent; /* Treated specially by GC */
@@ -342,22 +344,6 @@ public T get() {
342344
return this.referent;
343345
}
344346

345-
/**
346-
* Load referent with strong semantics. Treating the referent
347-
* as strong referent is ok when the Reference is inactive,
348-
* because then the referent is switched to strong semantics
349-
* anyway.
350-
*
351-
* This is only used from Finalizer to bypass the intrinsic,
352-
* which might return a null referent, even though it is not
353-
* null, and would subsequently not finalize the referent/finalizee.
354-
*/
355-
T getInactive() {
356-
assert this instanceof FinalReference;
357-
assert next == this; // I.e. FinalReference is inactive
358-
return this.referent;
359-
}
360-
361347
/**
362348
* Tests if the referent of this reference object is {@code obj}.
363349
* Using a {@code null} {@code obj} returns {@code true} if the
@@ -383,6 +369,41 @@ public final boolean refersTo(T obj) {
383369
* clears references it does so directly, without invoking this method.
384370
*/
385371
public void clear() {
372+
clear0();
373+
}
374+
375+
/* Implementation of clear(), also used by enqueue(). A simple
376+
* assignment of the referent field won't do for some garbage
377+
* collectors.
378+
*/
379+
private native void clear0();
380+
381+
/* -- Operations on inactive FinalReferences -- */
382+
383+
/* These functions are only used by FinalReference, and must only be
384+
* called after the reference becomes inactive. While active, a
385+
* FinalReference is considered weak but the referent is not normally
386+
* accessed. Once a FinalReference becomes inactive it is considered a
387+
* strong reference. These functions are used to bypass the
388+
* corresponding weak implementations, directly accessing the referent
389+
* field with strong semantics.
390+
*/
391+
392+
/**
393+
* Load referent with strong semantics.
394+
*/
395+
T getFromInactiveFinalReference() {
396+
assert this instanceof FinalReference;
397+
assert next != null; // I.e. FinalReference is inactive
398+
return this.referent;
399+
}
400+
401+
/**
402+
* Clear referent with strong semantics.
403+
*/
404+
void clearInactiveFinalReference() {
405+
assert this instanceof FinalReference;
406+
assert next != null; // I.e. FinalReference is inactive
386407
this.referent = null;
387408
}
388409

@@ -413,7 +434,7 @@ public boolean isEnqueued() {
413434
* it was not registered with a queue when it was created
414435
*/
415436
public boolean enqueue() {
416-
this.referent = null;
437+
clear0(); // Intentionally clear0() rather than clear()
417438
return this.queue.enqueue(this);
418439
}
419440

0 commit comments

Comments
 (0)