8333236: Test java/foreign/TestAccessModes.java is timing out after passing

Reviewed-by: jvernee
This commit is contained in:
Maurizio Cimadamore 2024-05-31 17:53:35 +00:00
parent e650bdf465
commit e99f6a65a8
2 changed files with 27 additions and 3 deletions

View File

@ -205,7 +205,7 @@ public class LayoutPath {
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,

View File

@ -28,6 +28,7 @@ package jdk.internal.foreign;
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;
@ -37,6 +38,8 @@ import java.lang.invoke.MethodType;
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;
@ -87,7 +90,28 @@ public final class Utils {
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
* with 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::makeRawSegmentViewVarHandleInternal);
}
private static VarHandle makeRawSegmentViewVarHandleInternal(ValueLayout layout) {
Class<?> baseCarrier = layout.carrier();
if (layout.carrier() == MemorySegment.class) {
baseCarrier = switch ((int) ValueLayout.ADDRESS.byteSize()) {
@ -108,7 +132,7 @@ public final class Utils {
handle = MethodHandles.filterValue(handle,
MethodHandles.explicitCastArguments(ADDRESS_TO_LONG, MethodType.methodType(baseCarrier, MemorySegment.class)),
MethodHandles.explicitCastArguments(MethodHandles.insertArguments(LONG_TO_ADDRESS, 1,
pointeeByteSize(addressLayout), pointeeByteAlign(addressLayout)),
pointeeByteSize(addressLayout), pointeeByteAlign(addressLayout)),
MethodType.methodType(MemorySegment.class, baseCarrier)));
}
return handle;