Skip to content

Commit

Permalink
Merge pull request #759 from nbhuiyan/vh-cas
Browse files Browse the repository at this point in the history
Use Unsafe.compareAndExchange for writing to Stable field and array
  • Loading branch information
keithc-ca authored Feb 29, 2024
2 parents 9f480ba + 33eb270 commit f0a7818
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,9 +23,16 @@
* questions.
*/

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

package java.lang.invoke;

import jdk.internal.HotSpotIntrinsicCandidate;
import jdk.internal.misc.Unsafe;
import jdk.internal.util.Preconditions;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.Stable;
Expand Down Expand Up @@ -1964,11 +1971,22 @@ static class TypesAndInvokers {
new MethodHandle[AccessMode.values().length];
}

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.compareAndExchangeObject(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 @@ -1978,7 +1996,13 @@ final 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.compareAndExchangeObject(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 f0a7818

Please sign in to comment.