Skip to content

Commit 44ffa7e

Browse files
committed
[GR-42079] Share RuntimeStub info across libgraal isolates (22.3)
PullRequest: graal/13031
2 parents bb1b1e6 + 8fe8455 commit 44ffa7e

File tree

21 files changed

+496
-207
lines changed

21 files changed

+496
-207
lines changed

compiler/CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Compiler Changelog
22

3-
This changelog summarizes newly introduced optimizations that may be relevant to other teams.
3+
This changelog summarizes newly introduced optimizations and other compiler related changes.
44

55
## Version 22.3.0
66
* (GR-19840): An image produced by GraalVM's jlink now includes and uses libgraal by default and its `java -version` output includes GraalVM branding.

compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallDescriptor.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@ public class ForeignCallDescriptor {
5050
protected final boolean isGuaranteedSafepoint;
5151
protected final LocationIdentity[] killedLocations;
5252

53-
public ForeignCallDescriptor(String name, Class<?> resultType, Class<?>[] argumentTypes, boolean isReexecutable, LocationIdentity[] killedLocations, boolean canDeoptimize,
53+
public ForeignCallDescriptor(String name,
54+
Class<?> resultType,
55+
Class<?>[] argumentTypes,
56+
boolean isReexecutable,
57+
LocationIdentity[] killedLocations,
58+
boolean canDeoptimize,
5459
boolean isGuaranteedSafepoint) {
5560
this.isReexecutable = isReexecutable;
5661
this.killedLocations = killedLocations;

compiler/src/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallSignature.java

+22-3
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,26 @@
2525
package org.graalvm.compiler.core.common.spi;
2626

2727
import java.util.Arrays;
28+
import java.util.regex.Pattern;
29+
30+
import org.graalvm.compiler.debug.GraalError;
2831

2932
/**
3033
* The name and signature of a {@link ForeignCallDescriptor foreign call}.
3134
*/
3235
public final class ForeignCallSignature {
3336

37+
/**
38+
* {@link ForeignCallSignature} names can only contain non-whitespace characters.
39+
*/
40+
public static final Pattern NAME_PATTERN = Pattern.compile("[\\S]+");
41+
3442
private final String name;
3543
private final Class<?> resultType;
3644
private final Class<?>[] argumentTypes;
3745

3846
public ForeignCallSignature(String name, Class<?> resultType, Class<?>... argumentTypes) {
47+
GraalError.guarantee(NAME_PATTERN.matcher(name).matches(), "invalid foreign call name: %s", name);
3948
this.name = name;
4049
this.resultType = resultType;
4150
this.argumentTypes = argumentTypes;
@@ -76,14 +85,24 @@ public boolean equals(Object obj) {
7685
return false;
7786
}
7887

79-
@Override
80-
public String toString() {
81-
StringBuilder sb = new StringBuilder(name).append('(');
88+
/**
89+
* Gets the signature of this foreign call as a String.
90+
*
91+
* @param withName if true, the {@link #getName()} is prepended to the returned string
92+
*/
93+
public String toString(boolean withName) {
94+
StringBuilder sb = withName ? new StringBuilder(name) : new StringBuilder();
95+
sb.append('(');
8296
String sep = "";
8397
for (Class<?> arg : argumentTypes) {
8498
sb.append(sep).append(arg.getSimpleName());
8599
sep = ",";
86100
}
87101
return sb.append(')').append(resultType.getSimpleName()).toString();
88102
}
103+
104+
@Override
105+
public String toString() {
106+
return toString(true);
107+
}
89108
}

compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationPrinter.java

+24-11
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030

3131
import org.graalvm.compiler.code.CompilationResult;
3232
import org.graalvm.compiler.core.common.CompilationIdentifier;
33+
import org.graalvm.compiler.core.common.spi.ForeignCallSignature;
34+
import org.graalvm.compiler.debug.GraalError;
3335
import org.graalvm.compiler.debug.TTY;
3436
import org.graalvm.compiler.options.OptionValues;
3537

@@ -42,7 +44,7 @@
4244
public final class CompilationPrinter {
4345

4446
private final CompilationIdentifier id;
45-
private final JavaMethod method;
47+
private final Object source;
4648
private final int entryBCI;
4749
private final long start;
4850
private final long allocatedBytesBefore;
@@ -56,28 +58,30 @@ public final class CompilationPrinter {
5658
*
5759
* @param options used to get the value of {@link GraalCompilerOptions#PrintCompilation}
5860
* @param id the identifier for the compilation
59-
* @param method the method for which code is being compiled
61+
* @param source describes the object for which code is being compiled. Must be a
62+
* {@link JavaMethod} or a {@link ForeignCallSignature}
6063
* @param entryBCI the BCI at which compilation starts
6164
*/
62-
public static CompilationPrinter begin(OptionValues options, CompilationIdentifier id, JavaMethod method, int entryBCI) {
65+
public static CompilationPrinter begin(OptionValues options, CompilationIdentifier id, Object source, int entryBCI) {
66+
GraalError.guarantee(source instanceof JavaMethod || source instanceof ForeignCallSignature, "%s", source.getClass());
6367
if (PrintCompilation.getValue(options) && !TTY.isSuppressed()) {
64-
return new CompilationPrinter(id, method, entryBCI);
68+
return new CompilationPrinter(id, source, entryBCI);
6569
}
6670
return DISABLED;
6771
}
6872

6973
private static final CompilationPrinter DISABLED = new CompilationPrinter();
7074

7175
private CompilationPrinter() {
72-
this.method = null;
76+
this.source = null;
7377
this.id = null;
7478
this.entryBCI = -1;
7579
this.start = -1;
7680
this.allocatedBytesBefore = -1;
7781
}
7882

79-
private CompilationPrinter(CompilationIdentifier id, JavaMethod method, int entryBCI) {
80-
this.method = method;
83+
private CompilationPrinter(CompilationIdentifier id, Object source, int entryBCI) {
84+
this.source = source;
8185
this.id = id;
8286
this.entryBCI = entryBCI;
8387

@@ -86,10 +90,19 @@ private CompilationPrinter(CompilationIdentifier id, JavaMethod method, int entr
8690
}
8791

8892
private String getMethodDescription() {
89-
return String.format("%-30s %-70s %-45s %-50s %s", id.toString(CompilationIdentifier.Verbosity.ID),
90-
method.getDeclaringClass().getName(), method.getName(),
91-
method.getSignature().toMethodDescriptor(),
92-
entryBCI == JVMCICompiler.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") ");
93+
if (source instanceof JavaMethod) {
94+
JavaMethod method = (JavaMethod) source;
95+
return String.format("%-30s %-70s %-45s %-50s %s", id.toString(CompilationIdentifier.Verbosity.ID),
96+
method.getDeclaringClass().getName(), method.getName(),
97+
method.getSignature().toMethodDescriptor(),
98+
entryBCI == JVMCICompiler.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") ");
99+
} else {
100+
ForeignCallSignature sig = (ForeignCallSignature) source;
101+
return String.format("%-30s %-70s %-45s %-50s %s", id.toString(CompilationIdentifier.Verbosity.ID),
102+
"<stub>", sig.getName(),
103+
sig.toString(false),
104+
"");
105+
}
93106
}
94107

95108
/**

compiler/src/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotInvokeJavaMethodTest.java

+15-58
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
*/
2525
package org.graalvm.compiler.hotspot.test;
2626

27-
import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider;
27+
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor;
28+
import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider.TestForeignCalls;
2829
import org.graalvm.compiler.nodes.ValueNode;
2930
import org.graalvm.compiler.nodes.extended.ForeignCallNode;
3031
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
@@ -41,63 +42,19 @@ public class HotSpotInvokeJavaMethodTest extends HotSpotGraalCompilerTest {
4142

4243
@Override
4344
protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) {
44-
invocationPlugins.register(HotSpotInvokeJavaMethodTest.class, new InvocationPlugin("booleanReturnsBoolean", boolean.class) {
45-
@Override
46-
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode arg) {
47-
ForeignCallNode node = new ForeignCallNode(HotSpotHostForeignCallsProvider.TestForeignCalls.BOOLEAN_RETURNS_BOOLEAN, arg);
48-
b.addPush(JavaKind.Boolean, node);
49-
return true;
50-
}
51-
});
52-
invocationPlugins.register(HotSpotInvokeJavaMethodTest.class, new InvocationPlugin("byteReturnsByte", byte.class) {
53-
@Override
54-
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode arg) {
55-
ForeignCallNode node = new ForeignCallNode(HotSpotHostForeignCallsProvider.TestForeignCalls.BYTE_RETURNS_BYTE, arg);
56-
b.addPush(JavaKind.Byte, node);
57-
return true;
58-
}
59-
});
60-
invocationPlugins.register(HotSpotInvokeJavaMethodTest.class, new InvocationPlugin("shortReturnsShort", short.class) {
61-
@Override
62-
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode arg) {
63-
ForeignCallNode node = new ForeignCallNode(HotSpotHostForeignCallsProvider.TestForeignCalls.SHORT_RETURNS_SHORT, arg);
64-
b.addPush(JavaKind.Short, node);
65-
return true;
66-
}
67-
});
68-
invocationPlugins.register(HotSpotInvokeJavaMethodTest.class, new InvocationPlugin("charReturnsChar", char.class) {
69-
@Override
70-
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode arg) {
71-
ForeignCallNode node = new ForeignCallNode(HotSpotHostForeignCallsProvider.TestForeignCalls.CHAR_RETURNS_CHAR, arg);
72-
b.addPush(JavaKind.Char, node);
73-
return true;
74-
}
75-
});
76-
invocationPlugins.register(HotSpotInvokeJavaMethodTest.class, new InvocationPlugin("intReturnsInt", int.class) {
77-
@Override
78-
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode arg) {
79-
ForeignCallNode node = new ForeignCallNode(HotSpotHostForeignCallsProvider.TestForeignCalls.INT_RETURNS_INT, arg);
80-
b.addPush(JavaKind.Int, node);
81-
return true;
82-
}
83-
});
84-
invocationPlugins.register(HotSpotInvokeJavaMethodTest.class, new InvocationPlugin("longReturnsLong", long.class) {
85-
@Override
86-
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode arg) {
87-
ForeignCallNode node = new ForeignCallNode(HotSpotHostForeignCallsProvider.TestForeignCalls.LONG_RETURNS_LONG, arg);
88-
b.addPush(JavaKind.Long, node);
89-
return true;
90-
}
91-
});
92-
invocationPlugins.register(HotSpotInvokeJavaMethodTest.class, new InvocationPlugin("objectReturnsObject", Object.class) {
93-
@Override
94-
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode arg) {
95-
ForeignCallNode node = new ForeignCallNode(HotSpotHostForeignCallsProvider.TestForeignCalls.OBJECT_RETURNS_OBJECT, arg);
96-
b.addPush(JavaKind.Object, node);
97-
return true;
98-
}
99-
});
100-
45+
for (JavaKind kind : TestForeignCalls.KINDS) {
46+
HotSpotForeignCallDescriptor desc = TestForeignCalls.createStubCallDescriptor(kind);
47+
String name = desc.getName();
48+
Class<?> argType = desc.getSignature().getArgumentTypes()[0];
49+
invocationPlugins.register(HotSpotInvokeJavaMethodTest.class, new InvocationPlugin(name, argType) {
50+
@Override
51+
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode arg) {
52+
ForeignCallNode node = new ForeignCallNode(desc, arg);
53+
b.addPush(kind, node);
54+
return true;
55+
}
56+
});
57+
}
10158
super.registerInvocationPlugins(invocationPlugins);
10259
}
10360

compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java

+49-11
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import jdk.vm.ci.code.CallingConvention;
3939
import jdk.vm.ci.code.CallingConvention.Type;
4040
import jdk.vm.ci.code.CodeCacheProvider;
41-
import jdk.vm.ci.code.InstalledCode;
4241
import jdk.vm.ci.code.Register;
4342
import jdk.vm.ci.code.RegisterConfig;
4443
import jdk.vm.ci.code.ValueKindFactory;
@@ -92,8 +91,15 @@ public class HotSpotForeignCallLinkageImpl extends HotSpotForeignCallTarget impl
9291
* @param outgoingCcType outgoing (caller) calling convention type
9392
* @param incomingCcType incoming (callee) calling convention type (can be null)
9493
*/
95-
public static HotSpotForeignCallLinkage create(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, WordTypes wordTypes, HotSpotForeignCallsProvider foreignCalls,
96-
HotSpotForeignCallDescriptor descriptor, long address, RegisterEffect effect, Type outgoingCcType, Type incomingCcType) {
94+
public static HotSpotForeignCallLinkage create(MetaAccessProvider metaAccess,
95+
CodeCacheProvider codeCache,
96+
WordTypes wordTypes,
97+
HotSpotForeignCallsProvider foreignCalls,
98+
HotSpotForeignCallDescriptor descriptor,
99+
long address,
100+
RegisterEffect effect,
101+
Type outgoingCcType,
102+
Type incomingCcType) {
97103
CallingConvention outgoingCc = createCallingConvention(metaAccess, codeCache, wordTypes, foreignCalls, descriptor, outgoingCcType);
98104
CallingConvention incomingCc = incomingCcType == null ? null : createCallingConvention(metaAccess, codeCache, wordTypes, foreignCalls, descriptor, incomingCcType);
99105
HotSpotForeignCallLinkageImpl linkage = new HotSpotForeignCallLinkageImpl(descriptor, address, effect, outgoingCc, incomingCc);
@@ -106,8 +112,12 @@ public static HotSpotForeignCallLinkage create(MetaAccessProvider metaAccess, Co
106112
/**
107113
* Gets a calling convention for a given descriptor and call type.
108114
*/
109-
public static CallingConvention createCallingConvention(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, WordTypes wordTypes, ValueKindFactory<?> valueKindFactory,
110-
ForeignCallDescriptor descriptor, Type ccType) {
115+
public static CallingConvention createCallingConvention(MetaAccessProvider metaAccess,
116+
CodeCacheProvider codeCache,
117+
WordTypes wordTypes,
118+
ValueKindFactory<?> valueKindFactory,
119+
ForeignCallDescriptor descriptor,
120+
Type ccType) {
111121
assert ccType != null;
112122
Class<?>[] argumentTypes = descriptor.getArgumentTypes();
113123
JavaType[] parameterTypes = new JavaType[argumentTypes.length];
@@ -210,22 +220,50 @@ private boolean checkStubCondition() {
210220
return true;
211221
}
212222

223+
/**
224+
* Encapsulates a stub's entry point and set of killed registers.
225+
*/
226+
public static final class CodeInfo {
227+
/**
228+
* Address of first instruction in the stub.
229+
*/
230+
final long start;
231+
232+
/**
233+
* @see Stub#getDestroyedCallerRegisters()
234+
*/
235+
final EconomicSet<Register> killedRegisters;
236+
237+
public CodeInfo(long start, EconomicSet<Register> killedRegisters) {
238+
this.start = start;
239+
this.killedRegisters = killedRegisters;
240+
}
241+
}
242+
243+
/**
244+
* Substituted by
245+
* {@code com.oracle.svm.graal.hotspot.libgraal.Target_org_graalvm_compiler_hotspot_HotSpotForeignCallLinkageImpl}.
246+
*/
247+
private static CodeInfo getCodeInfo(Stub stub, Backend backend) {
248+
return new CodeInfo(stub.getCode(backend).getStart(), stub.getDestroyedCallerRegisters());
249+
}
250+
213251
@Override
214252
public void finalizeAddress(Backend backend) {
215253
if (address == 0) {
216254
assert checkStubCondition();
217-
InstalledCode code = stub.getCode(backend);
255+
CodeInfo codeInfo = getCodeInfo(stub, backend);
218256

219-
EconomicSet<Register> destroyedRegisters = stub.getDestroyedCallerRegisters();
220-
if (!destroyedRegisters.isEmpty()) {
221-
AllocatableValue[] temporaryLocations = new AllocatableValue[destroyedRegisters.size()];
257+
EconomicSet<Register> killedRegisters = codeInfo.killedRegisters;
258+
if (!killedRegisters.isEmpty()) {
259+
AllocatableValue[] temporaryLocations = new AllocatableValue[killedRegisters.size()];
222260
int i = 0;
223-
for (Register reg : destroyedRegisters) {
261+
for (Register reg : killedRegisters) {
224262
temporaryLocations[i++] = reg.asValue();
225263
}
226264
temporaries = temporaryLocations;
227265
}
228-
address = code.getStart();
266+
address = codeInfo.start;
229267
}
230268
}
231269

compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallDescriptor.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,19 @@ public enum Reexecutability {
9595
private final Transition transition;
9696
private final Reexecutability reexecutability;
9797

98-
public HotSpotForeignCallDescriptor(Transition transition, Reexecutability reexecutability, LocationIdentity[] killedLocations, String name, Class<?> resultType, Class<?>... argumentTypes) {
99-
super(name, resultType, argumentTypes, reexecutability == Reexecutability.REEXECUTABLE, killedLocations, transition == SAFEPOINT, transition == SAFEPOINT);
98+
public HotSpotForeignCallDescriptor(Transition transition,
99+
Reexecutability reexecutability,
100+
LocationIdentity[] killedLocations,
101+
String name,
102+
Class<?> resultType,
103+
Class<?>... argumentTypes) {
104+
super(name,
105+
resultType,
106+
argumentTypes,
107+
reexecutability == Reexecutability.REEXECUTABLE,
108+
killedLocations,
109+
transition == SAFEPOINT,
110+
transition == SAFEPOINT);
100111
this.transition = transition;
101112
this.reexecutability = reexecutability;
102113
}

compiler/src/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallsProvider.java

-8
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@
2424
*/
2525
package org.graalvm.compiler.hotspot.meta;
2626

27-
import java.util.List;
28-
2927
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
30-
import org.graalvm.compiler.hotspot.stubs.Stub;
3128

3229
import jdk.vm.ci.meta.Value;
3330

@@ -40,9 +37,4 @@ public interface HotSpotForeignCallsProvider extends ForeignCallsProvider {
4037
* Gets the registers that must be saved across a foreign call into the runtime.
4138
*/
4239
Value[] getNativeABICallerSaveRegisters();
43-
44-
/**
45-
* Gets the set of stubs linked to by the foreign calls represented by this object.
46-
*/
47-
List<Stub> getStubs();
4840
}

0 commit comments

Comments
 (0)