< prev index next >

src/java.base/share/classes/jdk/internal/foreign/abi/x64/sysv/SysVx64ABI.java

Print this page

        

@@ -31,24 +31,30 @@
 
 import java.foreign.Library;
 import java.foreign.NativeMethodType;
 import java.foreign.NativeTypes;
 import java.foreign.Scope;
-import java.foreign.layout.*;
 import java.foreign.memory.LayoutType;
 import java.foreign.memory.Pointer;
 import java.foreign.memory.Struct;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.WrongMethodTypeException;
 import java.util.*;
+import java.util.function.Function;
 
 import static sun.security.action.GetPropertyAction.privilegedGetProperty;
 
 /**
  * ABI implementation based on System V ABI AMD64 supplement v.0.99.6
  */
 public class SysVx64ABI implements SystemABI {
+    public static final int MAX_INTEGER_ARGUMENT_REGISTERS = 6;
+    public static final int MAX_INTEGER_RETURN_REGISTERS = 2;
+    public static final int MAX_VECTOR_ARGUMENT_REGISTERS = 8;
+    public static final int MAX_VECTOR_RETURN_REGISTERS = 2;
+    public static final int MAX_X87_RETURN_REGISTERS = 2;
+
     private static final String fastPath = privilegedGetProperty("jdk.internal.foreign.NativeInvoker.FASTPATH");
     private static SysVx64ABI instance;
 
     public static SysVx64ABI getInstance() {
         if (instance == null) {

@@ -58,43 +64,52 @@
     }
 
     @Override
     public MethodHandle downcallHandle(CallingConvention cc, Library.Symbol symbol, NativeMethodType nmt) {
         if (nmt.isVarArgs()) {
-            return VarargsInvokerImpl.make(symbol, nmt);
+            return VarargsInvoker.make(symbol, nmt, CallingSequenceBuilderImpl::new, adapter);
         }
 
-        StandardCall sc = new StandardCall();
-        CallingSequence callingSequence = sc.arrangeCall(nmt);
-
+        CallingSequence callingSequence = arrangeCall(nmt);
         if (fastPath == null || !fastPath.equals("none")) {
             if (DirectSignatureShuffler.acceptDowncall(nmt, callingSequence)) {
                 return DirectNativeInvoker.make(symbol, callingSequence, nmt);
             } else if (fastPath != null && fastPath.equals("direct")) {
                 throw new IllegalStateException(
                         String.format("No fast path for: %s", symbol.getName()));
             }
         }
-        return UniversalNativeInvokerImpl.make(symbol, callingSequence, nmt).getBoundMethodHandle();
+        try {
+            return new UniversalNativeInvoker(symbol, callingSequence, nmt,
+                    adapter).getBoundMethodHandle();
+        } catch (IllegalAccessException ex) {
+            throw new IllegalStateException(ex);
+        }
     }
 
     @Override
     public Library.Symbol upcallStub(CallingConvention cc, MethodHandle target, NativeMethodType nmt) {
         if (!target.type().equals(nmt.methodType())) {
             throw new WrongMethodTypeException("Native method type has wrong type: " + nmt.methodType());
         }
-        StandardCall sc = new StandardCall();
-        CallingSequence callingSequence = sc.arrangeCall(nmt);
+        CallingSequence callingSequence = arrangeCall(nmt);
         if (fastPath == null || !fastPath.equals("none")) {
             if (DirectSignatureShuffler.acceptUpcall(nmt, callingSequence)) {
                 return UpcallStubs.registerUpcallStub(new DirectUpcallHandler(target, callingSequence, nmt));
             } else if (fastPath != null && fastPath.equals("direct")) {
                 throw new IllegalStateException(
                         String.format("No fast path for function type %s", nmt.function()));
             }
         }
-        return UpcallStubs.registerUpcallStub(new UniversalUpcallHandlerImpl(target, callingSequence, nmt));
+        return UpcallStubs.registerUpcallStub(new UniversalUpcallHandler(target, callingSequence, nmt,
+                adapter));
+    }
+
+    CallingSequence arrangeCall(NativeMethodType nmt) {
+        CallingSequenceBuilder stdc = new CallingSequenceBuilderImpl(nmt.function().returnLayout().orElse(null));
+        nmt.function().argumentLayouts().forEach(stdc::addArgument);
+        return stdc.build();
     }
 
     private static final Map<String, CallingConvention> SysVCallingConventions = new HashMap<>();
     private static final CallingConvention CV_C = () -> "C";
 

@@ -119,31 +134,33 @@
     @Override
     public Collection<CallingConvention> callingConventions() {
         return Collections.unmodifiableCollection(SysVCallingConventions.values());
     }
 
-    static void unboxValue(Object o, LayoutType<?> type, java.util.function.Function<ArgumentBinding, Pointer<?>> dstPtrFunc,
+    UniversalAdapter adapter = new UniversalAdapter() {
+        @Override
+        public void unboxValue(Object o, LayoutType<?> type, java.util.function.Function<ArgumentBinding, Pointer<?>> dstPtrFunc,
                            List<ArgumentBinding> bindings) throws Throwable {
         if (o instanceof Struct) {
             Struct<?> struct = (Struct<?>) o;
             if (struct.ptr().type().bytesSize() != 0) {
                 Pointer<Long> src = Util.unsafeCast(struct.ptr(), NativeTypes.UINT64);
                 for (ArgumentBinding binding : bindings) {
                     Pointer<?> dst = dstPtrFunc.apply(binding);
-                    Pointer<Long> srcPtr = src.offset(binding.getOffset() / NativeTypes.UINT64.bytesSize());
-                    Pointer.copy(srcPtr, dst, binding.getStorage().getSize());
+                        Pointer<Long> srcPtr = src.offset(binding.offset() / NativeTypes.UINT64.bytesSize());
+                        Pointer.copy(srcPtr, dst, binding.storage().getSize());
                 }
             }
         } else {
             assert bindings.size() <= 2;
             Pointer<?> dst = Util.unsafeCast(dstPtrFunc.apply(bindings.get(0)), type);
             dst.type().setter().invoke(dst, o);
         }
     }
 
     @SuppressWarnings("unchecked")
-    static Object boxValue(LayoutType<?> type, java.util.function.Function<ArgumentBinding, Pointer<?>> srcPtrFunc,
+        public Object boxValue(LayoutType<?> type, java.util.function.Function<ArgumentBinding, Pointer<?>> srcPtrFunc,
                            List<ArgumentBinding> bindings) throws IllegalAccessException {
         Class<?> carrier = ((LayoutTypeImpl<?>)type).carrier();
         if (Util.isCStruct(carrier)) {
             /*
              * Leak memory for now

@@ -157,17 +174,18 @@
 
             @SuppressWarnings({"rawtypes", "unchecked"})
             Pointer<?> rtmp = ((ScopeImpl)scope).allocate(type, 8);
 
             for (ArgumentBinding binding : bindings) {
-                Pointer<Long> dst = Util.unsafeCast(rtmp, NativeTypes.UINT64).offset(binding.getOffset() / NativeTypes.UINT64.bytesSize());
-                Pointer.copy(srcPtrFunc.apply(binding), dst, binding.getStorage().getSize());
+                    Pointer<Long> dst = Util.unsafeCast(rtmp, NativeTypes.UINT64).offset(binding.offset() / NativeTypes.UINT64.bytesSize());
+                    Pointer.copy(srcPtrFunc.apply(binding), dst, binding.storage().getSize());
             }
 
             return rtmp.get();
         } else {
             assert bindings.size() <= 2;
             return Util.unsafeCast(srcPtrFunc.apply(bindings.get(0)), type).get();
         }
     }
+    };
 }
 
< prev index next >