Skip to content

Commit e84e685

Browse files
authored
Merge pull request #132 from jdmpapin/vh-mhtable-cas
Initialize VarHandle.methodHandleTable and its entries with atomic CAS
2 parents d7906f4 + 1a13ab0 commit e84e685

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

src/java.base/share/classes/java/lang/invoke/VarHandle.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
* questions.
2424
*/
2525

26+
/*
27+
* ===========================================================================
28+
* (c) Copyright IBM Corp. 2024, 2024 All Rights Reserved
29+
* ===========================================================================
30+
*/
31+
2632
package java.lang.invoke;
2733

2834
import java.lang.constant.ClassDesc;
@@ -35,6 +41,7 @@
3541
import java.util.Objects;
3642
import java.util.Optional;
3743

44+
import jdk.internal.misc.Unsafe;
3845
import jdk.internal.vm.annotation.DontInline;
3946
import jdk.internal.vm.annotation.ForceInline;
4047
import jdk.internal.vm.annotation.IntrinsicCandidate;
@@ -2173,15 +2180,32 @@ public Optional<VarHandleDesc> describeConstable() {
21732180
@Stable
21742181
MethodHandle[] methodHandleTable;
21752182

2183+
private static final long METHOD_HANDLE_TABLE_OFFSET;
2184+
2185+
static {
2186+
METHOD_HANDLE_TABLE_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class, "methodHandleTable");
2187+
}
2188+
21762189
@ForceInline
21772190
final MethodHandle getMethodHandle(int mode) {
21782191
MethodHandle[] mhTable = methodHandleTable;
21792192
if (mhTable == null) {
2180-
mhTable = methodHandleTable = new MethodHandle[AccessMode.COUNT];
2193+
mhTable = new MethodHandle[AccessMode.COUNT];
2194+
Object other = UNSAFE.compareAndExchangeReference(this, METHOD_HANDLE_TABLE_OFFSET, null, mhTable);
2195+
if (other != null) {
2196+
// We lost the race. Use the winning table instead.
2197+
mhTable = (MethodHandle[])other;
2198+
}
21812199
}
21822200
MethodHandle mh = mhTable[mode];
21832201
if (mh == null) {
2184-
mh = mhTable[mode] = getMethodHandleUncached(mode);
2202+
mh = getMethodHandleUncached(mode);
2203+
long offset = Unsafe.ARRAY_OBJECT_BASE_OFFSET + (Unsafe.ARRAY_OBJECT_INDEX_SCALE * mode);
2204+
Object other = UNSAFE.compareAndExchangeReference(mhTable, offset, null, mh);
2205+
if (other != null) {
2206+
// We lost the race. Use the winning handle instead.
2207+
mh = (MethodHandle)other;
2208+
}
21852209
}
21862210
return mh;
21872211
}

0 commit comments

Comments
 (0)