Skip to content

Commit

Permalink
Merge pull request #28 from jdmpapin/vh-mhtable-cas
Browse files Browse the repository at this point in the history
Initialize VarHandle.methodHandleTable and its entries with atomic CAS
  • Loading branch information
keithc-ca authored Feb 28, 2024
2 parents cdc12a5 + 3c4bd5d commit 658edbf
Showing 1 changed file with 26 additions and 2 deletions.
28 changes: 26 additions & 2 deletions src/java.base/share/classes/java/lang/invoke/VarHandle.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
* questions.
*/

/*
* ===========================================================================
* (c) Copyright IBM Corp. 2024, 2024 All Rights Reserved
* ===========================================================================
*/

package java.lang.invoke;

import java.lang.constant.ClassDesc;
Expand All @@ -35,6 +41,7 @@
import java.util.Objects;
import java.util.Optional;

import jdk.internal.misc.Unsafe;
import jdk.internal.vm.annotation.DontInline;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.IntrinsicCandidate;
Expand Down Expand Up @@ -2198,15 +2205,32 @@ public Optional<VarHandleDesc> describeConstable() {
@Stable
MethodHandle[] methodHandleTable;

private static final long METHOD_HANDLE_TABLE_OFFSET;

static {
METHOD_HANDLE_TABLE_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class, "methodHandleTable");
}

@ForceInline
final MethodHandle getMethodHandle(int mode) {
MethodHandle[] mhTable = methodHandleTable;
if (mhTable == null) {
mhTable = methodHandleTable = new MethodHandle[AccessMode.COUNT];
mhTable = new MethodHandle[AccessMode.COUNT];
Object other = UNSAFE.compareAndExchangeReference(this, METHOD_HANDLE_TABLE_OFFSET, null, mhTable);
if (other != null) {
// We lost the race. Use the winning table instead.
mhTable = (MethodHandle[])other;
}
}
MethodHandle mh = mhTable[mode];
if (mh == null) {
mh = mhTable[mode] = getMethodHandleUncached(mode);
mh = getMethodHandleUncached(mode);
long offset = Unsafe.ARRAY_OBJECT_BASE_OFFSET + (Unsafe.ARRAY_OBJECT_INDEX_SCALE * mode);
Object other = UNSAFE.compareAndExchangeReference(mhTable, offset, null, mh);
if (other != null) {
// We lost the race. Use the winning handle instead.
mh = (MethodHandle)other;
}
}
return mh;
}
Expand Down

0 comments on commit 658edbf

Please sign in to comment.