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);
}
}
}
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));
}
}
}
}
Aggregations