Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/jcl/src/java.base/share/classes/java/lang/ref/Reference.java
12521 views
1
/*[INCLUDE-IF Sidecar16]*/
2
/*******************************************************************************
3
* Copyright (c) 1998, 2021 IBM Corp. and others
4
*
5
* This program and the accompanying materials are made available under
6
* the terms of the Eclipse Public License 2.0 which accompanies this
7
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
8
* or the Apache License, Version 2.0 which accompanies this distribution and
9
* is available at https://www.apache.org/licenses/LICENSE-2.0.
10
*
11
* This Source Code may also be made available under the following
12
* Secondary Licenses when the conditions for such availability set
13
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
14
* General Public License, version 2 with the GNU Classpath
15
* Exception [1] and GNU General Public License, version 2 with the
16
* OpenJDK Assembly Exception [2].
17
*
18
* [1] https://www.gnu.org/software/classpath/license.html
19
* [2] http://openjdk.java.net/legal/assembly-exception.html
20
*
21
* 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-exception
22
*******************************************************************************/
23
package java.lang.ref;
24
25
import java.security.AccessController;
26
import java.security.PrivilegedAction;
27
28
import com.ibm.oti.vm.VM;
29
30
/*[IF JAVA_SPEC_VERSION >= 12]*/
31
import jdk.internal.access.JavaLangRefAccess;
32
import jdk.internal.access.SharedSecrets;
33
/*[ELSE] JAVA_SPEC_VERSION >= 12
34
/*[IF Sidecar19-SE]
35
import jdk.internal.misc.JavaLangRefAccess;
36
import jdk.internal.misc.SharedSecrets;
37
/*[ELSE]
38
/*[IF Sidecar18-SE-OpenJ9]
39
import sun.misc.JavaLangRefAccess;
40
import sun.misc.SharedSecrets;
41
/*[ENDIF]*/
42
/*[ENDIF]*/
43
/*[ENDIF] JAVA_SPEC_VERSION >= 12 */
44
45
/**
46
* Abstract class which describes behavior common to all reference objects.
47
*
48
* @author OTI
49
* @version initial
50
* @since 1.2
51
*/
52
public abstract class Reference<T> extends Object {
53
private static final int STATE_INITIAL = 0;
54
private static final int STATE_CLEARED = 1;
55
private static final int STATE_ENQUEUED = 2;
56
57
private T referent;
58
private ReferenceQueue queue;
59
private int state;
60
61
/*[IF Sidecar18-SE-OpenJ9 | Sidecar19-SE]*/
62
/**
63
* Wait for progress in reference processing.
64
* return false if there is no processing reference,
65
* return true after wait the notification from the reference processing thread if currently the thread is processing references.
66
*/
67
static private native boolean waitForReferenceProcessingImpl();
68
69
/*[IF Sidecar19-SE]*/
70
static {
71
SharedSecrets.setJavaLangRefAccess(new JavaLangRefAccess() {
72
public boolean waitForReferenceProcessing() throws InterruptedException {
73
return waitForReferenceProcessingImpl();
74
}
75
76
/*[IF JAVA_SPEC_VERSION >= 11]*/
77
public void runFinalization() {
78
Finalizer.runFinalization();
79
}
80
/*[ENDIF] JAVA_SPEC_VERSION >= 11 */
81
});
82
}
83
84
/* jdk.lang.ref.disableClearBeforeEnqueue property allow reverting to the old behavior(non clear before enqueue)
85
* defer initializing the immutable variable to avoid bootstrap error
86
*/
87
static class ClearBeforeEnqueue {
88
@SuppressWarnings("boxing")
89
static final boolean ENABLED = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
90
@Override public Boolean run() {
91
return !Boolean.getBoolean("jdk.lang.ref.disableClearBeforeEnqueue"); //$NON-NLS-1$
92
}
93
});
94
}
95
96
/* The method waitForReferenceProcessing() is not used directly, just adapt for openjdk regression tests for TLS 1.3 */
97
private static boolean waitForReferenceProcessing() throws InterruptedException {
98
return waitForReferenceProcessingImpl();
99
}
100
101
/*[ELSE]
102
static {
103
SharedSecrets.setJavaLangRefAccess(new JavaLangRefAccess() {
104
public boolean tryHandlePendingReference() {
105
return waitForReferenceProcessingImpl();
106
}
107
});
108
}
109
110
/*[ENDIF]*/
111
/*[ENDIF]*/
112
113
/**
114
* Make the referent null. This does not force the reference object to be enqueued.
115
*/
116
public void clear() {
117
clearImpl();
118
}
119
120
/**
121
* set the referent to null.
122
*/
123
private void clearImpl() {
124
synchronized(this) {
125
referent = null;
126
/* change the state to cleared if it's not already cleared or enqueued */
127
if (STATE_INITIAL == state) {
128
state = STATE_CLEARED;
129
}
130
}
131
}
132
133
/**
134
* Force the reference object to be enqueued if it has been associated with a queue.
135
*
136
* @return true if Reference is enqueued, false otherwise.
137
*/
138
public boolean enqueue() {
139
/*[IF Sidecar19-SE]*/
140
if (ClearBeforeEnqueue.ENABLED) {
141
clearImpl();
142
}
143
/*[ENDIF]*/
144
return enqueueImpl();
145
}
146
147
/**
148
* Return the referent of the reference object.
149
*
150
* @return the referent to which reference refers,
151
* or null if object has been cleared.
152
*/
153
public T get() {
154
return getImpl();
155
}
156
157
private native T getImpl();
158
159
/**
160
* Return whether the reference object has been enqueued.
161
*
162
* @return true if Reference has been enqueued, false otherwise.
163
/*[IF JAVA_SPEC_VERSION >= 16]
164
*
165
* @deprecated Use ReferenceQueue or Reference.refersTo(null).
166
/*[ENDIF] JAVA_SPEC_VERSION >= 16
167
*/
168
/*[IF JAVA_SPEC_VERSION >= 16]*/
169
@Deprecated(since="16")
170
/*[ENDIF] JAVA_SPEC_VERSION >= 16 */
171
public boolean isEnqueued () {
172
synchronized(this) {
173
return state == STATE_ENQUEUED;
174
}
175
}
176
177
/**
178
* Enqueue the reference object on the associated queue.
179
*
180
* @return true if the Reference was successfully
181
* enqueued, false otherwise.
182
*/
183
boolean enqueueImpl() {
184
final ReferenceQueue tempQueue;
185
boolean result;
186
T tempReferent = referent;
187
synchronized(this) {
188
/* Static order for the following code (DO NOT CHANGE) */
189
tempQueue = queue;
190
queue = null;
191
if (state == STATE_ENQUEUED || tempQueue == null) {
192
return false;
193
}
194
result = tempQueue.enqueue(this);
195
if (result) {
196
state = STATE_ENQUEUED;
197
if (null != tempReferent) {
198
reprocess();
199
}
200
}
201
return result;
202
}
203
}
204
205
private native void reprocess();
206
207
/**
208
* Constructs a new instance of this class.
209
*/
210
Reference() {
211
}
212
213
/**
214
* Initialize a newly created reference object. Associate the
215
* reference object with the referent.
216
*
217
* @param r the referent
218
*/
219
void initReference (T r) {
220
state = STATE_INITIAL;
221
referent = r;
222
}
223
224
/**
225
* Initialize a newly created reference object. Associate the
226
* reference object with the referent, and the specified ReferenceQueue.
227
*
228
* @param r the referent
229
* @param q the ReferenceQueue
230
*/
231
void initReference (T r, ReferenceQueue q) {
232
/*[PR 101461] Reference should allow null queues */
233
queue = q;
234
state = STATE_INITIAL;
235
referent = r;
236
}
237
238
/**
239
* Called when a Reference has been removed from its ReferenceQueue.
240
* Set the enqueued field to false.
241
*/
242
void dequeue() {
243
/*[PR 112508] not synchronized, so isEnqueued() could return wrong result */
244
synchronized(this) {
245
state = STATE_CLEARED;
246
}
247
}
248
249
/*[IF Sidecar19-SE]*/
250
/**
251
* Used to keep the referenced object strongly reachable so that it is not reclaimable by garbage collection.
252
*
253
* @param ref reference of the object.
254
* @since 9
255
*/
256
public static void reachabilityFence(java.lang.Object ref) {
257
}
258
/*[ENDIF]*/
259
260
/*[IF JAVA_SPEC_VERSION >= 11]*/
261
/**
262
* This method will always throw CloneNotSupportedException. A clone of this instance will not be returned
263
* since a Reference cannot be cloned. Workaround is to create a new Reference.
264
*
265
* @throws CloneNotSupportedException always since a Reference cannot be cloned
266
*
267
* @since 11
268
*/
269
@Override
270
protected Object clone() throws CloneNotSupportedException {
271
/*[MSG "K0900", "Create a new Reference, since a Reference cannot be cloned."]*/
272
throw new CloneNotSupportedException(com.ibm.oti.util.Msg.getString("K0900")); //$NON-NLS-1$
273
}
274
/*[ENDIF] JAVA_SPEC_VERSION >= 11 */
275
276
/*[IF JAVA_SPEC_VERSION >= 16]*/
277
/**
278
* Does this object refer to {@code target}?
279
*
280
* @param target the candidate referent
281
* @return true if this object refers to {@code target}
282
* @since 16
283
*/
284
public final native boolean refersTo(T target);
285
286
/*[ENDIF] JAVA_SPEC_VERSION >= 16 */
287
}
288
289