Skip to content

Commit

Permalink
Merge pull request #325 from nbhuiyan/vh-cas
Browse files Browse the repository at this point in the history
Use Unsafe.compareAndSwap for writing to Stable field and array
  • Loading branch information
keithc-ca committed Feb 28, 2024
2 parents bf83787 + f7d6940 commit 76b191b
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 @@ -39,6 +45,7 @@
import java.util.function.BiFunction;
import java.util.function.Function;

import jdk.internal.misc.Unsafe;
import jdk.internal.util.Preconditions;
import jdk.internal.vm.annotation.DontInline;
import jdk.internal.vm.annotation.ForceInline;
Expand Down Expand Up @@ -2140,11 +2147,22 @@ static class TypesAndInvokers {
MethodHandle[] methodHandle_table = new MethodHandle[AccessMode.COUNT];
}

private static final long TYPES_AND_INVOKERS_OFFSET;

static {
TYPES_AND_INVOKERS_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class, "typesAndInvokers");
}

@ForceInline
private final TypesAndInvokers getTypesAndInvokers() {
TypesAndInvokers tis = typesAndInvokers;
if (tis == null) {
tis = typesAndInvokers = new TypesAndInvokers();
tis = new TypesAndInvokers();
Object other = UNSAFE.compareAndExchangeReference(this, TYPES_AND_INVOKERS_OFFSET, null, tis);
if (other != null) {
// Lost the race, so use what was set by winning thread.
tis = (TypesAndInvokers) other;
}
}
return tis;
}
Expand All @@ -2154,7 +2172,13 @@ MethodHandle getMethodHandle(int mode) {
TypesAndInvokers tis = getTypesAndInvokers();
MethodHandle mh = tis.methodHandle_table[mode];
if (mh == null) {
mh = tis.methodHandle_table[mode] = getMethodHandleUncached(mode);
mh = getMethodHandleUncached(mode);
long offset = Unsafe.ARRAY_OBJECT_BASE_OFFSET + (Unsafe.ARRAY_OBJECT_INDEX_SCALE * mode);
Object other = UNSAFE.compareAndExchangeReference(tis.methodHandle_table, offset, null, mh);
if (other != null) {
// We lost the race. Use the winning thread's handle instead.
mh = (MethodHandle) other;
}
}
return mh;
}
Expand Down

0 comments on commit 76b191b

Please sign in to comment.