Path: blob/master/jcl/src/java.base/share/classes/java/lang/ref/Reference.java
12521 views
/*[INCLUDE-IF Sidecar16]*/1/*******************************************************************************2* Copyright (c) 1998, 2021 IBM Corp. and others3*4* This program and the accompanying materials are made available under5* the terms of the Eclipse Public License 2.0 which accompanies this6* distribution and is available at https://www.eclipse.org/legal/epl-2.0/7* or the Apache License, Version 2.0 which accompanies this distribution and8* is available at https://www.apache.org/licenses/LICENSE-2.0.9*10* This Source Code may also be made available under the following11* Secondary Licenses when the conditions for such availability set12* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU13* General Public License, version 2 with the GNU Classpath14* Exception [1] and GNU General Public License, version 2 with the15* OpenJDK Assembly Exception [2].16*17* [1] https://www.gnu.org/software/classpath/license.html18* [2] http://openjdk.java.net/legal/assembly-exception.html19*20* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception21*******************************************************************************/22package java.lang.ref;2324import java.security.AccessController;25import java.security.PrivilegedAction;2627import com.ibm.oti.vm.VM;2829/*[IF JAVA_SPEC_VERSION >= 12]*/30import jdk.internal.access.JavaLangRefAccess;31import jdk.internal.access.SharedSecrets;32/*[ELSE] JAVA_SPEC_VERSION >= 1233/*[IF Sidecar19-SE]34import jdk.internal.misc.JavaLangRefAccess;35import jdk.internal.misc.SharedSecrets;36/*[ELSE]37/*[IF Sidecar18-SE-OpenJ9]38import sun.misc.JavaLangRefAccess;39import sun.misc.SharedSecrets;40/*[ENDIF]*/41/*[ENDIF]*/42/*[ENDIF] JAVA_SPEC_VERSION >= 12 */4344/**45* Abstract class which describes behavior common to all reference objects.46*47* @author OTI48* @version initial49* @since 1.250*/51public abstract class Reference<T> extends Object {52private static final int STATE_INITIAL = 0;53private static final int STATE_CLEARED = 1;54private static final int STATE_ENQUEUED = 2;5556private T referent;57private ReferenceQueue queue;58private int state;5960/*[IF Sidecar18-SE-OpenJ9 | Sidecar19-SE]*/61/**62* Wait for progress in reference processing.63* return false if there is no processing reference,64* return true after wait the notification from the reference processing thread if currently the thread is processing references.65*/66static private native boolean waitForReferenceProcessingImpl();6768/*[IF Sidecar19-SE]*/69static {70SharedSecrets.setJavaLangRefAccess(new JavaLangRefAccess() {71public boolean waitForReferenceProcessing() throws InterruptedException {72return waitForReferenceProcessingImpl();73}7475/*[IF JAVA_SPEC_VERSION >= 11]*/76public void runFinalization() {77Finalizer.runFinalization();78}79/*[ENDIF] JAVA_SPEC_VERSION >= 11 */80});81}8283/* jdk.lang.ref.disableClearBeforeEnqueue property allow reverting to the old behavior(non clear before enqueue)84* defer initializing the immutable variable to avoid bootstrap error85*/86static class ClearBeforeEnqueue {87@SuppressWarnings("boxing")88static final boolean ENABLED = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {89@Override public Boolean run() {90return !Boolean.getBoolean("jdk.lang.ref.disableClearBeforeEnqueue"); //$NON-NLS-1$91}92});93}9495/* The method waitForReferenceProcessing() is not used directly, just adapt for openjdk regression tests for TLS 1.3 */96private static boolean waitForReferenceProcessing() throws InterruptedException {97return waitForReferenceProcessingImpl();98}99100/*[ELSE]101static {102SharedSecrets.setJavaLangRefAccess(new JavaLangRefAccess() {103public boolean tryHandlePendingReference() {104return waitForReferenceProcessingImpl();105}106});107}108109/*[ENDIF]*/110/*[ENDIF]*/111112/**113* Make the referent null. This does not force the reference object to be enqueued.114*/115public void clear() {116clearImpl();117}118119/**120* set the referent to null.121*/122private void clearImpl() {123synchronized(this) {124referent = null;125/* change the state to cleared if it's not already cleared or enqueued */126if (STATE_INITIAL == state) {127state = STATE_CLEARED;128}129}130}131132/**133* Force the reference object to be enqueued if it has been associated with a queue.134*135* @return true if Reference is enqueued, false otherwise.136*/137public boolean enqueue() {138/*[IF Sidecar19-SE]*/139if (ClearBeforeEnqueue.ENABLED) {140clearImpl();141}142/*[ENDIF]*/143return enqueueImpl();144}145146/**147* Return the referent of the reference object.148*149* @return the referent to which reference refers,150* or null if object has been cleared.151*/152public T get() {153return getImpl();154}155156private native T getImpl();157158/**159* Return whether the reference object has been enqueued.160*161* @return true if Reference has been enqueued, false otherwise.162/*[IF JAVA_SPEC_VERSION >= 16]163*164* @deprecated Use ReferenceQueue or Reference.refersTo(null).165/*[ENDIF] JAVA_SPEC_VERSION >= 16166*/167/*[IF JAVA_SPEC_VERSION >= 16]*/168@Deprecated(since="16")169/*[ENDIF] JAVA_SPEC_VERSION >= 16 */170public boolean isEnqueued () {171synchronized(this) {172return state == STATE_ENQUEUED;173}174}175176/**177* Enqueue the reference object on the associated queue.178*179* @return true if the Reference was successfully180* enqueued, false otherwise.181*/182boolean enqueueImpl() {183final ReferenceQueue tempQueue;184boolean result;185T tempReferent = referent;186synchronized(this) {187/* Static order for the following code (DO NOT CHANGE) */188tempQueue = queue;189queue = null;190if (state == STATE_ENQUEUED || tempQueue == null) {191return false;192}193result = tempQueue.enqueue(this);194if (result) {195state = STATE_ENQUEUED;196if (null != tempReferent) {197reprocess();198}199}200return result;201}202}203204private native void reprocess();205206/**207* Constructs a new instance of this class.208*/209Reference() {210}211212/**213* Initialize a newly created reference object. Associate the214* reference object with the referent.215*216* @param r the referent217*/218void initReference (T r) {219state = STATE_INITIAL;220referent = r;221}222223/**224* Initialize a newly created reference object. Associate the225* reference object with the referent, and the specified ReferenceQueue.226*227* @param r the referent228* @param q the ReferenceQueue229*/230void initReference (T r, ReferenceQueue q) {231/*[PR 101461] Reference should allow null queues */232queue = q;233state = STATE_INITIAL;234referent = r;235}236237/**238* Called when a Reference has been removed from its ReferenceQueue.239* Set the enqueued field to false.240*/241void dequeue() {242/*[PR 112508] not synchronized, so isEnqueued() could return wrong result */243synchronized(this) {244state = STATE_CLEARED;245}246}247248/*[IF Sidecar19-SE]*/249/**250* Used to keep the referenced object strongly reachable so that it is not reclaimable by garbage collection.251*252* @param ref reference of the object.253* @since 9254*/255public static void reachabilityFence(java.lang.Object ref) {256}257/*[ENDIF]*/258259/*[IF JAVA_SPEC_VERSION >= 11]*/260/**261* This method will always throw CloneNotSupportedException. A clone of this instance will not be returned262* since a Reference cannot be cloned. Workaround is to create a new Reference.263*264* @throws CloneNotSupportedException always since a Reference cannot be cloned265*266* @since 11267*/268@Override269protected Object clone() throws CloneNotSupportedException {270/*[MSG "K0900", "Create a new Reference, since a Reference cannot be cloned."]*/271throw new CloneNotSupportedException(com.ibm.oti.util.Msg.getString("K0900")); //$NON-NLS-1$272}273/*[ENDIF] JAVA_SPEC_VERSION >= 11 */274275/*[IF JAVA_SPEC_VERSION >= 16]*/276/**277* Does this object refer to {@code target}?278*279* @param target the candidate referent280* @return true if this object refers to {@code target}281* @since 16282*/283public final native boolean refersTo(T target);284285/*[ENDIF] JAVA_SPEC_VERSION >= 16 */286}287288289