< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/ForeignCallStub.java
Print this page
@@ -22,15 +22,18 @@
*/
package org.graalvm.compiler.hotspot.stubs;
+import static jdk.vm.ci.code.BytecodeFrame.UNKNOWN_BCI;
import static jdk.vm.ci.hotspot.HotSpotCallingConventionType.JavaCall;
import static jdk.vm.ci.hotspot.HotSpotCallingConventionType.JavaCallee;
import static jdk.vm.ci.hotspot.HotSpotCallingConventionType.NativeCall;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.DESTROYS_REGISTERS;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.PRESERVES_REGISTERS;
+import static org.graalvm.compiler.nodes.CallTargetNode.InvokeKind.Static;
+import static org.graalvm.compiler.nodes.ConstantNode.forBoolean;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.core.common.type.Stamp;
@@ -41,14 +44,14 @@
import org.graalvm.compiler.debug.JavaMethodContext;
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability;
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition;
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkageImpl;
+import org.graalvm.compiler.hotspot.meta.HotSpotLoweringProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.nodes.StubForeignCallNode;
-import org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil;
-import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.hotspot.stubs.ForeignCallSnippets.Templates;
import org.graalvm.compiler.nodes.InvokeNode;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
@@ -74,12 +77,12 @@
* A {@linkplain #getGraph generated} stub for a {@link Transition non-leaf} foreign call from
* compiled code. A stub is required for such calls as the caller may be scheduled for
* deoptimization while the call is in progress. And since these are foreign/runtime calls on slow
* paths, we don't want to force the register allocator to spill around the call. As such, this stub
* saves and restores all allocatable registers. It also
- * {@linkplain StubUtil#handlePendingException(Word, boolean, boolean) handles} any exceptions
- * raised during the foreign call.
+ * {@linkplain ForeignCallSnippets#handlePendingException handles} any exceptions raised during the
+ * foreign call.
*/
public class ForeignCallStub extends Stub {
private final HotSpotJVMCIRuntime jvmciRuntime;
@@ -110,13 +113,14 @@
Transition transition, Reexecutability reexecutability, LocationIdentity... killedLocations) {
super(options, providers, HotSpotForeignCallLinkageImpl.create(providers.getMetaAccess(), providers.getCodeCache(), providers.getWordTypes(), providers.getForeignCalls(), descriptor, 0L,
PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutability, killedLocations));
this.jvmciRuntime = runtime;
this.prependThread = prependThread;
+ MetaAccessProvider metaAccess = providers.getMetaAccess();
Class<?>[] targetParameterTypes = createTargetParameters(descriptor);
ForeignCallDescriptor targetSig = new ForeignCallDescriptor(descriptor.getName() + ":C", descriptor.getResultType(), targetParameterTypes);
- target = HotSpotForeignCallLinkageImpl.create(providers.getMetaAccess(), providers.getCodeCache(), providers.getWordTypes(), providers.getForeignCalls(), targetSig, address,
+ target = HotSpotForeignCallLinkageImpl.create(metaAccess, providers.getCodeCache(), providers.getWordTypes(), providers.getForeignCalls(), targetSig, address,
DESTROYS_REGISTERS, NativeCall, NativeCall, transition, reexecutability, killedLocations);
}
/**
* Gets the linkage information for the call from this stub.
@@ -232,20 +236,25 @@
Class<?>[] args = linkage.getDescriptor().getArgumentTypes();
boolean isObjectResult = !LIRKind.isValue(linkage.getOutgoingCallingConvention().getReturn());
// Do we want to clear the pending exception?
boolean shouldClearException = linkage.isReexecutable() || linkage.isReexecutableOnlyAfterException();
try {
- ResolvedJavaMethod thisMethod = providers.getMetaAccess().lookupJavaMethod(ForeignCallStub.class.getDeclaredMethod("getGraph", DebugContext.class, CompilationIdentifier.class));
+ HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer();
+ Templates foreignCallSnippets = lowerer.getForeignCallSnippets();
+ ResolvedJavaMethod handlePendingException = foreignCallSnippets.handlePendingException.getMethod();
+ ResolvedJavaMethod getAndClearObjectResult = foreignCallSnippets.getAndClearObjectResult.getMethod();
+ ResolvedJavaMethod verifyObject = foreignCallSnippets.verifyObject.getMethod();
+ ResolvedJavaMethod thisMethod = getGraphMethod();
GraphKit kit = new GraphKit(debug, thisMethod, providers, wordTypes, providers.getGraphBuilderPlugins(), compilationId, toString());
StructuredGraph graph = kit.getGraph();
ParameterNode[] params = createParameters(kit, args);
ReadRegisterNode thread = kit.append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), wordTypes.getWordKind(), true, false));
ValueNode result = createTargetCall(kit, params, thread);
- kit.createInvoke(StubUtil.class, "handlePendingException", thread, ConstantNode.forBoolean(shouldClearException, graph), ConstantNode.forBoolean(isObjectResult, graph));
+ createStaticInvoke(kit, handlePendingException, thread, forBoolean(shouldClearException, graph), forBoolean(isObjectResult, graph));
if (isObjectResult) {
- InvokeNode object = kit.createInvoke(HotSpotReplacementsUtil.class, "getAndClearObjectResult", thread);
- result = kit.createInvoke(StubUtil.class, "verifyObject", object);
+ InvokeNode object = createStaticInvoke(kit, getAndClearObjectResult, thread);
+ result = createStaticInvoke(kit, verifyObject, object);
}
kit.append(new ReturnNode(linkage.getDescriptor().getResultType() == void.class ? null : result));
debug.dump(DebugContext.VERBOSE_LEVEL, graph, "Initial stub graph");
kit.inlineInvokes("Foreign call stub.", "Backend");
@@ -256,10 +265,31 @@
} catch (Exception e) {
throw GraalError.shouldNotReachHere(e);
}
}
+ private static InvokeNode createStaticInvoke(GraphKit kit, ResolvedJavaMethod method, ValueNode... args) {
+ return kit.createInvoke(method, Static, null, UNKNOWN_BCI, args);
+ }
+
+ private ResolvedJavaMethod getGraphMethod() {
+ ResolvedJavaMethod thisMethod = null;
+ for (ResolvedJavaMethod method : providers.getMetaAccess().lookupJavaType(ForeignCallStub.class).getDeclaredMethods()) {
+ if (method.getName().equals("getGraph")) {
+ if (thisMethod == null) {
+ thisMethod = method;
+ } else {
+ throw new InternalError("getGraph is ambiguous");
+ }
+ }
+ }
+ if (thisMethod == null) {
+ throw new InternalError("Can't find getGraph");
+ }
+ return thisMethod;
+ }
+
private ParameterNode[] createParameters(GraphKit kit, Class<?>[] args) {
ParameterNode[] params = new ParameterNode[args.length];
ResolvedJavaType accessingClass = providers.getMetaAccess().lookupJavaType(getClass());
for (int i = 0; i < args.length; i++) {
ResolvedJavaType type = providers.getMetaAccess().lookupJavaType(args[i]).resolve(accessingClass);
< prev index next >