2323 * questions.
2424 */
2525
26+ /*
27+ * ===========================================================================
28+ * (c) Copyright IBM Corp. 2024, 2024 All Rights Reserved
29+ * ===========================================================================
30+ */
31+
2632package java .lang .invoke ;
2733
2834import jdk .internal .HotSpotIntrinsicCandidate ;
35+ import jdk .internal .misc .Unsafe ;
2936import jdk .internal .util .Preconditions ;
3037import jdk .internal .vm .annotation .ForceInline ;
3138import jdk .internal .vm .annotation .Stable ;
@@ -1964,11 +1971,22 @@ static class TypesAndInvokers {
19641971 new MethodHandle [AccessMode .values ().length ];
19651972 }
19661973
1974+ private static final long TYPES_AND_INVOKERS_OFFSET ;
1975+
1976+ static {
1977+ TYPES_AND_INVOKERS_OFFSET = UNSAFE .objectFieldOffset (VarHandle .class , "typesAndInvokers" );
1978+ }
1979+
19671980 @ ForceInline
19681981 private final TypesAndInvokers getTypesAndInvokers () {
19691982 TypesAndInvokers tis = typesAndInvokers ;
19701983 if (tis == null ) {
1971- tis = typesAndInvokers = new TypesAndInvokers ();
1984+ tis = new TypesAndInvokers ();
1985+ Object other = UNSAFE .compareAndExchangeObject (this , TYPES_AND_INVOKERS_OFFSET , null , tis );
1986+ if (other != null ) {
1987+ // Lost the race, so use what was set by winning thread.
1988+ tis = (TypesAndInvokers ) other ;
1989+ }
19721990 }
19731991 return tis ;
19741992 }
@@ -1978,7 +1996,13 @@ final MethodHandle getMethodHandle(int mode) {
19781996 TypesAndInvokers tis = getTypesAndInvokers ();
19791997 MethodHandle mh = tis .methodHandle_table [mode ];
19801998 if (mh == null ) {
1981- mh = tis .methodHandle_table [mode ] = getMethodHandleUncached (mode );
1999+ mh = getMethodHandleUncached (mode );
2000+ long offset = Unsafe .ARRAY_OBJECT_BASE_OFFSET + (Unsafe .ARRAY_OBJECT_INDEX_SCALE * mode );
2001+ Object other = UNSAFE .compareAndExchangeObject (tis .methodHandle_table , offset , null , mh );
2002+ if (other != null ) {
2003+ // We lost the race. Use the winning thread's handle instead.
2004+ mh = (MethodHandle ) other ;
2005+ }
19822006 }
19832007 return mh ;
19842008 }
0 commit comments