Search in sources :

Example 1 with HostedImageHeapConstantPatch

use of com.oracle.svm.hosted.code.HostedImageHeapConstantPatch in project graal by oracle.

the class AMD64HostedPatcher method afterRegistration.

@Override
public void afterRegistration(AfterRegistrationAccess access) {
    ImageSingletons.add(PatchConsumerFactory.HostedPatchConsumerFactory.class, new PatchConsumerFactory.HostedPatchConsumerFactory() {

        @Override
        public Consumer<Assembler.CodeAnnotation> newConsumer(CompilationResult compilationResult) {
            return new Consumer<>() {

                @Override
                public void accept(Assembler.CodeAnnotation annotation) {
                    if (annotation instanceof OperandDataAnnotation) {
                        compilationResult.addAnnotation(new AMD64HostedPatcher((OperandDataAnnotation) annotation));
                    } else if (annotation instanceof AddressDisplacementAnnotation) {
                        AddressDisplacementAnnotation dispAnnotation = (AddressDisplacementAnnotation) annotation;
                        compilationResult.addAnnotation(new HostedImageHeapConstantPatch(dispAnnotation.operandPosition, (SubstrateObjectConstant) dispAnnotation.annotation));
                    }
                }
            };
        }
    });
}
Also used : OperandDataAnnotation(org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandDataAnnotation) Consumer(java.util.function.Consumer) SubstrateObjectConstant(com.oracle.svm.core.meta.SubstrateObjectConstant) HostedImageHeapConstantPatch(com.oracle.svm.hosted.code.HostedImageHeapConstantPatch) PatchConsumerFactory(com.oracle.svm.core.graal.code.PatchConsumerFactory) CompilationResult(org.graalvm.compiler.code.CompilationResult) Assembler(org.graalvm.compiler.asm.Assembler) AddressDisplacementAnnotation(org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.AddressDisplacementAnnotation)

Example 2 with HostedImageHeapConstantPatch

use of com.oracle.svm.hosted.code.HostedImageHeapConstantPatch in project graal by oracle.

the class NativeImageCodeCache method addConstantsToHeap.

public void addConstantsToHeap() {
    for (DataSection.Data data : dataSection) {
        if (data instanceof SubstrateDataBuilder.ObjectData) {
            JavaConstant constant = ((SubstrateDataBuilder.ObjectData) data).getConstant();
            addConstantToHeap(constant, "data section");
        }
    }
    for (CompilationResult compilationResult : compilations.values()) {
        for (DataPatch patch : compilationResult.getDataPatches()) {
            if (patch.reference instanceof ConstantReference) {
                addConstantToHeap(((ConstantReference) patch.reference).getConstant(), compilationResult.getName());
            }
        }
        for (CompilationResult.CodeAnnotation codeAnnotation : compilationResult.getCodeAnnotations()) {
            if (codeAnnotation instanceof HostedImageHeapConstantPatch) {
                addConstantToHeap(((HostedImageHeapConstantPatch) codeAnnotation).constant, compilationResult.getName());
            }
        }
    }
}
Also used : ConstantReference(jdk.vm.ci.code.site.ConstantReference) DataPatch(jdk.vm.ci.code.site.DataPatch) DataSection(org.graalvm.compiler.code.DataSection) HostedImageHeapConstantPatch(com.oracle.svm.hosted.code.HostedImageHeapConstantPatch) JavaConstant(jdk.vm.ci.meta.JavaConstant) CompilationResult(org.graalvm.compiler.code.CompilationResult)

Example 3 with HostedImageHeapConstantPatch

use of com.oracle.svm.hosted.code.HostedImageHeapConstantPatch 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)

Aggregations

HostedImageHeapConstantPatch (com.oracle.svm.hosted.code.HostedImageHeapConstantPatch)3 CompilationResult (org.graalvm.compiler.code.CompilationResult)3 DataPatch (jdk.vm.ci.code.site.DataPatch)2 PatchConsumerFactory (com.oracle.svm.core.graal.code.PatchConsumerFactory)1 SubstrateObjectConstant (com.oracle.svm.core.meta.SubstrateObjectConstant)1 HostedPatcher (com.oracle.svm.hosted.code.HostedPatcher)1 ObjectInfo (com.oracle.svm.hosted.image.NativeImageHeap.ObjectInfo)1 HostedMethod (com.oracle.svm.hosted.meta.HostedMethod)1 ByteBuffer (java.nio.ByteBuffer)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Consumer (java.util.function.Consumer)1 Call (jdk.vm.ci.code.site.Call)1 ConstantReference (jdk.vm.ci.code.site.ConstantReference)1 Infopoint (jdk.vm.ci.code.site.Infopoint)1 Reference (jdk.vm.ci.code.site.Reference)1 JavaConstant (jdk.vm.ci.meta.JavaConstant)1 Assembler (org.graalvm.compiler.asm.Assembler)1 AddressDisplacementAnnotation (org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.AddressDisplacementAnnotation)1 OperandDataAnnotation (org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandDataAnnotation)1