public class ForeignCallStub extends Stub
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
handles any exceptions raised during
the foreign call.Modifier and Type | Class and Description |
---|---|
private class |
ForeignCallStub.DebugScopeContext |
Modifier and Type | Field and Description |
---|---|
protected boolean |
prependThread
Specifies if the JavaThread value for the current thread is to be prepended to the arguments
for the call to
target . |
private HotSpotGraalRuntimeProvider |
runtime |
private HotSpotForeignCallLinkage |
target
The target of the call.
|
code, compResult, linkage, providers
Constructor and Description |
---|
ForeignCallStub(HotSpotGraalRuntimeProvider runtime,
HotSpotProviders providers,
long address,
ForeignCallDescriptor descriptor,
boolean prependThread,
HotSpotForeignCallLinkage.Transition transition,
boolean reexecutable,
LocationIdentity... killedLocations)
Creates a stub for a call to code at a given address.
|
Modifier and Type | Method and Description |
---|---|
private ParameterNode[] |
createParameters(GraphKit kit,
Class<?>[] args) |
private StubForeignCallNode |
createTargetCall(GraphKit kit,
ParameterNode[] params,
ReadRegisterNode thread) |
private Class<?>[] |
createTargetParameters(ForeignCallDescriptor descriptor) |
protected Object |
debugScopeContext()
Gets a context object for the debug scope created when producing the code for this stub.
|
protected StructuredGraph |
getGraph()
Creates a graph for this stub.
|
protected ResolvedJavaMethod |
getInstalledCodeOwner()
Gets the method the stub's code will be associated with once installed.
|
HotSpotForeignCallLinkage |
getTargetLinkage()
Gets the linkage information for the call from this stub.
|
getCode, getCompilationResult, getDestroyedRegisters, getLinkage, getRegisterConfig, getStubs, initDestroyedRegisters, preservesRegisters, toString
private final HotSpotGraalRuntimeProvider runtime
private final HotSpotForeignCallLinkage target
protected final boolean prependThread
target
.public ForeignCallStub(HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers, long address, ForeignCallDescriptor descriptor, boolean prependThread, HotSpotForeignCallLinkage.Transition transition, boolean reexecutable, LocationIdentity... killedLocations)
address
- the address of the code to calldescriptor
- the signature of the call to this stubprependThread
- true if the JavaThread value for the current thread is to be prepended
to the arguments for the call to address
reexecutable
- specifies if the stub call can be re-executed without (meaningful) side
effects. Deoptimization will not return to a point before a stub call that cannot
be re-executed.killedLocations
- the memory locations killed by the stub callpublic HotSpotForeignCallLinkage getTargetLinkage()
private Class<?>[] createTargetParameters(ForeignCallDescriptor descriptor)
protected ResolvedJavaMethod getInstalledCodeOwner()
Stub
getInstalledCodeOwner
in class Stub
protected Object debugScopeContext()
Stub
debugScopeContext
in class Stub
protected StructuredGraph getGraph()
If the stub returns an object, the graph created corresponds to this pseudo code:
Object foreignFunctionStub(args...) { foreignFunction(currentThread, args); if (clearPendingException(thread())) { getAndClearObjectResult(thread()); DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint); } return verifyObject(getAndClearObjectResult(thread())); }If the stub returns a primitive or word, the graph created corresponds to this pseudo code (using
int
as the primitive return type):
int foreignFunctionStub(args...) { int result = foreignFunction(currentThread, args); if (clearPendingException(thread())) { DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint); } return result; }If the stub is void, the graph created corresponds to this pseudo code:
void foreignFunctionStub(args...) { foreignFunction(currentThread, args); if (clearPendingException(thread())) { DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint); } }In each example above, the
currentThread
argument is the C++ JavaThread value (i.e.,
%r15 on AMD64) and is only prepended if prependThread
is true.private ParameterNode[] createParameters(GraphKit kit, Class<?>[] args)
private StubForeignCallNode createTargetCall(GraphKit kit, ParameterNode[] params, ReadRegisterNode thread)