< prev index next >

src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/sysv/CallArranger.java

Print this page

 53 import static jdk.internal.foreign.abi.x64.X86_64Architecture.*;
 54 import static jdk.internal.foreign.abi.x64.sysv.SysVx64Linker.MAX_INTEGER_ARGUMENT_REGISTERS;
 55 import static jdk.internal.foreign.abi.x64.sysv.SysVx64Linker.MAX_VECTOR_ARGUMENT_REGISTERS;
 56 
 57 /**
 58  * For the SysV x64 C ABI specifically, this class uses the ProgrammableInvoker API, namely CallingSequenceBuilder2
 59  * to translate a C FunctionDescriptor into a CallingSequence, which can then be turned into a MethodHandle.
 60  *
 61  * This includes taking care of synthetic arguments like pointers to return buffers for 'in-memory' returns.
 62  */
 63 public class CallArranger {
 64     private static final ABIDescriptor CSysV = X86_64Architecture.abiFor(
 65         new VMStorage[] { rdi, rsi, rdx, rcx, r8, r9, rax },
 66         new VMStorage[] { xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 },
 67         new VMStorage[] { rax, rdx },
 68         new VMStorage[] { xmm0, xmm1 },
 69         2,
 70         new VMStorage[] { r10, r11 },
 71         new VMStorage[] { xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 },
 72         16,
 73         0 //no shadow space


 74     );
 75 
 76     // record
 77     public static class Bindings {
 78         public final CallingSequence callingSequence;
 79         public final boolean isInMemoryReturn;
 80         public final int nVectorArgs;
 81 
 82         Bindings(CallingSequence callingSequence, boolean isInMemoryReturn, int nVectorArgs) {
 83             this.callingSequence = callingSequence;
 84             this.isInMemoryReturn = isInMemoryReturn;
 85             this.nVectorArgs = nVectorArgs;
 86         }
 87     }
 88 
 89     public static Bindings getBindings(MethodType mt, FunctionDescriptor cDesc, boolean forUpcall) {
 90         CallingSequenceBuilder csb = new CallingSequenceBuilder(forUpcall);
 91 
 92         BindingCalculator argCalc = forUpcall ? new BoxBindingCalculator(true) : new UnboxBindingCalculator(true);
 93         BindingCalculator retCalc = forUpcall ? new UnboxBindingCalculator(false) : new BoxBindingCalculator(false);
 94 
 95         boolean returnInMemory = isInMemoryReturn(cDesc.returnLayout());
 96         if (returnInMemory) {
 97             Class<?> carrier = MemoryAddress.class;
 98             MemoryLayout layout = SysV.C_POINTER;
 99             csb.addArgumentBindings(carrier, layout, argCalc.getBindings(carrier, layout));
100         } else if (cDesc.returnLayout().isPresent()) {
101             Class<?> carrier = mt.returnType();
102             MemoryLayout layout = cDesc.returnLayout().get();
103             csb.setReturnBindings(carrier, layout, retCalc.getBindings(carrier, layout));
104         }
105 
106         for (int i = 0; i < mt.parameterCount(); i++) {
107             Class<?> carrier = mt.parameterType(i);
108             MemoryLayout layout = cDesc.argumentLayouts().get(i);
109             csb.addArgumentBindings(carrier, layout, argCalc.getBindings(carrier, layout));
110         }

221                     return nVectorReg;
222                 default:
223                     throw new IllegalStateException();
224             }
225         }
226 
227         void incrementRegisterCount(int type) {
228             switch (type) {
229                 case StorageClasses.INTEGER:
230                     nIntegerReg++;
231                     break;
232                 case StorageClasses.VECTOR:
233                     nVectorReg++;
234                     break;
235                 default:
236                     throw new IllegalStateException();
237             }
238         }
239     }
240 
241     abstract static class BindingCalculator {
242         protected final StorageCalculator storageCalculator;
243 
244         protected BindingCalculator(boolean forArguments) {
245             this.storageCalculator = new StorageCalculator(forArguments);
246         }
247 
248         abstract List<Binding> getBindings(Class<?> carrier, MemoryLayout layout);
249     }
250 
251     static class UnboxBindingCalculator extends BindingCalculator {
252 
253         UnboxBindingCalculator(boolean forArguments) {
254             super(forArguments);
255         }
256 
257         @Override
258         List<Binding> getBindings(Class<?> carrier, MemoryLayout layout) {
259             TypeClass argumentClass = TypeClass.classifyLayout(layout);
260             Binding.Builder bindings = Binding.builder();
261             switch (argumentClass.kind()) {

 53 import static jdk.internal.foreign.abi.x64.X86_64Architecture.*;
 54 import static jdk.internal.foreign.abi.x64.sysv.SysVx64Linker.MAX_INTEGER_ARGUMENT_REGISTERS;
 55 import static jdk.internal.foreign.abi.x64.sysv.SysVx64Linker.MAX_VECTOR_ARGUMENT_REGISTERS;
 56 
 57 /**
 58  * For the SysV x64 C ABI specifically, this class uses the ProgrammableInvoker API, namely CallingSequenceBuilder2
 59  * to translate a C FunctionDescriptor into a CallingSequence, which can then be turned into a MethodHandle.
 60  *
 61  * This includes taking care of synthetic arguments like pointers to return buffers for 'in-memory' returns.
 62  */
 63 public class CallArranger {
 64     private static final ABIDescriptor CSysV = X86_64Architecture.abiFor(
 65         new VMStorage[] { rdi, rsi, rdx, rcx, r8, r9, rax },
 66         new VMStorage[] { xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 },
 67         new VMStorage[] { rax, rdx },
 68         new VMStorage[] { xmm0, xmm1 },
 69         2,
 70         new VMStorage[] { r10, r11 },
 71         new VMStorage[] { xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 },
 72         16,
 73         0, //no shadow space
 74         r10, // target addr reg
 75         r11  // ret buf addr reg
 76     );
 77 
 78     // record
 79     public static class Bindings {
 80         public final CallingSequence callingSequence;
 81         public final boolean isInMemoryReturn;
 82         public final int nVectorArgs;
 83 
 84         Bindings(CallingSequence callingSequence, boolean isInMemoryReturn, int nVectorArgs) {
 85             this.callingSequence = callingSequence;
 86             this.isInMemoryReturn = isInMemoryReturn;
 87             this.nVectorArgs = nVectorArgs;
 88         }
 89     }
 90 
 91     public static Bindings getBindings(MethodType mt, FunctionDescriptor cDesc, boolean forUpcall) {
 92         CallingSequenceBuilder csb = new CallingSequenceBuilder(CSysV, forUpcall);
 93 
 94         BindingCalculator argCalc = forUpcall ? new BoxBindingCalculator(true) : new UnboxBindingCalculator(true);
 95         BindingCalculator retCalc = forUpcall ? new UnboxBindingCalculator(false) : new BoxBindingCalculator(false);
 96 
 97         boolean returnInMemory = isInMemoryReturn(cDesc.returnLayout());
 98         if (returnInMemory) {
 99             Class<?> carrier = MemoryAddress.class;
100             MemoryLayout layout = SysV.C_POINTER;
101             csb.addArgumentBindings(carrier, layout, argCalc.getBindings(carrier, layout));
102         } else if (cDesc.returnLayout().isPresent()) {
103             Class<?> carrier = mt.returnType();
104             MemoryLayout layout = cDesc.returnLayout().get();
105             csb.setReturnBindings(carrier, layout, retCalc.getBindings(carrier, layout));
106         }
107 
108         for (int i = 0; i < mt.parameterCount(); i++) {
109             Class<?> carrier = mt.parameterType(i);
110             MemoryLayout layout = cDesc.argumentLayouts().get(i);
111             csb.addArgumentBindings(carrier, layout, argCalc.getBindings(carrier, layout));
112         }

223                     return nVectorReg;
224                 default:
225                     throw new IllegalStateException();
226             }
227         }
228 
229         void incrementRegisterCount(int type) {
230             switch (type) {
231                 case StorageClasses.INTEGER:
232                     nIntegerReg++;
233                     break;
234                 case StorageClasses.VECTOR:
235                     nVectorReg++;
236                     break;
237                 default:
238                     throw new IllegalStateException();
239             }
240         }
241     }
242 
243     static abstract class BindingCalculator {
244         protected final StorageCalculator storageCalculator;
245 
246         protected BindingCalculator(boolean forArguments) {
247             this.storageCalculator = new StorageCalculator(forArguments);
248         }
249 
250         abstract List<Binding> getBindings(Class<?> carrier, MemoryLayout layout);
251     }
252 
253     static class UnboxBindingCalculator extends BindingCalculator {
254 
255         UnboxBindingCalculator(boolean forArguments) {
256             super(forArguments);
257         }
258 
259         @Override
260         List<Binding> getBindings(Class<?> carrier, MemoryLayout layout) {
261             TypeClass argumentClass = TypeClass.classifyLayout(layout);
262             Binding.Builder bindings = Binding.builder();
263             switch (argumentClass.kind()) {
< prev index next >