Search in sources :

Example 1 with Reference

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

the class LIRNativeImageCodeCache 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
 */
@Override
@SuppressWarnings("try")
public void patchMethods(DebugContext debug, RelocatableBuffer relocs, ObjectFile objectFile) {
    // 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();
        // Build an index of PatchingAnnoations
        Map<Integer, HostedPatcher> patches = new HashMap<>();
        ByteBuffer targetCode = null;
        for (CodeAnnotation codeAnnotation : compilation.getCodeAnnotations()) {
            if (codeAnnotation instanceof HostedPatcher) {
                HostedPatcher priorValue = patches.put(codeAnnotation.getPosition(), (HostedPatcher) codeAnnotation);
                VMError.guarantee(priorValue == null, "Registering two patchers for same position.");
            } else if (codeAnnotation instanceof HostedImageHeapConstantPatch) {
                HostedImageHeapConstantPatch patch = (HostedImageHeapConstantPatch) codeAnnotation;
                ObjectInfo objectInfo = imageHeap.getObjectInfo(SubstrateObjectConstant.asObject(patch.constant));
                long objectAddress = objectInfo.getAddress();
                if (targetCode == null) {
                    targetCode = ByteBuffer.wrap(compilation.getTargetCode()).order(target.arch.getByteOrder());
                }
                int originalValue = targetCode.getInt(patch.getPosition());
                long newValue = originalValue + objectAddress;
                VMError.guarantee(NumUtil.isInt(newValue), "Image heap size is limited to 2 GByte");
                targetCode.putInt(patch.getPosition(), (int) newValue);
            }
        }
        int patchesHandled = 0;
        HashSet<Integer> patchedOffsets = new HashSet<>();
        // ... 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);
                patches.get(call.pcOffset).patch(compStart, pcDisplacement, compilation.getTargetCode());
                boolean noPriorMatch = patchedOffsets.add(call.pcOffset);
                VMError.guarantee(noPriorMatch, "Patching same offset twice.");
                patchesHandled++;
            }
        }
        for (DataPatch dataPatch : compilation.getDataPatches()) {
            Reference ref = dataPatch.reference;
            /*
                 * Constants are allocated offsets in a separate space, which can be emitted as
                 * read-only (.rodata) section.
                 */
            patches.get(dataPatch.pcOffset).relocate(ref, relocs, compStart);
            boolean noPriorMatch = patchedOffsets.add(dataPatch.pcOffset);
            VMError.guarantee(noPriorMatch, "Patching same offset twice.");
            patchesHandled++;
        }
        VMError.guarantee(patchesHandled == patches.size(), "Not all patches applied.");
        try (DebugContext.Scope ds = debug.scope("After Patching", method.asJavaMethod())) {
            debug.dump(DebugContext.BASIC_LEVEL, compilation, "After patching");
        } catch (Throwable e) {
            throw VMError.shouldNotReachHere(e);
        }
    }
}
Also used : CodeAnnotation(org.graalvm.compiler.code.CompilationResult.CodeAnnotation) Call(jdk.vm.ci.code.site.Call) HashMap(java.util.HashMap) Reference(jdk.vm.ci.code.site.Reference) Infopoint(jdk.vm.ci.code.site.Infopoint) DebugContext(org.graalvm.compiler.debug.DebugContext) HostedPatcher(com.oracle.svm.hosted.code.HostedPatcher) ByteBuffer(java.nio.ByteBuffer) Infopoint(jdk.vm.ci.code.site.Infopoint) ObjectInfo(com.oracle.svm.hosted.image.NativeImageHeap.ObjectInfo) DataPatch(jdk.vm.ci.code.site.DataPatch) HostedMethod(com.oracle.svm.hosted.meta.HostedMethod) HostedImageHeapConstantPatch(com.oracle.svm.hosted.code.HostedImageHeapConstantPatch) CompilationResult(org.graalvm.compiler.code.CompilationResult) HashSet(java.util.HashSet)

Example 2 with Reference

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

the class CompileQueue method ensureCalleesCompiled.

protected void ensureCalleesCompiled(HostedMethod method, CompileReason reason, CompilationResult 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));
                }
            }
        }
    }
    for (DataPatch dataPatch : result.getDataPatches()) {
        Reference reference = dataPatch.reference;
        if (reference instanceof ConstantReference) {
            VMConstant constant = ((ConstantReference) reference).getConstant();
            if (constant instanceof SubstrateMethodPointerConstant) {
                MethodPointer pointer = ((SubstrateMethodPointerConstant) constant).pointer();
                final ResolvedJavaMethod method1 = pointer.getMethod();
                HostedMethod hMethod = (HostedMethod) method1;
                ensureCompiled(hMethod, new MethodPointerConstantReason(method, hMethod, reason));
            }
        }
    }
}
Also used : Call(jdk.vm.ci.code.site.Call) ConstantReference(jdk.vm.ci.code.site.ConstantReference) ConstantReference(jdk.vm.ci.code.site.ConstantReference) Reference(jdk.vm.ci.code.site.Reference) SubstrateMethodPointerConstant(com.oracle.svm.core.meta.SubstrateMethodPointerConstant) DeoptEntryInfopoint(com.oracle.svm.core.deopt.DeoptEntryInfopoint) Infopoint(jdk.vm.ci.code.site.Infopoint) DataPatch(jdk.vm.ci.code.site.DataPatch) MethodPointer(com.oracle.svm.core.meta.MethodPointer) HostedMethod(com.oracle.svm.hosted.meta.HostedMethod) VMConstant(jdk.vm.ci.meta.VMConstant) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Aggregations

HostedMethod (com.oracle.svm.hosted.meta.HostedMethod)2 Call (jdk.vm.ci.code.site.Call)2 DataPatch (jdk.vm.ci.code.site.DataPatch)2 Infopoint (jdk.vm.ci.code.site.Infopoint)2 Reference (jdk.vm.ci.code.site.Reference)2 DeoptEntryInfopoint (com.oracle.svm.core.deopt.DeoptEntryInfopoint)1 MethodPointer (com.oracle.svm.core.meta.MethodPointer)1 SubstrateMethodPointerConstant (com.oracle.svm.core.meta.SubstrateMethodPointerConstant)1 HostedImageHeapConstantPatch (com.oracle.svm.hosted.code.HostedImageHeapConstantPatch)1 HostedPatcher (com.oracle.svm.hosted.code.HostedPatcher)1 ObjectInfo (com.oracle.svm.hosted.image.NativeImageHeap.ObjectInfo)1 ByteBuffer (java.nio.ByteBuffer)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 ConstantReference (jdk.vm.ci.code.site.ConstantReference)1 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)1 VMConstant (jdk.vm.ci.meta.VMConstant)1 CompilationResult (org.graalvm.compiler.code.CompilationResult)1 CodeAnnotation (org.graalvm.compiler.code.CompilationResult.CodeAnnotation)1 DebugContext (org.graalvm.compiler.debug.DebugContext)1