Skip to content

Commit

Permalink
Cache both nested and toplevel var handles
Browse files Browse the repository at this point in the history
  • Loading branch information
mcimadamore committed May 10, 2024
1 parent 0500824 commit 43eded4
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
20 changes: 20 additions & 0 deletions src/java.base/share/classes/jdk/internal/foreign/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import java.lang.invoke.VarHandle;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;

import jdk.internal.access.SharedSecrets;
Expand Down Expand Up @@ -88,6 +90,24 @@ public static MemorySegment alignUp(MemorySegment ms, long alignment) {
}

public static VarHandle makeSegmentViewVarHandle(ValueLayout layout, boolean nested) {
final class VarHandleCache {
private static final Map<ValueLayout, VarHandle> HANDLE_MAP_TOPLEVEL = new ConcurrentHashMap<>();
private static final Map<ValueLayout, VarHandle> HANDLE_MAP_NESTED = new ConcurrentHashMap<>();
}
return nested ?
VarHandleCache.HANDLE_MAP_NESTED.computeIfAbsent(layout.withoutName(), Utils::makeNestedSegmentViewVarHandle) :
VarHandleCache.HANDLE_MAP_TOPLEVEL.computeIfAbsent(layout.withoutName(), Utils::makeToplevelSegmentViewVarHandle);
}

private static VarHandle makeToplevelSegmentViewVarHandle(ValueLayout layout) {
return makeSegmentViewVarHandleInternal(layout, false);
}

private static VarHandle makeNestedSegmentViewVarHandle(ValueLayout layout) {
return makeSegmentViewVarHandleInternal(layout, true);
}

private static VarHandle makeSegmentViewVarHandleInternal(ValueLayout layout, boolean nested) {
Class<?> baseCarrier = layout.carrier();
if (layout.carrier() == MemorySegment.class) {
baseCarrier = switch ((int) ValueLayout.ADDRESS.byteSize()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,9 @@ static boolean isValidCarrier(Class<?> carrier) {

@ForceInline
public final VarHandle varHandle() {
final class VarHandleCache {
private static final Map<ValueLayout, VarHandle> HANDLE_MAP = new ConcurrentHashMap<>();
}
if (handle == null) {
// this store to stable field is safe, because return value of 'makeMemoryAccessVarHandle' has stable identity
handle = VarHandleCache.HANDLE_MAP
.computeIfAbsent(withoutName(), l -> Utils.makeSegmentViewVarHandle(l, false));
handle = Utils.makeSegmentViewVarHandle((ValueLayout) this, false);
}
return handle;
}
Expand Down

0 comments on commit 43eded4

Please sign in to comment.