Search in sources :

Example 6 with Infopoint

use of jdk.vm.ci.code.site.Infopoint in project graal by oracle.

the class CollectingObjectReferenceVisitor method verifyMethod.

protected void verifyMethod(CompilationResult compilation, int compilationOffset) {
    for (int relativeIP = 0; relativeIP < compilation.getTargetCodeSize(); relativeIP++) {
        int totalIP = relativeIP + compilationOffset;
        CodeInfoQueryResult codeInfo = new CodeInfoQueryResult();
        lookupCodeInfo(totalIP, codeInfo);
        assert codeInfo.getTotalFrameSize() == compilation.getTotalFrameSize();
        assert lookupTotalFrameSize(totalIP) == codeInfo.getTotalFrameSize();
        assert lookupExceptionOffset(totalIP) == codeInfo.getExceptionOffset();
        assert lookupReferenceMapIndex(totalIP) == codeInfo.getReferenceMapIndex();
        assert getReferenceMapEncoding() == codeInfo.getReferenceMapEncoding();
    }
    for (Infopoint infopoint : compilation.getInfopoints()) {
        if (infopoint.debugInfo != null) {
            int offset = CodeInfoEncoder.getEntryOffset(infopoint);
            if (offset >= 0) {
                assert offset < compilation.getTargetCodeSize();
                CodeInfoQueryResult codeInfo = new CodeInfoQueryResult();
                lookupCodeInfo(offset + compilationOffset, codeInfo);
                CollectingObjectReferenceVisitor visitor = new CollectingObjectReferenceVisitor();
                ReferenceMapDecoder.walkOffsetsFromPointer(WordFactory.zero(), codeInfo.getReferenceMapEncoding(), codeInfo.getReferenceMapIndex(), visitor);
                ReferenceMapEncoder.Input expected = (ReferenceMapEncoder.Input) infopoint.debugInfo.getReferenceMap();
                assert expected.equals(visitor.result);
                if (codeInfo.frameInfo != CodeInfoQueryResult.NO_FRAME_INFO) {
                    verifyFrame(compilation, infopoint.debugInfo.frame(), codeInfo.frameInfo, new BitSet());
                }
            }
        }
    }
    for (ExceptionHandler handler : compilation.getExceptionHandlers()) {
        int offset = handler.pcOffset;
        assert offset >= 0 && offset < compilation.getTargetCodeSize();
        long actual = lookupExceptionOffset(offset + compilationOffset);
        long expected = handler.handlerPos - handler.pcOffset;
        assert expected != 0;
        assert expected == actual;
    }
}
Also used : ExceptionHandler(jdk.vm.ci.code.site.ExceptionHandler) ReferenceMapEncoder(com.oracle.svm.core.heap.ReferenceMapEncoder) BitSet(java.util.BitSet) Infopoint(jdk.vm.ci.code.site.Infopoint) DeoptEntryInfopoint(com.oracle.svm.core.deopt.DeoptEntryInfopoint) Infopoint(jdk.vm.ci.code.site.Infopoint) DeoptEntryInfopoint(com.oracle.svm.core.deopt.DeoptEntryInfopoint)

Example 7 with Infopoint

use of jdk.vm.ci.code.site.Infopoint in project graal by oracle.

the class HexCodeFileDisassemblerProvider method disassemble.

private static String disassemble(CodeCacheProvider codeCache, CompilationResult compResult, InstalledCode installedCode) {
    TargetDescription target = codeCache.getTarget();
    RegisterConfig regConfig = codeCache.getRegisterConfig();
    byte[] code = installedCode == null ? Arrays.copyOf(compResult.getTargetCode(), compResult.getTargetCodeSize()) : installedCode.getCode();
    if (code == null) {
        // Method was deoptimized/invalidated
        return "";
    }
    long start = installedCode == null ? 0L : installedCode.getStart();
    HexCodeFile hcf = new HexCodeFile(code, start, target.arch.getName(), target.wordSize * 8);
    if (compResult != null) {
        HexCodeFile.addAnnotations(hcf, compResult.getAnnotations());
        addExceptionHandlersComment(compResult, hcf);
        Register fp = regConfig.getFrameRegister();
        RefMapFormatter slotFormatter = new DefaultRefMapFormatter(target.wordSize, fp, 0);
        for (Infopoint infopoint : compResult.getInfopoints()) {
            if (infopoint instanceof Call) {
                Call call = (Call) infopoint;
                if (call.debugInfo != null) {
                    hcf.addComment(call.pcOffset + call.size, CodeUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString());
                }
                addOperandComment(hcf, call.pcOffset, "{" + codeCache.getTargetName(call) + "}");
            } else {
                if (infopoint.debugInfo != null) {
                    hcf.addComment(infopoint.pcOffset, CodeUtil.append(new StringBuilder(100), infopoint.debugInfo, slotFormatter).toString());
                }
                addOperandComment(hcf, infopoint.pcOffset, "{infopoint: " + infopoint.reason + "}");
            }
        }
        for (DataPatch site : compResult.getDataPatches()) {
            hcf.addOperandComment(site.pcOffset, "{" + site.reference.toString() + "}");
        }
        for (Mark mark : compResult.getMarks()) {
            hcf.addComment(mark.pcOffset, codeCache.getMarkName(mark));
        }
    }
    String hcfEmbeddedString = hcf.toEmbeddedString();
    return HexCodeFileDisTool.tryDisassemble(hcfEmbeddedString);
}
Also used : DefaultRefMapFormatter(jdk.vm.ci.code.CodeUtil.DefaultRefMapFormatter) RefMapFormatter(jdk.vm.ci.code.CodeUtil.RefMapFormatter) RegisterConfig(jdk.vm.ci.code.RegisterConfig) Call(jdk.vm.ci.code.site.Call) TargetDescription(jdk.vm.ci.code.TargetDescription) Mark(jdk.vm.ci.code.site.Mark) Infopoint(jdk.vm.ci.code.site.Infopoint) DataPatch(jdk.vm.ci.code.site.DataPatch) Register(jdk.vm.ci.code.Register) DefaultRefMapFormatter(jdk.vm.ci.code.CodeUtil.DefaultRefMapFormatter)

Example 8 with Infopoint

use of jdk.vm.ci.code.site.Infopoint in project graal by oracle.

the class CompileQueue method verifyDeoptTarget.

private static boolean verifyDeoptTarget(HostedMethod method, CompilationResult result) {
    Map<Long, BytecodeFrame> encodedBciMap = new HashMap<>();
    /*
         * All deopt targets must have a graph.
         */
    assert method.compilationInfo.graph != null : "Deopt target must have a graph.";
    /*
         * No deopt targets can have a StackValueNode in the graph.
         */
    assert method.compilationInfo.graph.getNodes(StackValueNode.TYPE).isEmpty() : "No stack value nodes must be present in deopt target.";
    for (Infopoint infopoint : result.getInfopoints()) {
        if (infopoint.debugInfo != null) {
            DebugInfo debugInfo = infopoint.debugInfo;
            if (!debugInfo.hasFrame()) {
                continue;
            }
            BytecodeFrame topFrame = debugInfo.frame();
            BytecodeFrame rootFrame = topFrame;
            while (rootFrame.caller() != null) {
                rootFrame = rootFrame.caller();
            }
            assert rootFrame.getMethod().equals(method);
            boolean isDeoptEntry = method.compilationInfo.isDeoptEntry(rootFrame.getBCI(), rootFrame.duringCall, rootFrame.rethrowException);
            if (infopoint instanceof DeoptEntryInfopoint) {
                assert isDeoptEntry;
            } else if (rootFrame.duringCall && isDeoptEntry) {
                assert infopoint instanceof Call || isSingleSteppingInfopoint(infopoint);
            } else {
                continue;
            }
            long encodedBci = FrameInfoEncoder.encodeBci(rootFrame.getBCI(), rootFrame.duringCall, rootFrame.rethrowException);
            if (encodedBciMap.containsKey(encodedBci)) {
                assert encodedBciMap.get(encodedBci).equals(rootFrame) : "duplicate encoded bci " + encodedBci + " in deopt target " + method + " with different debug info:\n\n" + rootFrame + "\n\n" + encodedBciMap.get(encodedBci);
            }
            encodedBciMap.put(encodedBci, rootFrame);
        }
    }
    return true;
}
Also used : Call(jdk.vm.ci.code.site.Call) BytecodeFrame(jdk.vm.ci.code.BytecodeFrame) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) DeoptEntryInfopoint(com.oracle.svm.core.deopt.DeoptEntryInfopoint) Infopoint(jdk.vm.ci.code.site.Infopoint) DeoptEntryInfopoint(com.oracle.svm.core.deopt.DeoptEntryInfopoint) DebugInfo(jdk.vm.ci.code.DebugInfo)

Example 9 with Infopoint

use of jdk.vm.ci.code.site.Infopoint in project graal by oracle.

the class CompileQueue method defaultCompileFunction.

@SuppressWarnings("try")
private CompilationResult defaultCompileFunction(DebugContext debug, HostedMethod method, CompilationIdentifier compilationIdentifier, CompileReason reason, RuntimeConfiguration config) {
    if (NativeImageOptions.PrintAOTCompilation.getValue()) {
        System.out.println("Compiling " + method.format("%r %H.%n(%p)") + "  [" + reason + "]");
    }
    Backend backend = config.lookupBackend(method);
    StructuredGraph graph = method.compilationInfo.graph;
    assert graph != null : method;
    /* Operate on a copy, to keep the original graph intact for later inlining. */
    graph = graph.copyWithIdentifier(compilationIdentifier, debug);
    /* Check that graph is in good shape before compilation. */
    assert GraphOrder.assertSchedulableGraph(graph);
    try (DebugContext.Scope s = debug.scope("Compiling", graph, method, this)) {
        if (deoptimizeAll && method.compilationInfo.canDeoptForTesting) {
            insertDeoptTests(method, graph);
        }
        method.compilationInfo.numNodesBeforeCompilation = graph.getNodeCount();
        method.compilationInfo.numDeoptEntryPoints = graph.getNodes().filter(DeoptEntryNode.class).count();
        method.compilationInfo.numDuringCallEntryPoints = graph.getNodes(MethodCallTargetNode.TYPE).snapshot().stream().map(MethodCallTargetNode::invoke).filter(invoke -> method.compilationInfo.isDeoptEntry(invoke.bci(), true, false)).count();
        Suites suites = method.compilationInfo.isDeoptTarget() ? deoptTargetSuites : regularSuites;
        LIRSuites lirSuites = method.compilationInfo.isDeoptTarget() ? deoptTargetLIRSuites : regularLIRSuites;
        CompilationResult result = new CompilationResult(compilationIdentifier, method.format("%H.%n(%p)")) {

            @Override
            public void close() {
            /*
                     * Do nothing, we do not want our CompilationResult to be closed because we
                     * aggregate all data items and machine code in the native image heap.
                     */
            }
        };
        try (Indent indent = debug.logAndIndent("compile %s", method)) {
            GraalCompiler.compileGraph(graph, method, backend.getProviders(), backend, null, optimisticOpts, method.getProfilingInfo(), suites, lirSuites, result, new HostedCompilationResultBuilderFactory());
        }
        method.getProfilingInfo().setCompilerIRSize(StructuredGraph.class, method.compilationInfo.graph.getNodeCount());
        method.compilationInfo.numNodesAfterCompilation = graph.getNodeCount();
        if (method.compilationInfo.isDeoptTarget()) {
            assert verifyDeoptTarget(method, result);
        }
        for (Infopoint infopoint : result.getInfopoints()) {
            if (infopoint instanceof Call) {
                Call call = (Call) infopoint;
                HostedMethod callTarget = (HostedMethod) call.target;
                if (call.direct) {
                    ensureCompiled(callTarget, new DirectCallReason(method, reason));
                } else if (callTarget != null && callTarget.getImplementations() != null) {
                    for (HostedMethod impl : callTarget.getImplementations()) {
                        ensureCompiled(impl, new VirtualCallReason(method, callTarget, reason));
                    }
                }
            }
        }
        /* Shrink resulting code array to minimum size, to reduze memory footprint. */
        if (result.getTargetCode().length > result.getTargetCodeSize()) {
            result.setTargetCode(Arrays.copyOf(result.getTargetCode(), result.getTargetCodeSize()), result.getTargetCodeSize());
        }
        return result;
    } catch (Throwable ex) {
        GraalError error = ex instanceof GraalError ? (GraalError) ex : new GraalError(ex);
        error.addContext("method: " + method.format("%r %H.%n(%p)") + "  [" + reason + "]");
        throw error;
    }
}
Also used : Call(jdk.vm.ci.code.site.Call) Indent(org.graalvm.compiler.debug.Indent) DeoptEntryInfopoint(com.oracle.svm.core.deopt.DeoptEntryInfopoint) Infopoint(jdk.vm.ci.code.site.Infopoint) DebugContext(org.graalvm.compiler.debug.DebugContext) Backend(org.graalvm.compiler.core.target.Backend) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) GraalError(org.graalvm.compiler.debug.GraalError) HostedMethod(com.oracle.svm.hosted.meta.HostedMethod) LIRSuites(org.graalvm.compiler.lir.phases.LIRSuites) CompilationResult(org.graalvm.compiler.code.CompilationResult) LIRSuites(org.graalvm.compiler.lir.phases.LIRSuites) Suites(org.graalvm.compiler.phases.tiers.Suites)

Example 10 with Infopoint

use of jdk.vm.ci.code.site.Infopoint in project graal by oracle.

the class NativeImageCodeCache method patchMethods.

/**
 * Patch references from code to other code and constant data. Generate relocation information
 * in the process. More patching can be done, and correspondingly fewer relocation records
 * generated, if the caller passes a non-null rodataDisplacementFromText.
 *
 * @param relocs a relocation map
 */
public void patchMethods(RelocatableBuffer relocs) {
    // in each compilation result...
    for (Entry<HostedMethod, CompilationResult> entry : compilations.entrySet()) {
        HostedMethod method = entry.getKey();
        CompilationResult compilation = entry.getValue();
        // the codecache-relative offset of the compilation
        int compStart = method.getCodeAddressOffset();
        AMD64InstructionPatcher patcher = new AMD64InstructionPatcher(compilation);
        // ... patch direct call sites.
        for (Infopoint infopoint : compilation.getInfopoints()) {
            if (infopoint instanceof Call && ((Call) infopoint).direct) {
                Call call = (Call) infopoint;
                // NOTE that for the moment, we don't make static calls to external
                // (e.g. native) functions. So every static call site has a target
                // which is also in the code cache (a.k.a. a section-local call).
                // This will change, and we will have to case-split here... but not yet.
                int callTargetStart = ((HostedMethod) call.target).getCodeAddressOffset();
                // Patch a PC-relative call.
                // This code handles the case of section-local calls only.
                int pcDisplacement = callTargetStart - (compStart + call.pcOffset);
                patcher.findPatchData(call.pcOffset, pcDisplacement).apply(compilation.getTargetCode());
            }
        }
        // ... and patch references to constant data
        for (DataPatch dataPatch : compilation.getDataPatches()) {
            /*
                 * Constants are allocated offsets in a separate space, which can be emitted as
                 * read-only (.rodata) section.
                 */
            AMD64InstructionPatcher.PatchData patchData = patcher.findPatchData(dataPatch.pcOffset, 0);
            /*
                 * The relocation site is some offset into the instruction, which is some offset
                 * into the method, which is some offset into the text section (a.k.a. code cache).
                 * The offset we get out of the RelocationSiteInfo accounts for the first two, since
                 * we pass it the whole method. We add the method start to get the section-relative
                 * offset.
                 */
            long siteOffset = compStart + patchData.operandPosition;
            /*
                 * Do we have an addend? Yes; it's constStart. BUT x86/x86-64 PC-relative references
                 * are relative to the *next* instruction. So, if the next instruction starts n
                 * bytes from the relocation site, we want to subtract n bytes from our addend.
                 */
            long addend = (patchData.nextInstructionPosition - patchData.operandPosition);
            relocs.addPCRelativeRelocationWithAddend((int) siteOffset, patchData.operandSize, addend, dataPatch.reference);
        }
    }
}
Also used : Call(jdk.vm.ci.code.site.Call) DataPatch(jdk.vm.ci.code.site.DataPatch) AMD64InstructionPatcher(com.oracle.svm.core.graal.code.amd64.AMD64InstructionPatcher) HostedMethod(com.oracle.svm.hosted.meta.HostedMethod) Infopoint(jdk.vm.ci.code.site.Infopoint) DeoptEntryInfopoint(com.oracle.svm.core.deopt.DeoptEntryInfopoint) CompilationResult(org.graalvm.compiler.code.CompilationResult) Infopoint(jdk.vm.ci.code.site.Infopoint) DeoptEntryInfopoint(com.oracle.svm.core.deopt.DeoptEntryInfopoint)

Aggregations

Infopoint (jdk.vm.ci.code.site.Infopoint)13 Call (jdk.vm.ci.code.site.Call)8 DeoptEntryInfopoint (com.oracle.svm.core.deopt.DeoptEntryInfopoint)6 CompilationResult (org.graalvm.compiler.code.CompilationResult)5 DebugInfo (jdk.vm.ci.code.DebugInfo)3 DataPatch (jdk.vm.ci.code.site.DataPatch)3 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)3 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)3 ReferenceMapEncoder (com.oracle.svm.core.heap.ReferenceMapEncoder)2 HostedMethod (com.oracle.svm.hosted.meta.HostedMethod)2 HashMap (java.util.HashMap)2 BytecodeFrame (jdk.vm.ci.code.BytecodeFrame)2 ExceptionHandler (jdk.vm.ci.code.site.ExceptionHandler)2 Test (org.junit.Test)2 AMD64InstructionPatcher (com.oracle.svm.core.graal.code.amd64.AMD64InstructionPatcher)1 ByteBuffer (java.nio.ByteBuffer)1 ArrayList (java.util.ArrayList)1 BitSet (java.util.BitSet)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 DefaultRefMapFormatter (jdk.vm.ci.code.CodeUtil.DefaultRefMapFormatter)1