Search in sources :

Example 1 with CodeInfoQueryResult

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();
    }
}
Also used : Log(com.oracle.svm.core.log.Log) SubstrateInstalledCode(com.oracle.svm.core.deopt.SubstrateInstalledCode) CodePointer(org.graalvm.nativeimage.c.function.CodePointer) Pointer(org.graalvm.word.Pointer) CodeInfoQueryResult(com.oracle.svm.core.code.CodeInfoQueryResult) DeoptimizationAction(jdk.vm.ci.meta.DeoptimizationAction) CodePointer(org.graalvm.nativeimage.c.function.CodePointer) DeoptimizationReason(jdk.vm.ci.meta.DeoptimizationReason) NodeSourcePosition(org.graalvm.compiler.graph.NodeSourcePosition)

Example 2 with CodeInfoQueryResult

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;
}
Also used : VirtualFrame(com.oracle.svm.core.deopt.DeoptimizedFrame.VirtualFrame) MonitorSupport(com.oracle.svm.core.MonitorSupport) CodeInfoQueryResult(com.oracle.svm.core.code.CodeInfoQueryResult) FrameInfoQueryResult(com.oracle.svm.core.code.FrameInfoQueryResult)

Example 3 with CodeInfoQueryResult

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;
}
Also used : CodeInfoQueryResult(com.oracle.svm.core.code.CodeInfoQueryResult) Infopoint(jdk.vm.ci.code.site.Infopoint) DeoptEntryInfopoint(com.oracle.svm.core.deopt.DeoptEntryInfopoint)

Example 4 with CodeInfoQueryResult

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;
}
Also used : VirtualFrame(com.oracle.svm.core.deopt.DeoptimizedFrame.VirtualFrame) CodeInfoQueryResult(com.oracle.svm.core.code.CodeInfoQueryResult) FrameInfoQueryResult(com.oracle.svm.core.code.FrameInfoQueryResult)

Example 5 with CodeInfoQueryResult

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);
    }
}
Also used : CodeInfoQueryResult(com.oracle.svm.core.code.CodeInfoQueryResult) CodePointer(org.graalvm.nativeimage.c.function.CodePointer)

Aggregations

CodeInfoQueryResult (com.oracle.svm.core.code.CodeInfoQueryResult)5 FrameInfoQueryResult (com.oracle.svm.core.code.FrameInfoQueryResult)2 VirtualFrame (com.oracle.svm.core.deopt.DeoptimizedFrame.VirtualFrame)2 CodePointer (org.graalvm.nativeimage.c.function.CodePointer)2 MonitorSupport (com.oracle.svm.core.MonitorSupport)1 DeoptEntryInfopoint (com.oracle.svm.core.deopt.DeoptEntryInfopoint)1 SubstrateInstalledCode (com.oracle.svm.core.deopt.SubstrateInstalledCode)1 Log (com.oracle.svm.core.log.Log)1 Infopoint (jdk.vm.ci.code.site.Infopoint)1 DeoptimizationAction (jdk.vm.ci.meta.DeoptimizationAction)1 DeoptimizationReason (jdk.vm.ci.meta.DeoptimizationReason)1 NodeSourcePosition (org.graalvm.compiler.graph.NodeSourcePosition)1 Pointer (org.graalvm.word.Pointer)1