< prev index next >

src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java

Print this page
*** 52,10 ***
--- 52,11 ---
  import java.lang.foreign.StructLayout;
  import java.lang.foreign.UnionLayout;
  import java.lang.foreign.ValueLayout;
  import java.lang.invoke.MethodHandle;
  import java.lang.invoke.MethodType;
+ import java.util.HashSet;
  import java.util.List;
  import java.nio.ByteOrder;
  import java.util.Objects;
  import java.util.Set;
  

*** 71,10 ***
--- 72,11 ---
      }
  
      private record LinkRequest(FunctionDescriptor descriptor, LinkerOptions options) {}
      private final SoftReferenceCache<LinkRequest, MethodHandle> DOWNCALL_CACHE = new SoftReferenceCache<>();
      private final SoftReferenceCache<LinkRequest, UpcallStubFactory> UPCALL_CACHE = new SoftReferenceCache<>();
+     private final Set<MemoryLayout> CANONICAL_LAYOUTS_CACHE = new HashSet<>(canonicalLayouts().values());
  
      @Override
      @CallerSensitive
      public final MethodHandle downcallHandle(MemorySegment symbol, FunctionDescriptor function, Option... options) {
          Reflection.ensureNativeAccess(Reflection.getCallerClass(), Linker.class, "downcallHandle");

*** 87,11 ***
      public final MethodHandle downcallHandle(FunctionDescriptor function, Option... options) {
          Reflection.ensureNativeAccess(Reflection.getCallerClass(), Linker.class, "downcallHandle");
          return downcallHandle0(function, options);
      }
  
!     private final MethodHandle downcallHandle0(FunctionDescriptor function, Option... options) {
          Objects.requireNonNull(function);
          Objects.requireNonNull(options);
          checkLayouts(function);
          function = stripNames(function);
          LinkerOptions optionSet = LinkerOptions.forDowncall(function, options);
--- 89,11 ---
      public final MethodHandle downcallHandle(FunctionDescriptor function, Option... options) {
          Reflection.ensureNativeAccess(Reflection.getCallerClass(), Linker.class, "downcallHandle");
          return downcallHandle0(function, options);
      }
  
!     private MethodHandle downcallHandle0(FunctionDescriptor function, Option... options) {
          Objects.requireNonNull(function);
          Objects.requireNonNull(options);
          checkLayouts(function);
          function = stripNames(function);
          LinkerOptions optionSet = LinkerOptions.forDowncall(function, options);

*** 211,40 ***
              checkLayoutRecursive(sl.elementLayout());
          }
      }
  
      // check for trailing padding
!     private static void checkGroupSize(GroupLayout gl, long maxUnpaddedOffset) {
          long expectedSize = Utils.alignUp(maxUnpaddedOffset, gl.byteAlignment());
          if (gl.byteSize() != expectedSize) {
              throw new IllegalArgumentException("Layout '" + gl + "' has unexpected size: "
                      + gl.byteSize() + " != " + expectedSize);
          }
      }
  
      // checks both that there is no excess padding between 'memberLayout' and
      // the previous layout
!     private static void checkMemberOffset(StructLayout parent, MemoryLayout memberLayout,
                                            long lastUnpaddedOffset, long offset) {
          long expectedOffset = Utils.alignUp(lastUnpaddedOffset, memberLayout.byteAlignment());
          if (expectedOffset != offset) {
              throw new IllegalArgumentException("Member layout '" + memberLayout + "', of '" + parent + "'" +
                      " found at unexpected offset: " + offset + " != " + expectedOffset);
          }
      }
  
!     private static void checkSupported(ValueLayout valueLayout) {
          valueLayout = valueLayout.withoutName();
          if (valueLayout instanceof AddressLayout addressLayout) {
              valueLayout = addressLayout.withoutTargetLayout();
          }
!         if (!SUPPORTED_LAYOUTS.contains(valueLayout.withoutName())) {
              throw new IllegalArgumentException("Unsupported layout: " + valueLayout);
          }
      }
  
!     private static void checkHasNaturalAlignment(MemoryLayout layout) {
          if (!((AbstractLayout<?>) layout).hasNaturalAlignment()) {
              throw new IllegalArgumentException("Layout alignment must be natural alignment: " + layout);
          }
      }
  
--- 213,40 ---
              checkLayoutRecursive(sl.elementLayout());
          }
      }
  
      // check for trailing padding
!     private void checkGroupSize(GroupLayout gl, long maxUnpaddedOffset) {
          long expectedSize = Utils.alignUp(maxUnpaddedOffset, gl.byteAlignment());
          if (gl.byteSize() != expectedSize) {
              throw new IllegalArgumentException("Layout '" + gl + "' has unexpected size: "
                      + gl.byteSize() + " != " + expectedSize);
          }
      }
  
      // checks both that there is no excess padding between 'memberLayout' and
      // the previous layout
!     private void checkMemberOffset(StructLayout parent, MemoryLayout memberLayout,
                                            long lastUnpaddedOffset, long offset) {
          long expectedOffset = Utils.alignUp(lastUnpaddedOffset, memberLayout.byteAlignment());
          if (expectedOffset != offset) {
              throw new IllegalArgumentException("Member layout '" + memberLayout + "', of '" + parent + "'" +
                      " found at unexpected offset: " + offset + " != " + expectedOffset);
          }
      }
  
!     private void checkSupported(ValueLayout valueLayout) {
          valueLayout = valueLayout.withoutName();
          if (valueLayout instanceof AddressLayout addressLayout) {
              valueLayout = addressLayout.withoutTargetLayout();
          }
!         if (!CANONICAL_LAYOUTS_CACHE.contains(valueLayout.withoutName())) {
              throw new IllegalArgumentException("Unsupported layout: " + valueLayout);
          }
      }
  
!     private void checkHasNaturalAlignment(MemoryLayout layout) {
          if (!((AbstractLayout<?>) layout).hasNaturalAlignment()) {
              throw new IllegalArgumentException("Layout alignment must be natural alignment: " + layout);
          }
      }
  

*** 271,18 ***
      private static FunctionDescriptor stripNames(FunctionDescriptor function) {
          return function.returnLayout()
                  .map(rl -> FunctionDescriptor.of(stripNames(rl), stripNames(function.argumentLayouts())))
                  .orElseGet(() -> FunctionDescriptor.ofVoid(stripNames(function.argumentLayouts())));
      }
- 
-     private static final Set<MemoryLayout> SUPPORTED_LAYOUTS = Set.of(
-             ValueLayout.JAVA_BOOLEAN,
-             ValueLayout.JAVA_BYTE,
-             ValueLayout.JAVA_CHAR,
-             ValueLayout.JAVA_SHORT,
-             ValueLayout.JAVA_INT,
-             ValueLayout.JAVA_FLOAT,
-             ValueLayout.JAVA_LONG,
-             ValueLayout.JAVA_DOUBLE,
-             ValueLayout.ADDRESS
-     );
  }
--- 273,6 ---
< prev index next >