use of com.oracle.svm.core.deopt.SubstrateInstalledCode in project graal by oracle.
the class SnippetRuntime method deoptimize.
/**
* Foreign call: {@link #DEOPTIMIZE}.
*/
@SubstrateForeignCallTarget
private static void deoptimize(long actionAndReason, SpeculationReason speculation) {
Pointer sp = KnownIntrinsics.readCallerStackPointer();
DeoptimizationAction action = Deoptimizer.decodeDeoptAction(actionAndReason);
if (Deoptimizer.Options.TraceDeoptimization.getValue()) {
Log log = Log.log().string("[Deoptimization initiated").newline();
CodePointer ip = KnownIntrinsics.readReturnAddress();
SubstrateInstalledCode installedCode = CodeInfoTable.lookupInstalledCode(ip);
if (installedCode != null) {
log.string(" name: ").string(installedCode.getName()).newline();
}
log.string(" sp: ").hex(sp).string(" ip: ").hex(ip).newline();
DeoptimizationReason reason = Deoptimizer.decodeDeoptReason(actionAndReason);
log.string(" reason: ").string(reason.toString()).string(" action: ").string(action.toString()).newline();
int debugId = Deoptimizer.decodeDebugId(actionAndReason);
log.string(" debugId: ").signed(debugId).string(" speculation: ").string(Objects.toString(speculation)).newline();
CodeInfoQueryResult info = CodeInfoTable.lookupCodeInfoQueryResult(ip);
if (info != null) {
NodeSourcePosition sourcePosition = DeoptimizationSourcePositionDecoder.decode(debugId, info);
if (sourcePosition != null) {
log.string(" stack trace that triggered deoptimization:").newline();
NodeSourcePosition cur = sourcePosition;
while (cur != null) {
log.string(" at ");
if (cur.getMethod() != null) {
StackTraceElement element = cur.getMethod().asStackTraceElement(cur.getBCI());
if (element.getFileName() != null && element.getLineNumber() >= 0) {
log.string(element.toString());
} else {
log.string(cur.getMethod().format("%H.%n(%p)")).string(" bci ").signed(cur.getBCI());
}
} else {
log.string("[unknown method]");
}
log.newline();
cur = cur.getCaller();
}
}
}
}
if (action.doesInvalidateCompilation()) {
Deoptimizer.invalidateMethodOfFrame(sp, speculation);
} else {
Deoptimizer.deoptimizeFrame(sp, false, speculation);
}
if (Deoptimizer.Options.TraceDeoptimization.getValue()) {
Log.log().string("]").newline();
}
}
use of com.oracle.svm.core.deopt.SubstrateInstalledCode in project graal by oracle.
the class RuntimeCodeInfoMemoryWalkerAccessFeature method logMethod.
private static void logMethod(Log log, RuntimeMethodInfo methodInfo) {
log.string(methodInfo.name);
log.string(" ip: ").hex(methodInfo.getCodeStart()).string(" - ").hex(methodInfo.getCodeEnd());
log.string(" size: ").unsigned(methodInfo.getCodeSize());
SubstrateInstalledCode installedCode = methodInfo.installedCode.get();
if (installedCode != null) {
log.string(" installedCode: ").object(installedCode).string(" at ").hex(installedCode.getAddress());
} else {
log.string(" (invalidated)");
}
}
use of com.oracle.svm.core.deopt.SubstrateInstalledCode in project graal by oracle.
the class RuntimeCodeInfoMemoryWalkerAccessFeature method invalidateMethod.
protected void invalidateMethod(RuntimeMethodInfo methodInfo) {
VMOperation.guaranteeInProgress("Modifying code tables that are used by the GC");
invalidateMethodCount.inc();
assert verifyTable();
if (Options.TraceCodeCache.getValue()) {
Log.log().string("[" + INFO_INVALIDATE + " method: ");
logMethod(Log.log(), methodInfo);
Log.log().string("]").newline();
}
SubstrateInstalledCode installedCode = methodInfo.installedCode.get();
if (installedCode != null) {
assert !installedCode.isValid() || methodInfo.getCodeStart().rawValue() == installedCode.getAddress();
/*
* Until this point, the InstalledCode is valid. It can be invoked, and frames can be on
* the stack. All the metadata must be valid until this point. Make it non-entrant,
* i.e., ensure it cannot be invoked any more.
*/
installedCode.clearAddress();
}
InstalledCodeObserverSupport.removeObservers(methodInfo.codeObserverHandles);
/*
* Deoptimize all invocations that are on the stack. This performs a stack walk, so all
* metadata must be intact (even though the method was already marked as non-invokable).
*/
Deoptimizer.deoptimizeInRange(methodInfo.getCodeStart(), methodInfo.getCodeEnd(), false);
/*
* Now it is guaranteed that the InstalledCode is not on the stack and cannot be invoked
* anymore, so we can free the code and all metadata.
*/
/* Remove methodInfo entry from our table. */
int idx = binarySearch(methodInfos, 0, numMethods, methodInfo.getCodeStart());
assert idx >= 0 : "methodInfo must be in table";
System.arraycopy(methodInfos, idx + 1, methodInfos, idx, numMethods - (idx + 1));
numMethods--;
methodInfos[numMethods] = null;
Heap.getHeap().getGC().unregisterObjectReferenceWalker(methodInfo.constantsWalker);
/*
* The arrays are in a pinned chunk that probably still contains metadata for other methods
* that are still alive. So even though we release our allocator, the arrays are not garbage
* collected any time soon. By clearing the object arrays, we make sure that we do not keep
* objects in the regular unpinned heap alive.
*/
Arrays.fill(methodInfo.frameInfoObjectConstants, null);
if (methodInfo.frameInfoSourceClassNames != null) {
Arrays.fill(methodInfo.frameInfoSourceClassNames, null);
}
if (methodInfo.frameInfoSourceMethodNames != null) {
Arrays.fill(methodInfo.frameInfoSourceMethodNames, null);
}
if (methodInfo.frameInfoSourceFileNames != null) {
Arrays.fill(methodInfo.frameInfoSourceFileNames, null);
}
if (methodInfo.frameInfoNames != null) {
Arrays.fill(methodInfo.frameInfoNames, null);
}
methodInfo.allocator.release();
ConfigurationValues.getOSInterface().freeVirtualMemory(methodInfo.getCodeStart(), methodInfo.getCodeSize());
if (Options.TraceCodeCache.getValue()) {
logTable();
}
assert verifyTable();
}
use of com.oracle.svm.core.deopt.SubstrateInstalledCode in project graal by oracle.
the class SubstrateCodeCacheProvider method installCode.
@Override
@SuppressFBWarnings(value = { "BC_UNCONFIRMED_CAST" }, justification = "We know what we are doing.")
public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compiledCode, InstalledCode predefinedInstalledCode, SpeculationLog log, boolean isDefault) {
VMError.guarantee(!isDefault);
SubstrateInstalledCode substrateInstalledCode;
if (predefinedInstalledCode instanceof SubstrateInstalledCode.Access) {
substrateInstalledCode = ((SubstrateInstalledCode.Access) predefinedInstalledCode).getSubstrateInstalledCode();
} else {
substrateInstalledCode = (SubstrateInstalledCode) predefinedInstalledCode;
}
CompilationResult compResult = ((SubstrateCompiledCode) compiledCode).getCompilationResult();
InstalledCodeBuilder builder = new InstalledCodeBuilder((SharedRuntimeMethod) method, compResult, substrateInstalledCode, null);
builder.install();
return predefinedInstalledCode;
}
use of com.oracle.svm.core.deopt.SubstrateInstalledCode in project graal by oracle.
the class InstalledCodeBuilder method getTargetCodeAddress.
private long getTargetCodeAddress(Call callInfo) {
// NOTE that for the moment, we don't make static calls to external
// (e.g. native) functions.
// This will change, and we will have to case-split here... but not yet.
SharedMethod targetMethod = (SharedMethod) callInfo.target;
long callTargetStart = CodeInfoTable.getImageCodeCache().absoluteIP(targetMethod.getCodeOffsetInImage()).rawValue();
if (allInstalledCode != null) {
InstalledCodeBuilder targetInstalledCodeBuilder = allInstalledCode.get(targetMethod);
if (targetInstalledCodeBuilder != null) {
SubstrateInstalledCode targetInstalledCode = targetInstalledCodeBuilder.getInstalledCode();
if (targetInstalledCode != null && targetInstalledCode.isValid()) {
callTargetStart = targetInstalledCode.getAddress();
}
}
}
if (callTargetStart == 0) {
throw VMError.shouldNotReachHere("target method not compiled: " + targetMethod.format("%H.%n(%p)"));
}
return callTargetStart;
}
Aggregations