@@ -100,10 +100,10 @@ public abstract class Reference<T> {
100
100
* [active/unregistered] [1]
101
101
*
102
102
* Transitions:
103
- * clear
103
+ * clear [2]
104
104
* [active/registered] -------> [inactive/registered]
105
105
* | |
106
- * | | enqueue [2]
106
+ * | | enqueue
107
107
* | GC enqueue [2] |
108
108
* | -----------------|
109
109
* | |
@@ -114,7 +114,7 @@ public abstract class Reference<T> {
114
114
* v | |
115
115
* [pending/enqueued] --- |
116
116
* | | poll/remove
117
- * | poll/remove |
117
+ * | poll/remove | + clear [4]
118
118
* | |
119
119
* v ReferenceHandler v
120
120
* [pending/dequeued] ------> [inactive/dequeued]
@@ -140,12 +140,14 @@ public abstract class Reference<T> {
140
140
* [1] Unregistered is not permitted for FinalReferences.
141
141
*
142
142
* [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 .
145
145
*
146
146
* [3] The garbage collector may directly transition a Reference
147
147
* from [active/unregistered] to [inactive/unregistered],
148
148
* bypassing the pending-Reference list.
149
+ *
150
+ * [4] The queue handler for FinalReferences also clears the reference.
149
151
*/
150
152
151
153
private T referent ; /* Treated specially by GC */
@@ -342,22 +344,6 @@ public T get() {
342
344
return this .referent ;
343
345
}
344
346
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
-
361
347
/**
362
348
* Tests if the referent of this reference object is {@code obj}.
363
349
* Using a {@code null} {@code obj} returns {@code true} if the
@@ -383,6 +369,41 @@ public final boolean refersTo(T obj) {
383
369
* clears references it does so directly, without invoking this method.
384
370
*/
385
371
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
386
407
this .referent = null ;
387
408
}
388
409
@@ -413,7 +434,7 @@ public boolean isEnqueued() {
413
434
* it was not registered with a queue when it was created
414
435
*/
415
436
public boolean enqueue () {
416
- this . referent = null ;
437
+ clear0 (); // Intentionally clear0() rather than clear()
417
438
return this .queue .enqueue (this );
418
439
}
419
440
0 commit comments