public abstract class AbstractForeignCallStub 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 | Field and Description |
|---|---|
protected HotSpotJVMCIRuntime |
jvmciRuntime |
protected boolean |
prependThread
Specifies if the JavaThread value for the current thread is to be prepended to the arguments
for the call to
AbstractForeignCallStub.target. |
protected HotSpotForeignCallLinkage |
target
The target of the call.
|
| Constructor and Description |
|---|
AbstractForeignCallStub(OptionValues options,
HotSpotJVMCIRuntime runtime,
HotSpotProviders providers,
long address,
HotSpotForeignCallDescriptor descriptor,
boolean prependThread)
Creates a stub for a call to code at a given address.
|
| Modifier and Type | Method and Description |
|---|---|
protected ParameterNode[] |
createParameters(GraphKit kit) |
protected abstract ValueNode |
createTargetCall(GraphKit kit,
ReadRegisterNode thread) |
protected Object |
debugScopeContext()
Gets a context object for the debug scope created when producing the code for this stub.
|
protected StructuredGraph |
getGraph(DebugContext debug,
CompilationIdentifier compilationId)
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.
|
protected abstract HotSpotForeignCallDescriptor |
getTargetSignature(HotSpotForeignCallDescriptor descriptor) |
protected abstract boolean |
returnsObject() |
protected abstract boolean |
shouldClearException() |
checkSafeDataReference, createLIRSuites, createSuites, getCode, getCompilationResult, getDestroyedCallerRegisters, getLinkage, getRegisterConfig, getStubCompilationId, initDestroyedCallerRegisters, shouldSaveRegistersAroundCalls, toStringprotected final HotSpotJVMCIRuntime jvmciRuntime
protected final HotSpotForeignCallLinkage target
protected final boolean prependThread
AbstractForeignCallStub.target.public AbstractForeignCallStub(OptionValues options, HotSpotJVMCIRuntime runtime, HotSpotProviders providers, long address, HotSpotForeignCallDescriptor descriptor, boolean prependThread)
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 addressprotected abstract HotSpotForeignCallDescriptor getTargetSignature(HotSpotForeignCallDescriptor descriptor)
public final HotSpotForeignCallLinkage getTargetLinkage()
protected final ResolvedJavaMethod getInstalledCodeOwner()
StubgetInstalledCodeOwner in class Stubprotected final Object debugScopeContext()
StubdebugScopeContext in class Stubprotected final StructuredGraph getGraph(DebugContext debug, CompilationIdentifier compilationId)
If the stub returns an object, the graph created corresponds to this pseudo code:
Object foreignFunctionStub(args...) {
foreignFunction(currentThread, args);
if ((shouldClearException && clearPendingException(thread())) || (!shouldClearException && hasPendingException(thread)) {
getAndClearObjectResult(thread());
DeoptimizeCallerNode.deopt(None, 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 ((shouldClearException && clearPendingException(thread())) || (!shouldClearException && hasPendingException(thread)) {
DeoptimizeCallerNode.deopt(None, RuntimeConstraint);
}
return result;
}
If the stub is void, the graph created corresponds to this pseudo code:
void foreignFunctionStub(args...) {
foreignFunction(currentThread, args);
if ((shouldClearException && clearPendingException(thread())) || (!shouldClearException && hasPendingException(thread)) {
DeoptimizeCallerNode.deopt(None, RuntimeConstraint);
}
}
In each example above, the currentThread argument is the C++ JavaThread value (i.e.,
%r15 on AMD64) and is only prepended if AbstractForeignCallStub.prependThread is true.protected abstract boolean returnsObject()
protected abstract boolean shouldClearException()
protected ParameterNode[] createParameters(GraphKit kit)
protected abstract ValueNode createTargetCall(GraphKit kit, ReadRegisterNode thread)