use of com.oracle.svm.core.code.CodeInfoQueryResult 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.code.CodeInfoQueryResult in project graal by oracle.
the class Deoptimizer method deoptSourceFrameOperation.
private DeoptimizedFrame deoptSourceFrameOperation(CodePointer pc, boolean ignoreNonDeoptimizable, IsolateThread currentThread) {
VMOperation.guaranteeInProgress("deoptSourceFrame");
assert DeoptimizationSupport.getDeoptStubPointer().rawValue() != 0;
DeoptimizedFrame existing = checkDeoptimized(sourceSp);
if (existing != null) {
/* Already deoptimized, so nothing to do. */
return existing;
}
FrameInfoQueryResult frameInfo = sourceChunk.getFrameInfo();
if (frameInfo == null) {
if (ignoreNonDeoptimizable) {
return null;
} else {
throw VMError.shouldNotReachHere("Deoptimization: cannot deoptimize a method that was not marked as deoptimizable from address " + Long.toHexString(pc.rawValue()));
}
}
assert sourceChunk.getTotalFrameSize() >= FrameAccess.wordSize() : "no place in frame to put pointer to DeoptimizedFrame";
assert endOfParams == 0;
/*
* In case deoptimization is called from an inlined method, we have to construct multiple
* target frames (one for each inline level) for this source frame. Note that target methods
* are never inlined.
*/
FrameInfoQueryResult deoptInfo = frameInfo;
VirtualFrame previousVirtualFrame = null;
VirtualFrame topFrame = null;
while (deoptInfo != null) {
DeoptimizationCounters.counters().virtualFrameCount.inc();
if (deoptInfo.getDeoptMethodOffset() == 0) {
if (ignoreNonDeoptimizable) {
return null;
} else {
throw VMError.shouldNotReachHere("Deoptimization: cannot deoptimize a method that has no deoptimization entry point: " + deoptInfo.getSourceReference());
}
}
CodeInfoQueryResult targetInfo = CodeInfoTable.lookupDeoptimizationEntrypoint(deoptInfo.getDeoptMethodOffset(), deoptInfo.getEncodedBci());
if (targetInfo == null || targetInfo.getFrameInfo() == null) {
throw VMError.shouldNotReachHere("Deoptimization: no matching target bytecode frame found for bci " + deoptInfo.getBci() + " (encodedBci " + deoptInfo.getEncodedBci() + ") in method at address " + Long.toHexString(deoptInfo.getDeoptMethodAddress().rawValue()));
} else if (!targetInfo.getFrameInfo().isDeoptEntry()) {
throw VMError.shouldNotReachHere("Deoptimization: target frame information not marked as deoptimization entry point for bci " + deoptInfo.getBci() + " (encodedBci " + deoptInfo.getEncodedBci() + ") in method at address" + Long.toHexString(deoptInfo.getDeoptMethodAddress().rawValue()));
}
VirtualFrame virtualFrame = constructTargetFrame(targetInfo, deoptInfo);
if (previousVirtualFrame != null) {
previousVirtualFrame.caller = virtualFrame;
} else {
topFrame = virtualFrame;
}
previousVirtualFrame = virtualFrame;
// Go up one inline level
deoptInfo = deoptInfo.getCaller();
}
if (relockedObjects != null) {
for (Object lockee : relockedObjects) {
if (lockee != null) {
/*
* The re-locked objects must appear as if they had been locked from the thread
* that contains the frame, not the thread that performed deoptimization. Since
* the same object can be re-locked multiple times, we change the thread after
* all virtual frames have been reconstructed.
*/
ImageSingletons.lookup(MonitorSupport.class).setExclusiveOwnerThread(lockee, JavaThreads.singleton().createIfNotExisting(currentThread));
}
}
}
/* Allocate a buffer to hold the contents of the new target frame. */
DeoptimizedFrame deoptimizedFrame = DeoptimizedFrame.factory(targetContentSize, sourceChunk.getTotalFrameSize(), CodeInfoTable.lookupInstalledCode(pc), topFrame, pc);
installDeoptimizedFrame(sourceSp, deoptimizedFrame);
if (Options.TraceDeoptimization.getValue()) {
printDeoptimizedFrame(Log.log(), sourceSp, deoptimizedFrame, frameInfo);
}
logDeoptSourceFrameOperation(sourceSp, deoptimizedFrame);
return deoptimizedFrame;
}
use of com.oracle.svm.core.code.CodeInfoQueryResult in project graal by oracle.
the class NativeImageCodeCache method verifyDeoptEntry.
private static boolean verifyDeoptEntry(ImageCodeInfo imageCodeInfo, HostedMethod method, long encodedBci) {
int deoptOffsetInImage = method.getDeoptOffsetInImage();
if (deoptOffsetInImage <= 0) {
return error(method, encodedBci, "entry point method not compiled");
}
CodeInfoQueryResult result = new CodeInfoQueryResult();
long relativeIP = imageCodeInfo.lookupDeoptimizationEntrypoint(deoptOffsetInImage, encodedBci, result);
if (relativeIP < 0) {
return error(method, encodedBci, "entry point not found");
}
if (result.getFrameInfo() == null || !result.getFrameInfo().isDeoptEntry() || result.getFrameInfo().getEncodedBci() != encodedBci) {
return error(method, encodedBci, "entry point found, but wrong property");
}
return false;
}
use of com.oracle.svm.core.code.CodeInfoQueryResult in project graal by oracle.
the class SubstrateInspectedFrame method visitFrame.
@Override
public boolean visitFrame(Pointer sp, CodePointer ip, DeoptimizedFrame deoptimizedFrame) {
VirtualFrame virtualFrame = null;
CodeInfoQueryResult info = null;
FrameInfoQueryResult deoptInfo = null;
if (deoptimizedFrame != null) {
virtualFrame = deoptimizedFrame.getTopFrame();
} else {
info = CodeInfoTable.lookupCodeInfoQueryResult(ip);
if (info == null || info.getFrameInfo() == null) {
/*
* We do not have detailed information about this physical frame. It does not
* contain Java frames that we care about, so we can go to the caller.
*/
return true;
}
deoptInfo = info.getFrameInfo();
}
int virtualFrameIndex = 0;
do {
int method;
if (virtualFrame != null) {
assert deoptInfo == null : "must have either deoptimized or non-deoptimized frame information, but not both";
method = virtualFrame.getFrameInfo().getDeoptMethodOffset();
} else {
method = deoptInfo.getDeoptMethodOffset();
}
if (matches(method, curMatchingMethods)) {
if (skip > 0) {
skip--;
} else {
SubstrateInspectedFrame inspectedFrame = new SubstrateInspectedFrame(sp, ip, virtualFrame, info, deoptInfo, virtualFrameIndex);
result = visitor.visitFrame(inspectedFrame);
if (result != null) {
/* The user told us to stop the stackwalk. */
return false;
}
if (virtualFrame == null && inspectedFrame.virtualFrame != null) {
/*
* We deoptimized while visiting the InspectedFrame. Continue walking the
* deoptimized frame.
*/
virtualFrame = inspectedFrame.virtualFrame;
deoptInfo = null;
}
curMatchingMethods = laterMatchingMethods;
}
}
if (virtualFrame != null) {
virtualFrame = virtualFrame.getCaller();
} else {
deoptInfo = deoptInfo.getCaller();
}
virtualFrameIndex++;
} while (virtualFrame != null || deoptInfo != null);
return true;
}
use of com.oracle.svm.core.code.CodeInfoQueryResult in project graal by oracle.
the class Deoptimizer method deoptimizeFrameOperation.
private static void deoptimizeFrameOperation(Pointer sourceSp, boolean ignoreNonDeoptimizable, SpeculationReason speculation, IsolateThread currentThread) {
VMOperation.guaranteeInProgress("doDeoptimizeFrame");
CodePointer returnAddress = FrameAccess.readReturnAddress(sourceSp);
CodeInfoQueryResult info = CodeInfoTable.lookupCodeInfoQueryResult(returnAddress);
Deoptimizer deoptimizer = new Deoptimizer(sourceSp, info);
DeoptimizedFrame sourceFrame = deoptimizer.deoptSourceFrame(returnAddress, ignoreNonDeoptimizable, currentThread);
if (sourceFrame != null) {
registerSpeculationFailure(sourceFrame.getSourceInstalledCode(), speculation);
}
}
Aggregations