use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.
the class DynamicCallGraphOrganizer method thresholdReached.
/**
* Process contents of buffer:
* add call graph edges and increment their weights.
*/
@Override
void thresholdReached() {
if (DEBUG)
VM.sysWriteln("DCG_Organizer.thresholdReached()");
for (int i = 0; i < bufferSize; i = i + 3) {
int calleeCMID = 0;
// FIXME: This is necessary but hacky and may not even be correct.
while (calleeCMID == 0) {
calleeCMID = buffer[i + 0];
}
CompiledMethod compiledMethod = CompiledMethods.getCompiledMethod(calleeCMID);
if (compiledMethod == null)
continue;
RVMMethod callee = compiledMethod.getMethod();
if (callee.isRuntimeServiceMethod()) {
if (DEBUG)
VM.sysWrite("Skipping sample with runtime service callee");
continue;
}
int callerCMID = buffer[i + 1];
compiledMethod = CompiledMethods.getCompiledMethod(callerCMID);
if (compiledMethod == null)
continue;
RVMMethod stackFrameCaller = compiledMethod.getMethod();
int MCOff = buffer[i + 2];
Offset MCOffset = Offset.fromIntSignExtend(buffer[i + 2]);
int bytecodeIndex = -1;
RVMMethod caller = null;
switch(compiledMethod.getCompilerType()) {
case CompiledMethod.TRAP:
case CompiledMethod.JNI:
if (DEBUG)
VM.sysWrite("Skipping sample with TRAP/JNI caller");
continue;
case CompiledMethod.BASELINE:
{
BaselineCompiledMethod baseCompiledMethod = (BaselineCompiledMethod) compiledMethod;
// note: the following call expects the offset in INSTRUCTIONS!
bytecodeIndex = baseCompiledMethod.findBytecodeIndexForInstruction(MCOffset);
caller = stackFrameCaller;
}
break;
case CompiledMethod.OPT:
{
OptCompiledMethod optCompiledMethod = (OptCompiledMethod) compiledMethod;
OptMachineCodeMap mc_map = optCompiledMethod.getMCMap();
try {
bytecodeIndex = mc_map.getBytecodeIndexForMCOffset(MCOffset);
if (bytecodeIndex == -1) {
// so skip the sample.
if (DEBUG) {
VM.sysWrite(" *** SKIP SAMPLE ", stackFrameCaller.toString());
VM.sysWrite("@", compiledMethod.toString());
VM.sysWrite(" at MC offset ", MCOff);
VM.sysWrite(" calling ", callee.toString());
VM.sysWriteln(" due to invalid bytecodeIndex");
}
// skip sample.
continue;
}
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
VM.sysWrite(" ***ERROR: getBytecodeIndexForMCOffset(", MCOffset);
VM.sysWriteln(") ArrayIndexOutOfBounds!");
e.printStackTrace();
if (VM.ErrorsFatal)
VM.sysFail("Exception in AI organizer.");
caller = stackFrameCaller;
// skip sample
continue;
} catch (OptimizingCompilerException e) {
VM.sysWrite("***Error: SKIP SAMPLE: can't find bytecode index in OPT compiled " + stackFrameCaller + "@" + compiledMethod + " at MC offset ", MCOff);
VM.sysWriteln("!");
if (VM.ErrorsFatal)
VM.sysFail("Exception in AI organizer.");
// skip sample
continue;
}
try {
caller = mc_map.getMethodForMCOffset(MCOffset);
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
VM.sysWrite(" ***ERROR: getMethodForMCOffset(", MCOffset);
VM.sysWriteln(") ArrayIndexOutOfBounds!");
e.printStackTrace();
if (VM.ErrorsFatal)
VM.sysFail("Exception in AI organizer.");
caller = stackFrameCaller;
continue;
} catch (OptimizingCompilerException e) {
VM.sysWrite("***Error: SKIP SAMPLE: can't find caller in OPT compiled " + stackFrameCaller + "@" + compiledMethod + " at MC offset ", MCOff);
VM.sysWriteln("!");
if (VM.ErrorsFatal)
VM.sysFail("Exception in AI organizer.");
// skip sample
continue;
}
if (caller == null) {
VM.sysWrite(" ***ERROR: getMethodForMCOffset(", MCOffset);
VM.sysWriteln(") returned null!");
caller = stackFrameCaller;
// skip sample
continue;
}
}
break;
}
// increment the call graph edge, adding it if needed
Controller.dcg.incrementEdge(caller, bytecodeIndex, callee);
}
if (thresholdReachedCount > 0) {
thresholdReachedCount--;
}
}
use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.
the class BulkCompile method compileAllMethods.
/**
* Compile all methods nominated in the compiler advice,
* which should have been provided in a .ca advice file.<p>
*
* This method will be called at boot time (via notifyStartup())
* if ENABLE_PRECOMPILE is true. For replay compilation, this
* method needs to be called explicitly from within the application
* or benchmark harness. Typical usage in a benchmarking context
* would be to call this method at the end of the first iteration
* of the benchmark so that all/most classes were loaded, and
* compilation could occur prior to the second iteration.
*/
public static void compileAllMethods() {
if (!(Controller.options.ENABLE_BULK_COMPILE || Controller.options.ENABLE_PRECOMPILE)) {
/* should not be here */
VM.sysFail("Attempt to perform bulk compilation without setting either -X:aos:enable_bulk_compile=true or -X:aos:enable_precompile=true");
}
EdgeCounts.loadCountsFromFileIfAvailable(VM.EdgeCounterFile);
CompilerAdvice.readCompilerAdvice();
if (Controller.options.BULK_COMPILATION_VERBOSITY >= 1)
VM.sysWriteln(Controller.options.ENABLE_PRECOMPILE ? "Start precompile" : "Start bulk compile");
for (CompilerAdviceAttribute value : CompilerAdviceAttribute.values()) {
if (value.getOptLevel() == -1) {
if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
VM.sysWriteln("Skipping base method: ", value.toString());
} else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
VM.sysWrite(".");
}
continue;
}
ClassLoader cl = RVMClassLoader.findWorkableClassloader(value.getClassName());
if (cl == null)
continue;
TypeReference tRef = TypeReference.findOrCreate(cl, value.getClassName());
RVMClass cls = (RVMClass) tRef.peekType();
if (cls != null) {
// Ensure the class is properly loaded
if (!cls.isInstantiated()) {
if (!cls.isResolved()) {
if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
VM.sysWriteln("Resolving class: ", cls.toString());
} else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
VM.sysWrite("R");
}
cls.resolve();
}
if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
VM.sysWriteln("Instantiating class: ", cls.toString());
} else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
VM.sysWrite("I");
}
cls.instantiate();
}
// Find the method
RVMMethod method = cls.findDeclaredMethod(value.getMethodName(), value.getMethodSig());
// If found, compile it
if ((method != null) && !method.hasNoOptCompileAnnotation() && (method instanceof org.jikesrvm.classloader.NormalMethod)) {
// if user's requirement is higher than advice
if (value.getOptLevel() > Controller.options.DERIVED_MAX_OPT_LEVEL) {
if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
VM.sysWrite("Replay advice overriden by default opt levels. Wanted ");
VM.sysWrite(value.getOptLevel());
VM.sysWrite(", but Controller.options.DERIVED_MAX_OPT_LEVEL: ");
VM.sysWrite(Controller.options.DERIVED_MAX_OPT_LEVEL);
VM.sysWrite(" ");
VM.sysWriteln(value.toString());
} else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
VM.sysWrite(value.getOptLevel(), "!");
}
method.compile();
} else {
CompilationPlan compPlan;
if (Controller.options.counters()) {
// for invocation counter, we only use one optimization level
compPlan = InvocationCounts.createCompilationPlan((NormalMethod) method);
AOSLogging.logger.recompilationStarted(compPlan);
if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
VM.sysWrite("Bulk compiling for counters ");
VM.sysWriteln(value.toString());
}
RuntimeCompiler.recompileWithOpt(compPlan);
AOSLogging.logger.recompilationCompleted(compPlan);
} else if (Controller.options.sampling()) {
// Create our set of standard optimization plans.
compPlan = Controller.recompilationStrategy.createCompilationPlan((NormalMethod) method, value.getOptLevel(), null);
if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
VM.sysWrite("Bulk compiling for sampling ");
VM.sysWriteln(value.toString());
}
if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
VM.sysWrite(value.getOptLevel());
}
AOSLogging.logger.recompilationStarted(compPlan);
RuntimeCompiler.recompileWithOpt(compPlan);
AOSLogging.logger.recompilationCompleted(compPlan);
} else {
if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
VM.sysWrite("Compiler advice file overridden ");
VM.sysWriteln(value.toString());
}
method.compile();
}
}
} else {
if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
VM.sysWrite("Replay failed for ");
VM.sysWrite(value.toString());
VM.sysWrite(" ");
VM.sysWriteln(cl.toString());
} else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
VM.sysWrite("*");
}
}
}
}
AOSLogging.logger.compileAllMethodsCompleted();
if (Controller.options.BULK_COMPILATION_VERBOSITY >= 1)
VM.sysWriteln();
if (Controller.options.BULK_COMPILATION_VERBOSITY >= 1)
VM.sysWriteln("Recompilation complete");
}
use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.
the class BootImageWriter method writeAddressMap.
/**
* Write method address map for use with dbx debugger.
*
* @param fileName name of file to write the map to
*/
private static void writeAddressMap(String mapFileName) throws IOException {
if (verbosity.isAtLeast(SUMMARY))
say("writing ", mapFileName);
// Restore previously unnecessary Statics data structures
Statics.bootImageReportGeneration(staticsJunk);
FileOutputStream fos = new FileOutputStream(mapFileName);
BufferedOutputStream bos = new BufferedOutputStream(fos, 128);
PrintStream out = new PrintStream(bos, false);
out.println("#! /bin/bash");
out.println("# This is a method address map, for use with the ``dbx'' debugger.");
out.println("# To sort by \"code\" address, type \"bash <name-of-this-file>\".");
out.println("# Bootimage data: " + Integer.toHexString(BOOT_IMAGE_DATA_START.toInt()) + "..." + Integer.toHexString(BOOT_IMAGE_DATA_START.toInt() + bootImage.getDataSize()));
out.println("# Bootimage code: " + Integer.toHexString(BOOT_IMAGE_CODE_START.toInt()) + "..." + Integer.toHexString(BOOT_IMAGE_CODE_START.toInt() + bootImage.getCodeSize()));
out.println("# Bootimage refs: " + Integer.toHexString(BOOT_IMAGE_RMAP_START.toInt()) + "..." + Integer.toHexString(BOOT_IMAGE_RMAP_START.toInt() + bootImage.getRMapSize()));
out.println();
out.println("(/bin/grep 'code 0x' | /bin/sort -k 4.3,4) << EOF-EOF-EOF");
out.println();
out.println("JTOC Map");
out.println("--------");
out.println("slot offset category contents details");
out.println("---- ------ -------- -------- -------");
String pad = " ";
// Numeric JTOC fields
for (int jtocSlot = Statics.getLowestInUseSlot(); jtocSlot < Statics.middleOfTable; jtocSlot++) {
Offset jtocOff = Statics.slotAsOffset(jtocSlot);
String category;
String contents;
String details;
RVMField field = getRvmStaticField(jtocOff);
RVMField field2 = getRvmStaticField(jtocOff.plus(4));
boolean couldBeLongLiteral = Statics.isLongSizeLiteral(jtocSlot);
boolean couldBeIntLiteral = Statics.isIntSizeLiteral(jtocSlot);
if (couldBeLongLiteral && ((field == null) || (field2 == null))) {
if ((field == null) && (field2 == null)) {
category = "literal ";
long lval = Statics.getSlotContentsAsLong(jtocOff);
contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
details = lval + "L";
} else if ((field == null) && (field2 != null)) {
category = "literal/field";
long lval = Statics.getSlotContentsAsLong(jtocOff);
contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
details = lval + "L / " + field2.toString();
} else if ((field != null) && (field2 == null)) {
category = "literal/field";
long lval = Statics.getSlotContentsAsLong(jtocOff);
contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
details = lval + "L / " + field.toString();
} else {
throw new Error("Unreachable");
}
jtocSlot++;
} else if (couldBeIntLiteral) {
if (field != null) {
category = "literal/field";
int ival = Statics.getSlotContentsAsInt(jtocOff);
contents = Services.intAsHexString(ival) + pad;
details = Integer.toString(ival) + " / " + field.toString();
} else {
category = "literal ";
int ival = Statics.getSlotContentsAsInt(jtocOff);
contents = Services.intAsHexString(ival) + pad;
details = Integer.toString(ival);
}
} else {
if (field != null) {
category = "field ";
details = field.toString();
TypeReference type = field.getType();
if (type.isIntLikeType()) {
int ival = Statics.getSlotContentsAsInt(jtocOff);
contents = Services.intAsHexString(ival) + pad;
} else if (type.isLongType()) {
long lval = Statics.getSlotContentsAsLong(jtocOff);
contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
jtocSlot++;
} else if (type.isFloatType()) {
int ival = Statics.getSlotContentsAsInt(jtocOff);
contents = Float.toString(Float.intBitsToFloat(ival)) + pad;
} else if (type.isDoubleType()) {
long lval = Statics.getSlotContentsAsLong(jtocOff);
contents = Double.toString(Double.longBitsToDouble(lval)) + pad;
jtocSlot++;
} else if (type.isWordLikeType()) {
if (VM.BuildFor32Addr) {
int ival = Statics.getSlotContentsAsInt(jtocOff);
contents = Services.intAsHexString(ival) + pad;
} else {
long lval = Statics.getSlotContentsAsLong(jtocOff);
contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
jtocSlot++;
}
} else {
// Unknown?
int ival = Statics.getSlotContentsAsInt(jtocOff);
category = "<? - field> ";
details = "<? - " + field.toString() + ">";
contents = Services.intAsHexString(ival) + pad;
}
} else {
// Unknown?
int ival = Statics.getSlotContentsAsInt(jtocOff);
category = "<?> ";
details = "<?>";
contents = Services.intAsHexString(ival) + pad;
}
}
out.println((jtocSlot + " ").substring(0, 8) + Services.addressAsHexString(jtocOff.toWord().toAddress()) + " " + category + " " + contents + " " + details);
}
// Reference JTOC fields
for (int jtocSlot = Statics.middleOfTable, n = Statics.getHighestInUseSlot(); jtocSlot <= n; jtocSlot += Statics.getReferenceSlotSize()) {
Offset jtocOff = Statics.slotAsOffset(jtocSlot);
Object obj = BootImageMap.getObject(getIVal(jtocOff));
String category;
String details;
String contents = Services.addressAsHexString(getReferenceAddr(jtocOff, false)) + pad;
RVMField field = getRvmStaticField(jtocOff);
if (Statics.isReferenceLiteral(jtocSlot)) {
if (field != null) {
category = "literal/field";
} else {
category = "literal ";
}
if (obj == null) {
details = "(null)";
} else if (obj instanceof String) {
details = "\"" + obj + "\"";
} else if (obj instanceof Class) {
details = obj.toString();
;
} else if (obj instanceof TIB) {
category = "literal tib ";
RVMType type = ((TIB) obj).getType();
details = (type == null) ? "?" : type.toString();
} else {
details = "object " + obj.getClass();
}
if (field != null) {
details += " / " + field.toString();
}
} else if (field != null) {
category = "field ";
details = field.toString();
} else if (obj instanceof TIB) {
// TIBs confuse the statics as their backing is written into the boot image
category = "tib ";
RVMType type = ((TIB) obj).getType();
details = (type == null) ? "?" : type.toString();
} else {
category = "unknown ";
if (obj instanceof String) {
details = "\"" + obj + "\"";
} else if (obj instanceof Class) {
details = obj.toString();
} else {
CompiledMethod m = findMethodOfCode(obj);
if (m != null) {
category = "code ";
details = m.getMethod().toString();
} else if (obj != null) {
details = "<?> - unrecognized field or literal of type " + obj.getClass();
} else {
details = "<?>";
}
}
}
out.println((jtocSlot + " ").substring(0, 8) + Services.addressAsHexString(jtocOff.toWord().toAddress()) + " " + category + " " + contents + " " + details);
}
out.println();
out.println("Method Map");
out.println("----------");
out.println(" address method");
out.println(" ------- ------");
out.println();
for (int i = 0; i < CompiledMethods.numCompiledMethods(); ++i) {
CompiledMethod compiledMethod = CompiledMethods.getCompiledMethodUnchecked(i);
if (compiledMethod != null) {
RVMMethod m = compiledMethod.getMethod();
if (m != null && compiledMethod.isCompiled()) {
CodeArray instructions = compiledMethod.getEntryCodeArray();
Address code = BootImageMap.getImageAddress(instructions.getBacking(), true);
out.println(". . code " + Services.addressAsHexString(code) + " " + compiledMethod.getMethod());
}
}
}
// Extra information on the layout of objects in the boot image
if (false) {
out.println();
out.println("Object Map");
out.println("----------");
out.println(" address type");
out.println(" ------- ------");
out.println();
SortedSet<BootImageMap.Entry> set = new TreeSet<BootImageMap.Entry>(new Comparator<BootImageMap.Entry>() {
@Override
public int compare(BootImageMap.Entry a, BootImageMap.Entry b) {
return Integer.valueOf(a.imageAddress.toInt()).compareTo(b.imageAddress.toInt());
}
});
for (Enumeration<BootImageMap.Entry> e = BootImageMap.elements(); e.hasMoreElements(); ) {
BootImageMap.Entry entry = e.nextElement();
set.add(entry);
}
for (Iterator<BootImageMap.Entry> i = set.iterator(); i.hasNext(); ) {
BootImageMap.Entry entry = i.next();
Address data = entry.imageAddress;
out.println(". . data " + Services.addressAsHexString(data) + " " + entry.jdkObject.getClass());
}
}
out.println();
out.println("EOF-EOF-EOF");
out.flush();
out.close();
}
use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.
the class BuildJNIFunctionTable method buildTable.
/**
* Construct the JNIFuntionTable.
* This is not very efficient, but is done at bootImageWriting time,
* so we just don't worry about it.
*/
public static FunctionTable buildTable() {
String[] names = initNames();
FunctionTable functions = FunctionTable.allocate(JNIFunctions.FUNCTIONCOUNT);
RVMClass cls = TypeReference.JNIFunctions.peekType().asClass();
if (VM.VerifyAssertions)
VM._assert(cls.isInstantiated());
for (RVMMethod mth : cls.getDeclaredMethods()) {
String methodName = mth.getName().toString();
int jniIndex = indexOf(names, methodName);
if (jniIndex != -1) {
functions.set(jniIndex, mth.getCurrentEntryCodeArray());
}
}
return functions;
}
use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.
the class FinalMIRExpansion method findOrCreateYieldpointBlock.
/**
* Return a basic block holding the call to a runtime yield service.
* Create a new basic block at the end of the code order if necessary.
*
* @param ir the governing IR
* @param whereFrom is this yieldpoint from the PROLOGUE, EPILOGUE, or a
* BACKEDGE?
*/
static BasicBlock findOrCreateYieldpointBlock(IR ir, int whereFrom) {
RVMMethod meth = null;
PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet().asPPC();
Register zero = phys.getGPR(0);
// state for creating the block
if (whereFrom == RVMThread.PROLOGUE) {
if (ir.MIRInfo.prologueYieldpointBlock != null) {
return ir.MIRInfo.prologueYieldpointBlock;
} else {
meth = Entrypoints.optThreadSwitchFromPrologueMethod;
}
} else if (whereFrom == RVMThread.BACKEDGE) {
if (ir.MIRInfo.backedgeYieldpointBlock != null) {
return ir.MIRInfo.backedgeYieldpointBlock;
} else {
meth = Entrypoints.optThreadSwitchFromBackedgeMethod;
}
} else if (whereFrom == RVMThread.EPILOGUE) {
if (ir.MIRInfo.epilogueYieldpointBlock != null) {
return ir.MIRInfo.epilogueYieldpointBlock;
} else {
meth = Entrypoints.optThreadSwitchFromEpilogueMethod;
}
} else if (whereFrom == RVMThread.OSROPT) {
if (ir.MIRInfo.osrYieldpointBlock != null) {
return ir.MIRInfo.osrYieldpointBlock;
} else {
meth = Entrypoints.optThreadSwitchFromOsrOptMethod;
}
}
// Not found. create new basic block holding the requested yieldpoint
// method
BasicBlock result = new BasicBlock(-1, null, ir.cfg);
ir.cfg.addLastInCodeOrder(result);
Register JTOC = phys.getJTOC();
Register CTR = phys.getCTR();
Offset offset = meth.getOffset();
if (fits(offset, 16)) {
result.appendInstruction(MIR_Load.create(PPC_LAddr, A(zero), A(JTOC), IC(PPCMaskLower16(offset))));
} else {
// not implemented
if (VM.VerifyAssertions)
VM._assert(fits(offset, 32));
result.appendInstruction(MIR_Binary.create(PPC_ADDIS, A(zero), A(JTOC), IC(PPCMaskUpper16(offset))));
result.appendInstruction(MIR_Load.create(PPC_LAddr, A(zero), A(zero), IC(PPCMaskLower16(offset))));
}
result.appendInstruction(MIR_Move.create(PPC_MTSPR, A(CTR), A(zero)));
result.appendInstruction(MIR_Branch.create(PPC_BCTR));
// cache the create block and then return it
if (whereFrom == RVMThread.PROLOGUE) {
ir.MIRInfo.prologueYieldpointBlock = result;
} else if (whereFrom == RVMThread.BACKEDGE) {
ir.MIRInfo.backedgeYieldpointBlock = result;
} else if (whereFrom == RVMThread.EPILOGUE) {
ir.MIRInfo.epilogueYieldpointBlock = result;
} else if (whereFrom == RVMThread.OSROPT) {
ir.MIRInfo.osrYieldpointBlock = result;
}
return result;
}
Aggregations