use of com.oracle.svm.hosted.meta.HostedMethod 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);
}
}
}
use of com.oracle.svm.hosted.meta.HostedMethod in project graal by oracle.
the class NativeImageCodeCache method printCompilationResults.
public void printCompilationResults() {
System.out.println("--- compiled methods");
for (Entry<HostedMethod, CompilationResult> entry : compilations.entrySet()) {
HostedMethod method = entry.getKey();
System.out.format("%8d %5d %s: frame %d\n", method.getCodeAddressOffset(), entry.getValue().getTargetCodeSize(), method.format("%H.%n(%p)"), entry.getValue().getTotalFrameSize());
}
System.out.println("--- vtables:");
for (HostedType type : imageHeap.getUniverse().getTypes()) {
for (int i = 0; i < type.getVTable().length; i++) {
HostedMethod method = type.getVTable()[i];
if (method != null) {
CompilationResult comp = compilations.get(type.getVTable()[i]);
if (comp != null) {
System.out.format("%d %s @ %d: %s = 0x%x\n", type.getTypeID(), type.toJavaName(false), i, method.format("%r %n(%p)"), method.getCodeAddressOffset());
}
}
}
}
}
use of com.oracle.svm.hosted.meta.HostedMethod in project graal by oracle.
the class NativeImageCodeCache method writeCode.
public void writeCode(RelocatableBuffer buffer) {
int startPos = buffer.getPosition();
/*
* Compilation start offsets are relative to the beginning of the code cache (since the heap
* size is not fixed at the time they are computed). This is just startPos, i.e. we start
* emitting the code wherever the buffer is positioned when we're called.
*/
for (Entry<HostedMethod, CompilationResult> entry : compilations.entrySet()) {
HostedMethod method = entry.getKey();
CompilationResult compilation = entry.getValue();
buffer.setPosition(startPos + method.getCodeAddressOffset());
int codeSize = compilation.getTargetCodeSize();
buffer.putBytes(compilation.getTargetCode(), 0, codeSize);
for (int i = codeSize; i < ObjectLayout.roundUp(codeSize, CODE_ALIGNMENT); i++) {
buffer.putByte(CODE_FILLER_BYTE);
}
}
buffer.setPosition(startPos);
}
use of com.oracle.svm.hosted.meta.HostedMethod in project graal by oracle.
the class RelocatableBuffer method targetObjectClassification.
protected static String targetObjectClassification(final Object targetObject) {
final StringBuilder result = new StringBuilder();
if (targetObject == null) {
result.append("null");
} else {
if (targetObject instanceof CFunctionPointer) {
result.append("pointer to function");
if (targetObject instanceof MethodPointer) {
final MethodPointer mp = (MethodPointer) targetObject;
final HostedMethod hm = mp.getMethod();
result.append(" name: ");
result.append(hm.getName());
}
} else {
result.append("pointer to data");
}
}
return result.toString();
}
use of com.oracle.svm.hosted.meta.HostedMethod in project graal by oracle.
the class NativeImageGenerator method printTypes.
private void printTypes() {
for (HostedType type : hUniverse.getTypes()) {
System.out.format("%8d %s ", type.getTypeID(), type.toJavaName(true));
if (type.getSuperclass() != null) {
System.out.format("extends %d %s ", type.getSuperclass().getTypeID(), type.getSuperclass().toJavaName(false));
}
if (type.getInterfaces().length > 0) {
System.out.print("implements ");
String sep = "";
for (HostedInterface interf : type.getInterfaces()) {
System.out.format("%s%d %s", sep, interf.getTypeID(), interf.toJavaName(false));
sep = ", ";
}
System.out.print(" ");
}
if (type.getWrapped().isInstantiated()) {
System.out.print("instantiated ");
}
if (type.getWrapped().isInTypeCheck()) {
System.out.print("inTypeCheck ");
}
System.out.format("assignableFrom %s ", matchesToString(type.getAssignableFromMatches()));
System.out.format("instanceOf typeID %d, # %d ", type.getInstanceOfFromTypeID(), type.getInstanceOfNumTypeIDs());
// if (type.findLeafConcreteSubtype() != null) {
// System.out.format("unique %d %s ", type.findLeafConcreteSubtype().getTypeID(),
// type.findLeafConcreteSubtype().toJavaName(false));
// }
int le = type.getHub().getLayoutEncoding();
if (LayoutEncoding.isPrimitive(le)) {
System.out.print("primitive ");
} else if (LayoutEncoding.isInterface(le)) {
System.out.print("interface ");
} else if (LayoutEncoding.isAbstract(le)) {
System.out.print("abstract ");
} else if (LayoutEncoding.isInstance(le)) {
System.out.format("instance size %d ", LayoutEncoding.getInstanceSize(le).rawValue());
} else if (LayoutEncoding.isObjectArray(le)) {
System.out.format("object array base %d shift %d scale %d ", LayoutEncoding.getArrayBaseOffset(le).rawValue(), LayoutEncoding.getArrayIndexShift(le), LayoutEncoding.getArrayIndexScale(le));
} else if (LayoutEncoding.isPrimitiveArray(le)) {
System.out.format("primitive array base %d shift %d scale %d ", LayoutEncoding.getArrayBaseOffset(le).rawValue(), LayoutEncoding.getArrayIndexShift(le), LayoutEncoding.getArrayIndexScale(le));
} else {
throw VMError.shouldNotReachHere();
}
System.out.println();
for (HostedType sub : type.getSubTypes()) {
System.out.format(" s %d %s\n", sub.getTypeID(), sub.toJavaName(false));
}
if (type.isInterface()) {
for (HostedMethod method : hUniverse.getMethods()) {
if (method.getDeclaringClass() == type) {
printMethod(method, -1);
}
}
} else if (type.isInstanceClass()) {
HostedField[] fields = type.getInstanceFields(false);
fields = Arrays.copyOf(fields, fields.length);
Arrays.sort(fields, Comparator.comparing(HostedField::toString));
for (HostedField field : fields) {
System.out.println(" f " + field.getLocation() + ": " + field.format("%T %n"));
}
HostedMethod[] vtable = type.getVTable();
for (int i = 0; i < vtable.length; i++) {
if (vtable[i] != null) {
printMethod(vtable[i], i);
}
}
for (HostedMethod method : hUniverse.getMethods()) {
if (method.getDeclaringClass() == type && !method.hasVTableIndex()) {
printMethod(method, -1);
}
}
}
}
}
Aggregations