< prev index next >

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

Print this page

        

*** 24,44 **** package jdk.internal.foreign.abi; import java.foreign.Library; import java.foreign.NativeMethodType; import java.foreign.NativeTypes; - import java.foreign.Scope; import java.foreign.memory.LayoutType; import java.foreign.memory.Pointer; import java.lang.invoke.MethodHandle; import java.util.Arrays; - import java.util.List; - import java.util.function.Function; import jdk.internal.foreign.ScopeImpl; import jdk.internal.foreign.Util; ! import jdk.internal.foreign.abi.x64.SharedConstants; import jdk.internal.foreign.memory.MemoryBoundInfo; import jdk.internal.foreign.memory.BoundedPointer; import jdk.internal.vm.annotation.Stable; import static sun.security.action.GetBooleanAction.privilegedGetProperty; --- 24,41 ---- package jdk.internal.foreign.abi; import java.foreign.Library; import java.foreign.NativeMethodType; import java.foreign.NativeTypes; import java.foreign.memory.LayoutType; import java.foreign.memory.Pointer; import java.lang.invoke.MethodHandle; import java.util.Arrays; import jdk.internal.foreign.ScopeImpl; import jdk.internal.foreign.Util; ! import jdk.internal.foreign.abi.x64.SharedUtils; import jdk.internal.foreign.memory.MemoryBoundInfo; import jdk.internal.foreign.memory.BoundedPointer; import jdk.internal.vm.annotation.Stable; import static sun.security.action.GetBooleanAction.privilegedGetProperty;
*** 46,67 **** /** * This class implements upcall invocation from native code through a so called 'universal adapter'. A universal upcall adapter * takes an array of storage pointers, which describes the state of the CPU at the time of the upcall. This can be used * by the Java code to fetch the upcall arguments and to store the results to the desired location, as per system ABI. */ ! public abstract class UniversalUpcallHandler implements Library.Symbol { private static final boolean DEBUG = privilegedGetProperty("jdk.internal.foreign.UpcallHandler.DEBUG"); @Stable private final MethodHandle mh; private final NativeMethodType nmt; private final CallingSequence callingSequence; private final Pointer<?> entryPoint; ! protected UniversalUpcallHandler(MethodHandle target, CallingSequence callingSequence, NativeMethodType nmt) { mh = target.asSpreader(Object[].class, nmt.parameterCount()); this.nmt = nmt; this.callingSequence = callingSequence; this.entryPoint = BoundedPointer.createNativeVoidPointer(allocateUpcallStub()); } --- 43,67 ---- /** * This class implements upcall invocation from native code through a so called 'universal adapter'. A universal upcall adapter * takes an array of storage pointers, which describes the state of the CPU at the time of the upcall. This can be used * by the Java code to fetch the upcall arguments and to store the results to the desired location, as per system ABI. */ ! public class UniversalUpcallHandler implements Library.Symbol { private static final boolean DEBUG = privilegedGetProperty("jdk.internal.foreign.UpcallHandler.DEBUG"); @Stable private final MethodHandle mh; private final NativeMethodType nmt; private final CallingSequence callingSequence; private final Pointer<?> entryPoint; + private final UniversalAdapter adapter; ! public UniversalUpcallHandler(MethodHandle target, CallingSequence callingSequence, NativeMethodType nmt, ! UniversalAdapter adapter) { ! this.adapter = adapter; mh = target.asSpreader(Object[].class, nmt.parameterCount()); this.nmt = nmt; this.callingSequence = callingSequence; this.entryPoint = BoundedPointer.createNativeVoidPointer(allocateUpcallStub()); }
*** 98,130 **** this.vectorReturns = BoundedPointer.createRegisterPointer(NativeTypes.UINT64, vectorReturn, true); this.x87Returns = BoundedPointer.createRegisterPointer(NativeTypes.UINT64, x87Returns, true); } Pointer<Long> getPtr(ArgumentBinding binding) { ! Storage storage = binding.getStorage(); switch (storage.getStorageClass()) { case INTEGER_ARGUMENT_REGISTER: return integers.offset(storage.getStorageIndex()); case VECTOR_ARGUMENT_REGISTER: ! return vectors.offset(storage.getStorageIndex() * SharedConstants.VECTOR_REGISTER_SIZE / 8); case STACK_ARGUMENT_SLOT: return stack.offset(storage.getStorageIndex()); case INTEGER_RETURN_REGISTER: return integerReturns.offset(storage.getStorageIndex()); case VECTOR_RETURN_REGISTER: ! return vectorReturns.offset(storage.getStorageIndex() * SharedConstants.VECTOR_REGISTER_SIZE / 8); case X87_RETURN_REGISTER: ! return x87Returns.offset(storage.getStorageIndex() * SharedConstants.X87_REGISTER_SIZE / 8); default: throw new Error("Unhandled storage: " + storage); } } @SuppressWarnings("unchecked") Pointer<Object> inMemoryPtr() { assert callingSequence.returnsInMemory(); ! Pointer<Long> res = getPtr(callingSequence.getReturnBindings().get(0)); long structAddr = res.get(); long size = Util.alignUp(nmt.returnType().bytesSize(), 8); return new BoundedPointer<Object>((LayoutType)nmt.returnType(), ScopeImpl.UNCHECKED, Pointer.AccessMode.READ_WRITE, MemoryBoundInfo.ofNative(structAddr, size)); } --- 98,130 ---- this.vectorReturns = BoundedPointer.createRegisterPointer(NativeTypes.UINT64, vectorReturn, true); this.x87Returns = BoundedPointer.createRegisterPointer(NativeTypes.UINT64, x87Returns, true); } Pointer<Long> getPtr(ArgumentBinding binding) { ! Storage storage = binding.storage(); switch (storage.getStorageClass()) { case INTEGER_ARGUMENT_REGISTER: return integers.offset(storage.getStorageIndex()); case VECTOR_ARGUMENT_REGISTER: ! return vectors.offset(storage.getStorageIndex() * SharedUtils.VECTOR_REGISTER_SIZE / 8); case STACK_ARGUMENT_SLOT: return stack.offset(storage.getStorageIndex()); case INTEGER_RETURN_REGISTER: return integerReturns.offset(storage.getStorageIndex()); case VECTOR_RETURN_REGISTER: ! return vectorReturns.offset(storage.getStorageIndex() * SharedUtils.VECTOR_REGISTER_SIZE / 8); case X87_RETURN_REGISTER: ! return x87Returns.offset(storage.getStorageIndex() * SharedUtils.X87_REGISTER_SIZE / 8); default: throw new Error("Unhandled storage: " + storage); } } @SuppressWarnings("unchecked") Pointer<Object> inMemoryPtr() { assert callingSequence.returnsInMemory(); ! Pointer<Long> res = getPtr(callingSequence.returnInMemoryBinding()); long structAddr = res.get(); long size = Util.alignUp(nmt.returnType().bytesSize(), 8); return new BoundedPointer<Object>((LayoutType)nmt.returnType(), ScopeImpl.UNCHECKED, Pointer.AccessMode.READ_WRITE, MemoryBoundInfo.ofNative(structAddr, size)); }
*** 141,153 **** result.append("In memory pointer:\n".indent(2)); result.append(inMemoryPtr().toString().indent(4)); } for (StorageClass cls : StorageClass.values()) { result.append((cls + "\n").indent(2)); ! for (ArgumentBinding binding : callingSequence.getBindings(cls)) { BoundedPointer<?> argPtr = (BoundedPointer<?>) getPtr(binding); ! result.append(argPtr.dump((int) binding.getStorage().getSize()).indent(4)); } } return result.toString(); } } --- 141,153 ---- result.append("In memory pointer:\n".indent(2)); result.append(inMemoryPtr().toString().indent(4)); } for (StorageClass cls : StorageClass.values()) { result.append((cls + "\n").indent(2)); ! for (ArgumentBinding binding : callingSequence.bindings(cls)) { BoundedPointer<?> argPtr = (BoundedPointer<?>) getPtr(binding); ! result.append(argPtr.dump((int) binding.storage().getSize()).indent(4)); } } return result.toString(); } }
*** 161,171 **** System.err.println(context.asString()); } Object[] args = new Object[nmt.parameterCount()]; for (int i = 0 ; i < nmt.parameterCount() ; i++) { ! args[i] = boxValue(nmt.parameterType(i), context::getPtr, callingSequence.getArgumentBindings(i)); } if (DEBUG) { System.err.println("Java arguments:"); System.err.println(Arrays.toString(args).indent(2)); --- 161,171 ---- System.err.println(context.asString()); } Object[] args = new Object[nmt.parameterCount()]; for (int i = 0 ; i < nmt.parameterCount() ; i++) { ! args[i] = adapter.boxValue(nmt.parameterType(i), context::getPtr, callingSequence.argumentBindings(i)); } if (DEBUG) { System.err.println("Java arguments:"); System.err.println(Arrays.toString(args).indent(2));
*** 178,189 **** System.err.println(o.toString().indent(2)); } if (mh.type().returnType() != void.class) { if (!callingSequence.returnsInMemory()) { ! unboxValue(o, nmt.returnType(), context::getPtr, ! callingSequence.getReturnBindings()); } else { Pointer<Object> inMemPtr = context.inMemoryPtr(); inMemPtr.set(o); context.setReturnPtr(inMemPtr.addr()); // Write to RAX } --- 178,189 ---- System.err.println(o.toString().indent(2)); } if (mh.type().returnType() != void.class) { if (!callingSequence.returnsInMemory()) { ! adapter.unboxValue(o, nmt.returnType(), context::getPtr, ! callingSequence.returnBindings()); } else { Pointer<Object> inMemPtr = context.inMemoryPtr(); inMemPtr.set(o); context.setReturnPtr(inMemPtr.addr()); // Write to RAX }
*** 196,211 **** } catch (Throwable t) { throw new IllegalStateException(t); } } - public abstract void unboxValue(Object o, LayoutType<?> type, Function<ArgumentBinding, - Pointer<?>> dstPtrFunc, List<ArgumentBinding> bindings) throws Throwable; - - public abstract Object boxValue(LayoutType<?> type, Function<ArgumentBinding, - Pointer<?>> srcPtrFunc, List<ArgumentBinding> bindings) throws IllegalAccessException; - public native long allocateUpcallStub(); private static native void registerNatives(); static { registerNatives(); --- 196,205 ----
< prev index next >