< 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,36 **** --- 22,39 ---- */ 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,54 **** 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.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.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; --- 44,57 ---- 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.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,85 **** * 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. */ public class ForeignCallStub extends Stub { private final HotSpotJVMCIRuntime jvmciRuntime; --- 77,88 ---- * 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 ForeignCallSnippets#handlePendingException handles} any exceptions raised during the ! * foreign call. */ public class ForeignCallStub extends Stub { private final HotSpotJVMCIRuntime jvmciRuntime;
*** 110,122 **** 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; 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, DESTROYS_REGISTERS, NativeCall, NativeCall, transition, reexecutability, killedLocations); } /** * Gets the linkage information for the call from this stub. --- 113,126 ---- 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(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,251 **** 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)); 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)); if (isObjectResult) { ! InvokeNode object = kit.createInvoke(HotSpotReplacementsUtil.class, "getAndClearObjectResult", thread); ! result = kit.createInvoke(StubUtil.class, "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"); --- 236,260 ---- 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 { ! 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); ! createStaticInvoke(kit, handlePendingException, thread, forBoolean(shouldClearException, graph), forBoolean(isObjectResult, graph)); if (isObjectResult) { ! 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,265 **** --- 265,295 ---- } 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 >