Skip to content

Commit 0e19198

Browse files
Ef55peter-hofer
authored andcommitted
[GR-47831] Preparations for JEP 424 ("Panama") foreign upcalls in Native Image.
PullRequest: graal/15203
2 parents 7007979 + 7134c3d commit 0e19198

File tree

19 files changed

+728
-478
lines changed

19 files changed

+728
-478
lines changed

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/lir/LIRValueUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public static boolean differentRegisters(Object... values) {
144144
Register r1 = registers.get(i);
145145
for (int j = 0; j < i; j++) {
146146
Register r2 = registers.get(j);
147-
assert !r1.equals(r2) : r1 + " appears more than once";
147+
assert !r1.equals(r2) : r1 + " appears more than once: " + j + " and " + i;
148148
}
149149
}
150150
return true;

substratevm/src/com.oracle.svm.core.foreign/src/com/oracle/svm/core/foreign/AbiUtils.java

Lines changed: 290 additions & 191 deletions
Large diffs are not rendered by default.

substratevm/src/com.oracle.svm.core.foreign/src/com/oracle/svm/core/foreign/DowncallStubsHolder.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,14 @@ public static ConstantPool getConstantPool(MetaAccessProvider metaAccess) {
5353
*/
5454
@Platforms(Platform.HOSTED_ONLY.class)
5555
public static String stubName(NativeEntryPointInfo nep) {
56-
StringBuilder builder = new StringBuilder("downcall_(");
57-
for (var param : nep.nativeMethodType().parameterArray()) {
56+
StringBuilder builder = new StringBuilder("downcall_");
57+
for (var param : nep.methodType().parameterArray()) {
5858
builder.append(JavaKind.fromJavaClass(param).getTypeChar());
5959
}
60-
builder.append(")");
61-
builder.append(JavaKind.fromJavaClass(nep.nativeMethodType().returnType()).getTypeChar());
60+
builder.append("_");
61+
builder.append(JavaKind.fromJavaClass(nep.methodType().returnType()).getTypeChar());
6262

63-
if (nep.returnsAssignment() != null) {
63+
if (nep.needsReturnBuffer()) {
6464
builder.append("_r");
6565
}
6666
if (nep.capturesCallState()) {

substratevm/src/com.oracle.svm.core.foreign/src/com/oracle/svm/core/foreign/ForeignFunctionsRuntime.java

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import org.graalvm.nativeimage.Platform;
3131
import org.graalvm.nativeimage.Platforms;
3232
import org.graalvm.nativeimage.c.function.CFunctionPointer;
33-
import org.graalvm.nativeimage.c.function.CodePointer;
3433
import org.graalvm.nativeimage.c.type.CIntPointer;
3534
import org.graalvm.word.LocationIdentity;
3635

@@ -51,15 +50,15 @@ public static ForeignFunctionsRuntime singleton() {
5150
return ImageSingletons.lookup(ForeignFunctionsRuntime.class);
5251
}
5352

54-
private final EconomicMap<NativeEntryPointInfo, FunctionPointerHolder> stubs = EconomicMap.create();
53+
private final EconomicMap<NativeEntryPointInfo, FunctionPointerHolder> downcallStubs = EconomicMap.create();
5554

5655
public ForeignFunctionsRuntime() {
5756
}
5857

5958
@Platforms(Platform.HOSTED_ONLY.class)
60-
public void addStubPointer(NativeEntryPointInfo nepi, CFunctionPointer ptr) {
61-
VMError.guarantee(!stubs.containsKey(nepi), "Multiple stubs generated for " + nepi);
62-
stubs.put(nepi, new FunctionPointerHolder(ptr));
59+
public void addDowncallStubPointer(NativeEntryPointInfo nep, CFunctionPointer ptr) {
60+
VMError.guarantee(!downcallStubs.containsKey(nep), "Seems like multiple stubs were generated for " + nep);
61+
VMError.guarantee(downcallStubs.put(nep, new FunctionPointerHolder(ptr)) == null);
6362
}
6463

6564
/**
@@ -68,26 +67,24 @@ public void addStubPointer(NativeEntryPointInfo nepi, CFunctionPointer ptr) {
6867
* {@link jdk.internal.foreign.abi.DowncallLinker#getBoundMethodHandle} and add information
6968
* about the descriptor there.
7069
*/
71-
public CodePointer getStubPointer(NativeEntryPointInfo nep) {
72-
FunctionPointerHolder pointer = stubs.get(nep);
70+
public CFunctionPointer getDowncallStubPointer(NativeEntryPointInfo nep) {
71+
FunctionPointerHolder pointer = downcallStubs.get(nep);
7372
if (pointer == null) {
74-
throw new UnregisteredDowncallStubException(nep);
73+
throw new UnregisteredForeignStubException(nep);
7574
} else {
7675
return pointer.functionPointer;
7776
}
7877
}
7978

8079
@SuppressWarnings("serial")
81-
public static class UnregisteredDowncallStubException extends RuntimeException {
82-
private final NativeEntryPointInfo nep;
80+
public static class UnregisteredForeignStubException extends RuntimeException {
8381

84-
UnregisteredDowncallStubException(NativeEntryPointInfo nep) {
82+
UnregisteredForeignStubException(NativeEntryPointInfo nep) {
8583
super(generateMessage(nep));
86-
this.nep = nep;
8784
}
8885

8986
private static String generateMessage(NativeEntryPointInfo nep) {
90-
return "Cannot perform downcall with leaf type " + nep.nativeMethodType() + " as it was not registered at compilation time.";
87+
return "Cannot perform downcall with leaf type " + nep.methodType() + " as it was not registered at compilation time.";
9188
}
9289
}
9390

@@ -138,6 +135,7 @@ public static void captureCallState(int statesToCapture, CIntPointer captureBuff
138135
++i;
139136
}
140137

138+
@Platforms(Platform.HOSTED_ONLY.class)//
141139
public static final SnippetRuntime.SubstrateForeignCallDescriptor CAPTURE_CALL_STATE = SnippetRuntime.findForeignCall(ForeignFunctionsRuntime.class,
142140
"captureCallState", false, LocationIdentity.any());
143141
}

substratevm/src/com.oracle.svm.core.foreign/src/com/oracle/svm/core/foreign/NativeEntryPointInfo.java

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,15 @@
2828
import java.util.Arrays;
2929
import java.util.Objects;
3030

31-
import com.oracle.svm.core.graal.code.AssignedLocation;
32-
3331
import jdk.internal.foreign.abi.ABIDescriptor;
3432
import jdk.internal.foreign.abi.VMStorage;
3533

3634
/**
3735
* Carries information about an entrypoint for foreign function calls.
38-
* {@link ForeignFunctionsRuntime#getStubPointer} allows getting the associated function pointer at
39-
* runtime (if it exists).
36+
* {@link ForeignFunctionsRuntime#getDowncallStubPointer} allows getting the associated function
37+
* pointer at runtime (if it exists).
4038
* <p>
41-
* {@link NativeEntryPointInfo#linkMethodType} is of the form (<>: argument; []: optional argument)
39+
* {@link NativeEntryPointInfo#methodType} is of the form (<>: argument; []: optional argument)
4240
*
4341
* <pre>
4442
* {@code
@@ -50,15 +48,19 @@
5048
*/
5149
public final class NativeEntryPointInfo {
5250
private final MethodType methodType;
53-
private final AssignedLocation[] parameterAssignments;
54-
private final AssignedLocation[] returnBuffering;
51+
private final VMStorage[] parameterAssignments;
52+
private final VMStorage[] returnBuffering;
53+
private final boolean needsReturnBuffer;
5554
private final boolean capturesState;
5655
private final boolean needsTransition;
5756

58-
private NativeEntryPointInfo(MethodType methodType, AssignedLocation[] cc, AssignedLocation[] returnBuffering, boolean capturesState, boolean needsTransition) {
57+
private NativeEntryPointInfo(MethodType methodType, VMStorage[] cc, VMStorage[] returnBuffering, boolean needsReturnBuffer, boolean capturesState, boolean needsTransition) {
58+
assert methodType.parameterCount() == cc.length;
59+
assert needsReturnBuffer == (returnBuffering.length > 1);
5960
this.methodType = methodType;
6061
this.parameterAssignments = cc;
6162
this.returnBuffering = returnBuffering;
63+
this.needsReturnBuffer = needsReturnBuffer;
6264
this.capturesState = capturesState;
6365
this.needsTransition = needsTransition;
6466
}
@@ -69,13 +71,10 @@ public static NativeEntryPointInfo make(
6971
boolean needsReturnBuffer,
7072
int capturedStateMask,
7173
boolean needsTransition) {
72-
if (returnMoves.length > 1 != needsReturnBuffer) {
74+
if ((returnMoves.length > 1) != needsReturnBuffer) {
7375
throw new AssertionError("Multiple register return, but needsReturnBuffer was false");
7476
}
75-
76-
AssignedLocation[] parametersAssignment = AbiUtils.singleton().toMemoryAssignment(argMoves, false);
77-
AssignedLocation[] returnBuffering = needsReturnBuffer ? AbiUtils.singleton().toMemoryAssignment(returnMoves, true) : null;
78-
return new NativeEntryPointInfo(methodType, parametersAssignment, returnBuffering, capturedStateMask != 0, needsTransition);
77+
return new NativeEntryPointInfo(methodType, argMoves, returnMoves, needsReturnBuffer, capturedStateMask != 0, needsTransition);
7978
}
8079

8180
public static Target_jdk_internal_foreign_abi_NativeEntryPoint makeEntryPoint(
@@ -86,8 +85,8 @@ public static Target_jdk_internal_foreign_abi_NativeEntryPoint makeEntryPoint(
8685
int capturedStateMask,
8786
boolean needsTransition) {
8887
var info = make(argMoves, returnMoves, methodType, needsReturnBuffer, capturedStateMask, needsTransition);
89-
long addr = ForeignFunctionsRuntime.singleton().getStubPointer(info).rawValue();
90-
return new Target_jdk_internal_foreign_abi_NativeEntryPoint(info.linkMethodType(), addr, capturedStateMask);
88+
long addr = ForeignFunctionsRuntime.singleton().getDowncallStubPointer(info).rawValue();
89+
return new Target_jdk_internal_foreign_abi_NativeEntryPoint(info.methodType(), addr, capturedStateMask);
9190
}
9291

9392
public int callAddressIndex() {
@@ -101,38 +100,23 @@ public int captureAddressIndex() {
101100
return callAddressIndex() + 1;
102101
}
103102

104-
/**
105-
* Method type without any of the special arguments.
106-
*/
107-
public MethodType nativeMethodType() {
108-
if (capturesCallState()) {
109-
return this.methodType.dropParameterTypes(0, captureAddressIndex() + 1);
110-
} else {
111-
return this.methodType.dropParameterTypes(0, callAddressIndex() + 1);
112-
}
113-
}
114-
115-
/**
116-
* Method type with all special arguments.
117-
*/
118-
public MethodType linkMethodType() {
103+
public MethodType methodType() {
119104
return this.methodType;
120105
}
121106

122107
public boolean needsReturnBuffer() {
123-
return this.returnBuffering != null;
108+
return needsReturnBuffer;
124109
}
125110

126111
public boolean capturesCallState() {
127112
return capturesState;
128113
}
129114

130-
public AssignedLocation[] parametersAssignment() {
131-
assert parameterAssignments.length == this.nativeMethodType().parameterCount() : Arrays.toString(parameterAssignments) + " ; " + nativeMethodType();
115+
public VMStorage[] parametersAssignment() {
132116
return parameterAssignments;
133117
}
134118

135-
public AssignedLocation[] returnsAssignment() {
119+
public VMStorage[] returnsAssignment() {
136120
return returnBuffering;
137121
}
138122

@@ -149,12 +133,12 @@ public boolean equals(Object o) {
149133
return false;
150134
}
151135
NativeEntryPointInfo that = (NativeEntryPointInfo) o;
152-
return capturesState == that.capturesState && needsTransition == that.needsTransition && Objects.equals(methodType, that.methodType) &&
136+
return capturesState == that.capturesState && needsTransition == that.needsTransition && needsReturnBuffer == that.needsReturnBuffer && Objects.equals(methodType, that.methodType) &&
153137
Arrays.equals(parameterAssignments, that.parameterAssignments) && Arrays.equals(returnBuffering, that.returnBuffering);
154138
}
155139

156140
@Override
157141
public int hashCode() {
158-
return Objects.hash(methodType, capturesState, needsTransition, Arrays.hashCode(parameterAssignments), Arrays.hashCode(returnBuffering));
142+
return Objects.hash(methodType, needsReturnBuffer, capturesState, needsTransition, Arrays.hashCode(parameterAssignments), Arrays.hashCode(returnBuffering));
159143
}
160144
}

0 commit comments

Comments
 (0)