@@ -388,6 +388,22 @@ void unpark() {
388
388
389
389
// TODO(lukes): Investigate using a @Contended annotation on these fields once one is available.
390
390
391
+ /*
392
+ * The following fields are package-private, even though we intend never to use them outside this
393
+ * file. If they were instead private, then we wouldn't be able to access them reflectively from
394
+ * within VarHandleAtomicHelper.
395
+ *
396
+ * Package-private "shouldn't" be necessary: VarHandleAtomicHelper and AbstractFutureState
397
+ * "should" be nestmates, so a call to MethodHandles.lookup inside VarHandleAtomicHelper "should"
398
+ * have access to AbstractFutureState's private fields. However, our open-source build uses
399
+ * `-source 8 -target 8`, so the class files from that build can't express nestmates. Thus, when
400
+ * those class files are used from Java 9 or higher (i.e., high enough to trigger the VarHandle
401
+ * code path), such a lookup would fail with an IllegalAccessException.
402
+ *
403
+ * This same problem is one of the reasons for us to likewise keep the fields in Waiter as
404
+ * package-private instead of private.
405
+ */
406
+
391
407
/**
392
408
* This field encodes the current state of the future.
393
409
*
@@ -403,13 +419,13 @@ void unpark() {
403
419
* argument.
404
420
* </ul>
405
421
*/
406
- private volatile @ Nullable Object valueField ;
422
+ volatile @ Nullable Object valueField ;
407
423
408
424
/** All listeners. */
409
- private volatile @ Nullable Listener listenersField ;
425
+ volatile @ Nullable Listener listenersField ;
410
426
411
427
/** All waiting threads. */
412
- private volatile @ Nullable Waiter waitersField ;
428
+ volatile @ Nullable Waiter waitersField ;
413
429
414
430
/** Non-volatile write of the thread to the {@link Waiter#thread} field. */
415
431
private static void putThread (Waiter waiter , Thread newValue ) {
@@ -553,7 +569,7 @@ private static final class VarHandleAtomicHelper extends AtomicHelper {
553
569
static final VarHandle valueUpdater ;
554
570
555
571
static {
556
- MethodHandles .Lookup lookup = methodHandlesLookupFromWithinAbstractFutureState ();
572
+ MethodHandles .Lookup lookup = MethodHandles . lookup ();
557
573
try {
558
574
waiterThreadUpdater = lookup .findVarHandle (Waiter .class , "thread" , Thread .class );
559
575
waiterNextUpdater = lookup .findVarHandle (Waiter .class , "next" , Waiter .class );
@@ -610,28 +626,6 @@ private static LinkageError newLinkageError(Throwable cause) {
610
626
}
611
627
}
612
628
613
- /**
614
- * Returns the result of calling {@link MethodHandles#lookup} from inside {@link
615
- * AbstractFutureState}. By virtue of being created there, it has access to the private fields of
616
- * {@link AbstractFutureState}, so that access is available to anyone who calls this
617
- * method—specifically, to {@link VarHandleAtomicHelper}.
618
- *
619
- * <p>This "shouldn't" be necessary: {@link VarHandleAtomicHelper} and {@link AbstractFutureState}
620
- * "should" be nestmates, so a call to {@link MethodHandles#lookup} inside {@link
621
- * VarHandleAtomicHelper} "should" have access to each other's private fields. However, our
622
- * open-source build uses {@code -source 8 -target 8}, so the class files from that build can't
623
- * express nestmates. Thus, when those class files are used from Java 9 or higher (i.e., high
624
- * enough to trigger the {@link VarHandle} code path), such a lookup would fail with an {@link
625
- * IllegalAccessException}.
626
- *
627
- * <p>Note that we do not have a similar problem with the fields in {@link Waiter} because those
628
- * fields are not private. (We could solve the problem with {@link AbstractFutureState} fields in
629
- * the same way if we wanted.)
630
- */
631
- private static MethodHandles .Lookup methodHandlesLookupFromWithinAbstractFutureState () {
632
- return MethodHandles .lookup ();
633
- }
634
-
635
629
/**
636
630
* {@link AtomicHelper} based on {@link sun.misc.Unsafe}.
637
631
*
@@ -734,13 +728,13 @@ private static final class AtomicReferenceFieldUpdaterAtomicHelper extends Atomi
734
728
Waiter .class , Waiter .class , "next" );
735
729
private static final AtomicReferenceFieldUpdater <
736
730
? super AbstractFutureState <?>, @ Nullable Waiter >
737
- waitersUpdater = waitersUpdaterFromWithinAbstractFutureState ( );
731
+ waitersUpdater = newUpdater ( AbstractFutureState . class , Waiter . class , "waitersField" );
738
732
private static final AtomicReferenceFieldUpdater <
739
733
? super AbstractFutureState <?>, @ Nullable Listener >
740
- listenersUpdater = listenersUpdaterFromWithinAbstractFutureState ( );
734
+ listenersUpdater = newUpdater ( AbstractFutureState . class , Listener . class , "listenersField" );
741
735
private static final AtomicReferenceFieldUpdater <
742
736
? super AbstractFutureState <?>, @ Nullable Object >
743
- valueUpdater = valueUpdaterFromWithinAbstractFutureState ( );
737
+ valueUpdater = newUpdater ( AbstractFutureState . class , Object . class , "valueField" );
744
738
745
739
@ Override
746
740
void putThread (Waiter waiter , Thread newValue ) {
@@ -780,39 +774,6 @@ boolean casValue(AbstractFutureState<?> future, @Nullable Object expect, Object
780
774
}
781
775
}
782
776
783
- /**
784
- * Returns an {@link AtomicReferenceFieldUpdater} for {@link #waiters}.
785
- *
786
- * <p>The creation of the updater has to happen directly inside {@link AbstractFutureState}, as
787
- * discussed in {@link #methodHandlesLookupFromWithinAbstractFutureState}.
788
- */
789
- private static AtomicReferenceFieldUpdater <? super AbstractFutureState <?>, @ Nullable Waiter >
790
- waitersUpdaterFromWithinAbstractFutureState () {
791
- return newUpdater (AbstractFutureState .class , Waiter .class , "waitersField" );
792
- }
793
-
794
- /**
795
- * Returns an {@link AtomicReferenceFieldUpdater} for {@link #listeners}.
796
- *
797
- * <p>The creation of the updater has to happen directly inside {@link AbstractFutureState}, as
798
- * discussed in {@link #methodHandlesLookupFromWithinAbstractFutureState}.
799
- */
800
- private static AtomicReferenceFieldUpdater <? super AbstractFutureState <?>, @ Nullable Listener >
801
- listenersUpdaterFromWithinAbstractFutureState () {
802
- return newUpdater (AbstractFutureState .class , Listener .class , "listenersField" );
803
- }
804
-
805
- /**
806
- * Returns an {@link AtomicReferenceFieldUpdater} for {@link #value}.
807
- *
808
- * <p>The creation of the updater has to happen directly inside {@link AbstractFutureState}, as
809
- * discussed in {@link #methodHandlesLookupFromWithinAbstractFutureState}.
810
- */
811
- private static AtomicReferenceFieldUpdater <? super AbstractFutureState <?>, @ Nullable Object >
812
- valueUpdaterFromWithinAbstractFutureState () {
813
- return newUpdater (AbstractFutureState .class , Object .class , "valueField" );
814
- }
815
-
816
777
/**
817
778
* {@link AtomicHelper} based on {@code synchronized} and volatile writes.
818
779
*
0 commit comments