8303684: Lift upcall sharing mechanism to AbstractLinker (mainline)
Reviewed-by: mcimadamore
This commit is contained in:
parent
dfc7214a3e
commit
d4eb395335
src/java.base/share/classes/jdk/internal/foreign/abi
AbstractLinker.javaBindingSpecializer.javaDowncallLinker.javaSharedUtils.javaUpcallLinker.java
aarch64
riscv64/linux
x64
test/micro/org/openjdk/bench/java/lang/foreign
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -45,10 +45,16 @@ import java.lang.invoke.MethodType;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract sealed class AbstractLinker implements Linker permits LinuxAArch64Linker, MacOsAArch64Linker,
|
||||
SysVx64Linker, WindowsAArch64Linker, Windowsx64Linker, LinuxRISCV64Linker {
|
||||
SysVx64Linker, WindowsAArch64Linker,
|
||||
Windowsx64Linker, LinuxRISCV64Linker {
|
||||
|
||||
public interface UpcallStubFactory {
|
||||
MemorySegment makeStub(MethodHandle target, SegmentScope arena);
|
||||
}
|
||||
|
||||
private record LinkRequest(FunctionDescriptor descriptor, LinkerOptions options) {}
|
||||
private final SoftReferenceCache<LinkRequest, MethodHandle> DOWNCALL_CACHE = new SoftReferenceCache<>();
|
||||
private final SoftReferenceCache<FunctionDescriptor, UpcallStubFactory> UPCALL_CACHE = new SoftReferenceCache<>();
|
||||
|
||||
@Override
|
||||
public MethodHandle downcallHandle(FunctionDescriptor function, Option... options) {
|
||||
@ -79,11 +85,12 @@ public abstract sealed class AbstractLinker implements Linker permits LinuxAArch
|
||||
if (!type.equals(target.type())) {
|
||||
throw new IllegalArgumentException("Wrong method handle type: " + target.type());
|
||||
}
|
||||
return arrangeUpcall(target, target.type(), function, scope);
|
||||
|
||||
UpcallStubFactory factory = UPCALL_CACHE.get(function, f -> arrangeUpcall(type, f));
|
||||
return factory.makeStub(target, scope);
|
||||
}
|
||||
|
||||
protected abstract MemorySegment arrangeUpcall(MethodHandle target, MethodType targetType,
|
||||
FunctionDescriptor function, SegmentScope scope);
|
||||
protected abstract UpcallStubFactory arrangeUpcall(MethodType targetType, FunctionDescriptor function);
|
||||
|
||||
@Override
|
||||
public SystemLookup defaultLookup() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -126,8 +126,6 @@ public class BindingSpecializer {
|
||||
|
||||
private static final String SUPER_NAME = OBJECT_INTRN;
|
||||
|
||||
private static final SoftReferenceCache<FunctionDescriptor, MethodHandle> UPCALL_WRAPPER_CACHE = new SoftReferenceCache<>();
|
||||
|
||||
// Instance fields start here
|
||||
private final MethodVisitor mv;
|
||||
private final MethodType callerMethodType;
|
||||
@ -157,16 +155,7 @@ public class BindingSpecializer {
|
||||
this.leafType = leafType;
|
||||
}
|
||||
|
||||
static MethodHandle specialize(MethodHandle leafHandle, CallingSequence callingSequence, ABIDescriptor abi) {
|
||||
if (callingSequence.forUpcall()) {
|
||||
MethodHandle wrapper = UPCALL_WRAPPER_CACHE.get(callingSequence.functionDesc(), fd -> specializeUpcall(leafHandle, callingSequence, abi));
|
||||
return MethodHandles.insertArguments(wrapper, 0, leafHandle); // lazily customized for leaf handle instances
|
||||
} else {
|
||||
return specializeDowncall(leafHandle, callingSequence, abi);
|
||||
}
|
||||
}
|
||||
|
||||
private static MethodHandle specializeDowncall(MethodHandle leafHandle, CallingSequence callingSequence, ABIDescriptor abi) {
|
||||
static MethodHandle specializeDowncall(MethodHandle leafHandle, CallingSequence callingSequence, ABIDescriptor abi) {
|
||||
MethodType callerMethodType = callingSequence.callerMethodType();
|
||||
if (callingSequence.needsReturnBuffer()) {
|
||||
callerMethodType = callerMethodType.dropParameterTypes(0, 1); // Return buffer does not appear in the parameter list
|
||||
@ -183,11 +172,11 @@ public class BindingSpecializer {
|
||||
}
|
||||
}
|
||||
|
||||
private static MethodHandle specializeUpcall(MethodHandle leafHandle, CallingSequence callingSequence, ABIDescriptor abi) {
|
||||
static MethodHandle specializeUpcall(MethodType targetType, CallingSequence callingSequence, ABIDescriptor abi) {
|
||||
MethodType callerMethodType = callingSequence.callerMethodType();
|
||||
callerMethodType = callerMethodType.insertParameterTypes(0, MethodHandle.class); // target
|
||||
|
||||
byte[] bytes = specializeHelper(leafHandle.type(), callerMethodType, callingSequence, abi);
|
||||
byte[] bytes = specializeHelper(targetType, callerMethodType, callingSequence, abi);
|
||||
|
||||
try {
|
||||
// For upcalls, we must initialize the class since the upcall stubs don't have a clinit barrier,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -91,7 +91,7 @@ public class DowncallLinker {
|
||||
MethodHandle handle = JLIA.nativeMethodHandle(nep);
|
||||
|
||||
if (USE_SPEC) {
|
||||
handle = BindingSpecializer.specialize(handle, callingSequence, abi);
|
||||
handle = BindingSpecializer.specializeDowncall(handle, callingSequence, abi);
|
||||
} else {
|
||||
Map<VMStorage, Integer> argIndexMap = SharedUtils.indexMap(argMoves);
|
||||
Map<VMStorage, Integer> retIndexMap = SharedUtils.indexMap(retMoves);
|
||||
@ -198,4 +198,3 @@ public class DowncallLinker {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ import jdk.internal.access.JavaLangAccess;
|
||||
import jdk.internal.access.JavaLangInvokeAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.foreign.CABI;
|
||||
import jdk.internal.foreign.abi.AbstractLinker.UpcallStubFactory;
|
||||
import jdk.internal.foreign.abi.aarch64.linux.LinuxAArch64Linker;
|
||||
import jdk.internal.foreign.abi.aarch64.macos.MacOsAArch64Linker;
|
||||
import jdk.internal.foreign.abi.aarch64.windows.WindowsAArch64Linker;
|
||||
@ -137,7 +138,7 @@ public final class SharedUtils {
|
||||
* @param target the target handle to adapt
|
||||
* @return the adapted handle
|
||||
*/
|
||||
public static MethodHandle adaptUpcallForIMR(MethodHandle target, boolean dropReturn) {
|
||||
private static MethodHandle adaptUpcallForIMR(MethodHandle target, boolean dropReturn) {
|
||||
if (target.type().returnType() != MemorySegment.class)
|
||||
throw new IllegalArgumentException("Must return MemorySegment for IMR");
|
||||
|
||||
@ -154,6 +155,27 @@ public final class SharedUtils {
|
||||
return target;
|
||||
}
|
||||
|
||||
public static UpcallStubFactory arrangeUpcallHelper(MethodType targetType, boolean isInMemoryReturn, boolean dropReturn,
|
||||
ABIDescriptor abi, CallingSequence callingSequence) {
|
||||
if (isInMemoryReturn) {
|
||||
// simulate the adaptation to get the type
|
||||
MethodHandle fakeTarget = MethodHandles.empty(targetType);
|
||||
targetType = adaptUpcallForIMR(fakeTarget, dropReturn).type();
|
||||
}
|
||||
|
||||
UpcallStubFactory factory = UpcallLinker.makeFactory(targetType, abi, callingSequence);
|
||||
|
||||
if (isInMemoryReturn) {
|
||||
final UpcallStubFactory finalFactory = factory;
|
||||
factory = (target, scope) -> {
|
||||
target = adaptUpcallForIMR(target, dropReturn);
|
||||
return finalFactory.makeStub(target, scope);
|
||||
};
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
private static MemorySegment bufferCopy(MemorySegment dest, MemorySegment buffer) {
|
||||
return dest.copyFrom(buffer);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
package jdk.internal.foreign.abi;
|
||||
|
||||
import jdk.internal.foreign.abi.AbstractLinker.UpcallStubFactory;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
import java.lang.foreign.MemorySegment;
|
||||
@ -35,6 +36,7 @@ import java.lang.invoke.MethodType;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.lang.invoke.MethodHandles.exactInvoker;
|
||||
@ -55,23 +57,27 @@ public class UpcallLinker {
|
||||
try {
|
||||
MethodHandles.Lookup lookup = lookup();
|
||||
MH_invokeInterpBindings = lookup.findStatic(UpcallLinker.class, "invokeInterpBindings",
|
||||
methodType(Object.class, Object[].class, InvocationData.class));
|
||||
methodType(Object.class, MethodHandle.class, Object[].class, InvocationData.class));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static MemorySegment make(ABIDescriptor abi, MethodHandle target, CallingSequence callingSequence, SegmentScope scope) {
|
||||
public static UpcallStubFactory makeFactory(MethodType targetType, ABIDescriptor abi, CallingSequence callingSequence) {
|
||||
assert callingSequence.forUpcall();
|
||||
Binding.VMLoad[] argMoves = argMoveBindings(callingSequence);
|
||||
Binding.VMStore[] retMoves = retMoveBindings(callingSequence);
|
||||
|
||||
MethodType llType = callingSequence.callerMethodType();
|
||||
|
||||
MethodHandle doBindings;
|
||||
UnaryOperator<MethodHandle> doBindingsMaker;
|
||||
if (USE_SPEC) {
|
||||
doBindings = BindingSpecializer.specialize(target, callingSequence, abi);
|
||||
assert doBindings.type() == llType;
|
||||
MethodHandle doBindings = BindingSpecializer.specializeUpcall(targetType, callingSequence, abi);
|
||||
doBindingsMaker = target -> {
|
||||
MethodHandle handle = MethodHandles.insertArguments(doBindings, 0, target);
|
||||
assert handle.type() == llType;
|
||||
return handle;
|
||||
};
|
||||
} else {
|
||||
Map<VMStorage, Integer> argIndices = SharedUtils.indexMap(argMoves);
|
||||
Map<VMStorage, Integer> retIndices = SharedUtils.indexMap(retMoves);
|
||||
@ -79,21 +85,29 @@ public class UpcallLinker {
|
||||
if (callingSequence.needsReturnBuffer()) {
|
||||
spreaderCount--; // return buffer is dropped from the argument list
|
||||
}
|
||||
target = target.asSpreader(Object[].class, spreaderCount);
|
||||
InvocationData invData = new InvocationData(target, argIndices, retIndices, callingSequence, retMoves, abi);
|
||||
doBindings = insertArguments(MH_invokeInterpBindings, 1, invData);
|
||||
doBindings = doBindings.asCollector(Object[].class, llType.parameterCount());
|
||||
doBindings = doBindings.asType(llType);
|
||||
final int finalSpreaderCount = spreaderCount;
|
||||
InvocationData invData = new InvocationData(argIndices, retIndices, callingSequence, retMoves, abi);
|
||||
MethodHandle doBindings = insertArguments(MH_invokeInterpBindings, 2, invData);
|
||||
doBindingsMaker = target -> {
|
||||
target = target.asSpreader(Object[].class, finalSpreaderCount);
|
||||
MethodHandle handle = MethodHandles.insertArguments(doBindings, 0, target);
|
||||
handle = handle.asCollector(Object[].class, llType.parameterCount());
|
||||
return handle.asType(llType);
|
||||
};
|
||||
}
|
||||
|
||||
checkPrimitive(doBindings.type());
|
||||
doBindings = insertArguments(exactInvoker(doBindings.type()), 0, doBindings);
|
||||
VMStorage[] args = Arrays.stream(argMoves).map(Binding.Move::storage).toArray(VMStorage[]::new);
|
||||
VMStorage[] rets = Arrays.stream(retMoves).map(Binding.Move::storage).toArray(VMStorage[]::new);
|
||||
CallRegs conv = new CallRegs(args, rets);
|
||||
long entryPoint = makeUpcallStub(doBindings, abi, conv,
|
||||
callingSequence.needsReturnBuffer(), callingSequence.returnBufferSize());
|
||||
return UpcallStubs.makeUpcall(entryPoint, scope);
|
||||
return (target, scope) -> {
|
||||
assert target.type() == targetType;
|
||||
MethodHandle doBindings = doBindingsMaker.apply(target);
|
||||
checkPrimitive(doBindings.type());
|
||||
doBindings = insertArguments(exactInvoker(doBindings.type()), 0, doBindings);
|
||||
long entryPoint = makeUpcallStub(doBindings, abi, conv,
|
||||
callingSequence.needsReturnBuffer(), callingSequence.returnBufferSize());
|
||||
return UpcallStubs.makeUpcall(entryPoint, scope);
|
||||
};
|
||||
}
|
||||
|
||||
private static void checkPrimitive(MethodType type) {
|
||||
@ -120,14 +134,13 @@ public class UpcallLinker {
|
||||
.toArray(Binding.VMStore[]::new);
|
||||
}
|
||||
|
||||
private record InvocationData(MethodHandle leaf,
|
||||
Map<VMStorage, Integer> argIndexMap,
|
||||
private record InvocationData(Map<VMStorage, Integer> argIndexMap,
|
||||
Map<VMStorage, Integer> retIndexMap,
|
||||
CallingSequence callingSequence,
|
||||
Binding.VMStore[] retMoves,
|
||||
ABIDescriptor abi) {}
|
||||
|
||||
private static Object invokeInterpBindings(Object[] lowLevelArgs, InvocationData invData) throws Throwable {
|
||||
private static Object invokeInterpBindings(MethodHandle leaf, Object[] lowLevelArgs, InvocationData invData) throws Throwable {
|
||||
Binding.Context allocator = invData.callingSequence.allocationSize() != 0
|
||||
? Binding.Context.ofBoundedAllocator(invData.callingSequence.allocationSize())
|
||||
: Binding.Context.ofScope();
|
||||
@ -154,7 +167,7 @@ public class UpcallLinker {
|
||||
}
|
||||
|
||||
// invoke our target
|
||||
Object o = invData.leaf.invoke(highLevelArgs);
|
||||
Object o = leaf.invoke(highLevelArgs);
|
||||
|
||||
if (DEBUG) {
|
||||
System.err.println("Java return:");
|
||||
@ -162,7 +175,7 @@ public class UpcallLinker {
|
||||
}
|
||||
|
||||
Object[] returnValues = new Object[invData.retIndexMap.size()];
|
||||
if (invData.leaf.type().returnType() != void.class) {
|
||||
if (leaf.type().returnType() != void.class) {
|
||||
BindingInterpreter.unbox(o, invData.callingSequence.returnBindings(),
|
||||
(storage, type, value) -> returnValues[invData.retIndexMap.get(storage)] = value, null);
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import java.lang.foreign.GroupLayout;
|
||||
import java.lang.foreign.MemoryLayout;
|
||||
import java.lang.foreign.MemorySegment;
|
||||
import jdk.internal.foreign.abi.ABIDescriptor;
|
||||
import jdk.internal.foreign.abi.AbstractLinker.UpcallStubFactory;
|
||||
import jdk.internal.foreign.abi.Binding;
|
||||
import jdk.internal.foreign.abi.CallingSequence;
|
||||
import jdk.internal.foreign.abi.CallingSequenceBuilder;
|
||||
@ -189,14 +190,11 @@ public abstract class CallArranger {
|
||||
return handle;
|
||||
}
|
||||
|
||||
public MemorySegment arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, SegmentScope session) {
|
||||
public UpcallStubFactory arrangeUpcall(MethodType mt, FunctionDescriptor cDesc) {
|
||||
Bindings bindings = getBindings(mt, cDesc, true);
|
||||
|
||||
if (bindings.isInMemoryReturn) {
|
||||
target = SharedUtils.adaptUpcallForIMR(target, true /* drop return, since we don't have bindings for it */);
|
||||
}
|
||||
|
||||
return UpcallLinker.make(abiDescriptor(), target, bindings.callingSequence, session);
|
||||
final boolean dropReturn = true; /* drop return, since we don't have bindings for it */
|
||||
return SharedUtils.arrangeUpcallHelper(mt, bindings.isInMemoryReturn, dropReturn, abiDescriptor(),
|
||||
bindings.callingSequence);
|
||||
}
|
||||
|
||||
private static boolean isInMemoryReturn(Optional<MemoryLayout> returnLayout) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2021, Arm Limited. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -31,7 +31,6 @@ import jdk.internal.foreign.abi.aarch64.CallArranger;
|
||||
|
||||
import java.lang.foreign.SegmentScope;
|
||||
import java.lang.foreign.FunctionDescriptor;
|
||||
import java.lang.foreign.MemorySegment;
|
||||
import java.lang.foreign.VaList;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodType;
|
||||
@ -61,8 +60,8 @@ public final class LinuxAArch64Linker extends AbstractLinker {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MemorySegment arrangeUpcall(MethodHandle target, MethodType targetType, FunctionDescriptor function, SegmentScope scope) {
|
||||
return CallArranger.LINUX.arrangeUpcall(target, targetType, function, scope);
|
||||
protected UpcallStubFactory arrangeUpcall(MethodType targetType, FunctionDescriptor function) {
|
||||
return CallArranger.LINUX.arrangeUpcall(targetType, function);
|
||||
}
|
||||
|
||||
public static VaList newVaList(Consumer<VaList.Builder> actions, SegmentScope scope) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, Arm Limited. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -30,7 +30,6 @@ import jdk.internal.foreign.abi.LinkerOptions;
|
||||
import jdk.internal.foreign.abi.aarch64.CallArranger;
|
||||
|
||||
import java.lang.foreign.FunctionDescriptor;
|
||||
import java.lang.foreign.MemorySegment;
|
||||
import java.lang.foreign.SegmentScope;
|
||||
import java.lang.foreign.VaList;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
@ -61,8 +60,8 @@ public final class MacOsAArch64Linker extends AbstractLinker {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MemorySegment arrangeUpcall(MethodHandle target, MethodType targetType, FunctionDescriptor function, SegmentScope scope) {
|
||||
return CallArranger.MACOS.arrangeUpcall(target, targetType, function, scope);
|
||||
protected UpcallStubFactory arrangeUpcall(MethodType targetType, FunctionDescriptor function) {
|
||||
return CallArranger.MACOS.arrangeUpcall(targetType, function);
|
||||
}
|
||||
|
||||
public static VaList newVaList(Consumer<VaList.Builder> actions, SegmentScope scope) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2021, 2022, Microsoft. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -31,7 +31,6 @@ import jdk.internal.foreign.abi.LinkerOptions;
|
||||
import jdk.internal.foreign.abi.aarch64.CallArranger;
|
||||
|
||||
import java.lang.foreign.FunctionDescriptor;
|
||||
import java.lang.foreign.MemorySegment;
|
||||
import java.lang.foreign.SegmentScope;
|
||||
import java.lang.foreign.VaList;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
@ -58,8 +57,8 @@ public final class WindowsAArch64Linker extends AbstractLinker {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MemorySegment arrangeUpcall(MethodHandle target, MethodType targetType, FunctionDescriptor function, SegmentScope scope) {
|
||||
return CallArranger.WINDOWS.arrangeUpcall(target, targetType, function, scope);
|
||||
protected UpcallStubFactory arrangeUpcall(MethodType targetType, FunctionDescriptor function) {
|
||||
return CallArranger.WINDOWS.arrangeUpcall(targetType, function);
|
||||
}
|
||||
|
||||
public static VaList newVaList(Consumer<VaList.Builder> actions, SegmentScope scope) {
|
||||
@ -76,4 +75,4 @@ public final class WindowsAArch64Linker extends AbstractLinker {
|
||||
return WindowsAArch64VaList.empty();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import java.lang.foreign.GroupLayout;
|
||||
import java.lang.foreign.MemoryLayout;
|
||||
import java.lang.foreign.MemorySegment;
|
||||
import jdk.internal.foreign.abi.ABIDescriptor;
|
||||
import jdk.internal.foreign.abi.AbstractLinker.UpcallStubFactory;
|
||||
import jdk.internal.foreign.abi.Binding;
|
||||
import jdk.internal.foreign.abi.CallingSequence;
|
||||
import jdk.internal.foreign.abi.CallingSequenceBuilder;
|
||||
@ -120,15 +121,11 @@ public class LinuxRISCV64CallArranger {
|
||||
return handle;
|
||||
}
|
||||
|
||||
public static MemorySegment arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, SegmentScope scope) {
|
||||
|
||||
public static UpcallStubFactory arrangeUpcall(MethodType mt, FunctionDescriptor cDesc) {
|
||||
Bindings bindings = getBindings(mt, cDesc, true);
|
||||
|
||||
if (bindings.isInMemoryReturn) {
|
||||
target = SharedUtils.adaptUpcallForIMR(target, true /* drop return, since we don't have bindings for it */);
|
||||
}
|
||||
|
||||
return UpcallLinker.make(CLinux, target, bindings.callingSequence, scope);
|
||||
final boolean dropReturn = true; /* drop return, since we don't have bindings for it */
|
||||
return SharedUtils.arrangeUpcallHelper(mt, bindings.isInMemoryReturn, dropReturn, CLinux,
|
||||
bindings.callingSequence);
|
||||
}
|
||||
|
||||
private static boolean isInMemoryReturn(Optional<MemoryLayout> returnLayout) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, Institute of Software, Chinese Academy of Sciences.
|
||||
* All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -57,8 +57,8 @@ public final class LinuxRISCV64Linker extends AbstractLinker {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MemorySegment arrangeUpcall(MethodHandle target, MethodType targetType, FunctionDescriptor function, SegmentScope scope) {
|
||||
return LinuxRISCV64CallArranger.arrangeUpcall(target, targetType, function, scope);
|
||||
protected UpcallStubFactory arrangeUpcall(MethodType targetType, FunctionDescriptor function) {
|
||||
return LinuxRISCV64CallArranger.arrangeUpcall(targetType, function);
|
||||
}
|
||||
|
||||
public static VaList newVaList(Consumer<VaList.Builder> actions, SegmentScope scope) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,6 +27,7 @@ package jdk.internal.foreign.abi.x64.sysv;
|
||||
|
||||
import jdk.internal.foreign.Utils;
|
||||
import jdk.internal.foreign.abi.ABIDescriptor;
|
||||
import jdk.internal.foreign.abi.AbstractLinker.UpcallStubFactory;
|
||||
import jdk.internal.foreign.abi.Binding;
|
||||
import jdk.internal.foreign.abi.CallingSequence;
|
||||
import jdk.internal.foreign.abi.CallingSequenceBuilder;
|
||||
@ -132,14 +133,11 @@ public class CallArranger {
|
||||
return handle;
|
||||
}
|
||||
|
||||
public static MemorySegment arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, SegmentScope scope) {
|
||||
public static UpcallStubFactory arrangeUpcall(MethodType mt, FunctionDescriptor cDesc) {
|
||||
Bindings bindings = getBindings(mt, cDesc, true);
|
||||
|
||||
if (bindings.isInMemoryReturn) {
|
||||
target = SharedUtils.adaptUpcallForIMR(target, true /* drop return, since we don't have bindings for it */);
|
||||
}
|
||||
|
||||
return UpcallLinker.make(CSysV, target, bindings.callingSequence, scope);
|
||||
final boolean dropReturn = true; /* drop return, since we don't have bindings for it */
|
||||
return SharedUtils.arrangeUpcallHelper(mt, bindings.isInMemoryReturn, dropReturn, CSysV,
|
||||
bindings.callingSequence);
|
||||
}
|
||||
|
||||
private static boolean isInMemoryReturn(Optional<MemoryLayout> returnLayout) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,7 +30,6 @@ import jdk.internal.foreign.abi.LinkerOptions;
|
||||
|
||||
import java.lang.foreign.SegmentScope;
|
||||
import java.lang.foreign.FunctionDescriptor;
|
||||
import java.lang.foreign.MemorySegment;
|
||||
import java.lang.foreign.VaList;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodType;
|
||||
@ -52,14 +51,15 @@ public final class SysVx64Linker extends AbstractLinker {
|
||||
private SysVx64Linker() {
|
||||
// Ensure there is only one instance
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MethodHandle arrangeDowncall(MethodType inferredMethodType, FunctionDescriptor function, LinkerOptions options) {
|
||||
return CallArranger.arrangeDowncall(inferredMethodType, function, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MemorySegment arrangeUpcall(MethodHandle target, MethodType targetType, FunctionDescriptor function, SegmentScope scope) {
|
||||
return CallArranger.arrangeUpcall(target, targetType, function, scope);
|
||||
protected UpcallStubFactory arrangeUpcall(MethodType targetType, FunctionDescriptor function) {
|
||||
return CallArranger.arrangeUpcall(targetType, function);
|
||||
}
|
||||
|
||||
public static VaList newVaList(Consumer<VaList.Builder> actions, SegmentScope scope) {
|
||||
|
@ -26,6 +26,7 @@ package jdk.internal.foreign.abi.x64.windows;
|
||||
|
||||
import jdk.internal.foreign.Utils;
|
||||
import jdk.internal.foreign.abi.ABIDescriptor;
|
||||
import jdk.internal.foreign.abi.AbstractLinker.UpcallStubFactory;
|
||||
import jdk.internal.foreign.abi.Binding;
|
||||
import jdk.internal.foreign.abi.CallingSequence;
|
||||
import jdk.internal.foreign.abi.CallingSequenceBuilder;
|
||||
@ -131,14 +132,11 @@ public class CallArranger {
|
||||
return handle;
|
||||
}
|
||||
|
||||
public static MemorySegment arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, SegmentScope scope) {
|
||||
public static UpcallStubFactory arrangeUpcall(MethodType mt, FunctionDescriptor cDesc) {
|
||||
Bindings bindings = getBindings(mt, cDesc, true);
|
||||
|
||||
if (bindings.isInMemoryReturn) {
|
||||
target = SharedUtils.adaptUpcallForIMR(target, false /* need the return value as well */);
|
||||
}
|
||||
|
||||
return UpcallLinker.make(CWindows, target, bindings.callingSequence, scope);
|
||||
final boolean dropReturn = false; /* need the return value as well */
|
||||
return SharedUtils.arrangeUpcallHelper(mt, bindings.isInMemoryReturn, dropReturn, CWindows,
|
||||
bindings.callingSequence);
|
||||
}
|
||||
|
||||
private static boolean isInMemoryReturn(Optional<MemoryLayout> returnLayout) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -58,8 +58,8 @@ public final class Windowsx64Linker extends AbstractLinker {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MemorySegment arrangeUpcall(MethodHandle target, MethodType targetType, FunctionDescriptor function, SegmentScope scope) {
|
||||
return CallArranger.arrangeUpcall(target, targetType, function, scope);
|
||||
protected UpcallStubFactory arrangeUpcall(MethodType targetType, FunctionDescriptor function) {
|
||||
return CallArranger.arrangeUpcall(targetType, function);
|
||||
}
|
||||
|
||||
public static VaList newVaList(Consumer<VaList.Builder> actions, SegmentScope scope) {
|
||||
@ -76,4 +76,3 @@ public final class Windowsx64Linker extends AbstractLinker {
|
||||
return WinVaList.empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ import java.lang.foreign.Linker;
|
||||
import java.lang.foreign.FunctionDescriptor;
|
||||
import java.lang.foreign.MemorySegment;
|
||||
import java.lang.foreign.SegmentScope;
|
||||
import java.lang.foreign.Arena;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -64,7 +65,9 @@ public class LinkUpcall extends CLayouts {
|
||||
|
||||
@Benchmark
|
||||
public MemorySegment link_blank() {
|
||||
return LINKER.upcallStub(BLANK, BLANK_DESC, SegmentScope.auto());
|
||||
try (Arena arena = Arena.openConfined()) {
|
||||
return LINKER.upcallStub(BLANK, BLANK_DESC, arena.scope());
|
||||
}
|
||||
}
|
||||
|
||||
static void blank() {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user