Skip to content

Commit

Permalink
Address review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
mcimadamore committed May 31, 2024
1 parent b37f9cc commit 3b2a338
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ public VarHandle dereferenceHandle(boolean adapt) {
String.format("Path does not select a value layout: %s", breadcrumbs()));
}

VarHandle handle = Utils.makeSegmentViewVarHandle(valueLayout);
VarHandle handle = Utils.makeRawSegmentViewVarHandle(valueLayout);
handle = MethodHandles.collectCoordinates(handle, 1, offsetHandle());

// we only have to check the alignment of the root layout for the first dereference we do,
Expand Down
20 changes: 17 additions & 3 deletions src/java.base/share/classes/jdk/internal/foreign/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import java.lang.foreign.AddressLayout;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemoryLayout.PathElement;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.StructLayout;
import java.lang.foreign.ValueLayout;
Expand Down Expand Up @@ -89,15 +90,28 @@ public static MemorySegment alignUp(MemorySegment ms, long alignment) {
return ms.asSlice(alignUp(offset, alignment) - offset);
}

public static VarHandle makeSegmentViewVarHandle(ValueLayout layout) {
/**
* This method returns a <em>raw var handle</em>, that is, a var handle that does not perform any size
* or alignment checks. Such checks are added (using adaptation) by {@link LayoutPath#dereferenceHandle()}.
* <p>
* We provide two level of caching of the generated var handles. First, the var handle associated
* to a {@link ValueLayout#varHandle()} call is cached inside a stable field of the value layout implementation.
* This optimizes common code idioms like {@code JAVA_INT.varHandle().getInt(...)}. A second layer of caching
* is then provided by this method: after all, var handles constructed by {@link MemoryLayout#varHandle(PathElement...)}
* will be obtained by adapting some raw var handle generated by this method.
*
* @param layout the value layout for which a raw memory segment var handle is to be created.
* @return a raw memory segment var handle.
*/
public static VarHandle makeRawSegmentViewVarHandle(ValueLayout layout) {
final class VarHandleCache {
private static final Map<ValueLayout, VarHandle> HANDLE_MAP = new ConcurrentHashMap<>();
}
return VarHandleCache.HANDLE_MAP
.computeIfAbsent(layout.withoutName(), Utils::makeSegmentViewVarHandleInternal);
.computeIfAbsent(layout.withoutName(), Utils::makeRawSegmentViewVarHandleInternal);
}

private static VarHandle makeSegmentViewVarHandleInternal(ValueLayout layout) {
private static VarHandle makeRawSegmentViewVarHandleInternal(ValueLayout layout) {
Class<?> baseCarrier = layout.carrier();
if (layout.carrier() == MemorySegment.class) {
baseCarrier = switch ((int) ValueLayout.ADDRESS.byteSize()) {
Expand Down

0 comments on commit 3b2a338

Please sign in to comment.