use of org.jikesrvm.compilers.common.CompiledMethod in project JikesRVM by JikesRVM.
the class OnStackReplacementEvent method process.
/**
* This function will generate a controller plan and
* inserted in the recompilation queue.
*/
@Override
public void process() {
CompiledMethod compiledMethod = CompiledMethods.getCompiledMethod(CMID);
NormalMethod todoMethod = (NormalMethod) compiledMethod.getMethod();
double priority;
OptOptions options;
OptimizationPlanElement[] optimizationPlan;
ControllerPlan oldPlan = ControllerMemory.findLatestPlan(todoMethod);
if (oldPlan != null) {
CompilationPlan oldCompPlan = oldPlan.getCompPlan();
priority = oldPlan.getPriority();
options = oldCompPlan.options;
optimizationPlan = oldCompPlan.optimizationPlan;
} else {
priority = 5.0;
options = (OptOptions) RuntimeCompiler.options;
optimizationPlan = (OptimizationPlanElement[]) RuntimeCompiler.optimizationPlan;
}
CompilationPlan compPlan = new CompilationPlan(todoMethod, optimizationPlan, null, options);
OnStackReplacementPlan plan = new OnStackReplacementPlan(this.suspendedThread, compPlan, this.CMID, this.whereFrom, this.tsFromFPoff, this.ypTakenFPoff, priority);
Controller.compilationQueue.insert(priority, plan);
AOSLogging.logger.logOsrEvent("OSR inserts compilation plan successfully!");
// do not hold the reference anymore.
suspendedThread = null;
CMID = 0;
}
use of org.jikesrvm.compilers.common.CompiledMethod 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.compilers.common.CompiledMethod in project JikesRVM by JikesRVM.
the class MethodSampleOrganizer method thresholdReached.
@Override
void thresholdReached() {
AOSLogging.logger.organizerThresholdReached();
int numSamples = ((MethodListener) listener).getNumSamples();
int[] samples = ((MethodListener) listener).getSamples();
// (1) Update the global (cumulative) sample data
Controller.methodSamples.update(samples, numSamples);
// (2) Remove duplicates from samples buffer.
// NOTE: This is a dirty trick and may be ill-advised.
// Rather than copying the unique samples into a different buffer
// we treat samples as if it was a scratch buffer.
// NOTE: This is worse case O(numSamples^2) but we expect a
// significant number of duplicates, so it's probably better than
// the other obvious alternative (sorting samples).
int uniqueIdx = 1;
outer: for (int i = 1; i < numSamples; i++) {
int cur = samples[i];
for (int j = 0; j < uniqueIdx; j++) {
if (cur == samples[j])
continue outer;
}
samples[uniqueIdx++] = cur;
}
// then report it to the controller.
for (int i = 0; i < uniqueIdx; i++) {
int cmid = samples[i];
double ns = Controller.methodSamples.getData(cmid);
CompiledMethod cm = CompiledMethods.getCompiledMethod(cmid);
if (cm != null) {
// not already obsoleted
int compilerType = cm.getCompilerType();
// compiled at filterOptLevel or higher.
if (!(compilerType == CompiledMethod.TRAP || (compilerType == CompiledMethod.OPT && (((OptCompiledMethod) cm).getOptLevel() >= filterOptLevel)))) {
HotMethodRecompilationEvent event = new HotMethodRecompilationEvent(cm, ns);
Controller.controllerInputQueue.insert(ns, event);
AOSLogging.logger.controllerNotifiedForHotness(cm, ns);
}
}
}
}
use of org.jikesrvm.compilers.common.CompiledMethod in project JikesRVM by JikesRVM.
the class BaselineBootImageCompiler method compileMethod.
@Override
protected CompiledMethod compileMethod(NormalMethod method, TypeReference[] params) {
CompiledMethod cm;
Callbacks.notifyMethodCompile(method, CompiledMethod.BASELINE);
cm = BaselineCompiler.compile(method);
if (VM.BuildForAdaptiveSystem) {
/* We can't accurately measure compilation time on Host JVM, so just approximate with DNA */
cm.setCompilationTime((float) CompilerDNA.estimateCompileTime(CompilerDNA.BASELINE, method));
}
return cm;
}
use of org.jikesrvm.compilers.common.CompiledMethod 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();
}
Aggregations