use of org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod 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.opt.runtimesupport.OptCompiledMethod 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.opt.runtimesupport.OptCompiledMethod in project JikesRVM by JikesRVM.
the class OptExceptionDeliverer method deliverException.
/**
* Pass control to a catch block.
*/
@Override
@Unpreemptible("Deliver exception possibly from unpreemptible code")
public void deliverException(CompiledMethod compiledMethod, Address catchBlockInstructionAddress, Throwable exceptionObject, AbstractRegisters registers) {
OptCompiledMethod optMethod = (OptCompiledMethod) compiledMethod;
Address fp = registers.getInnermostFramePointer();
RVMThread myThread = RVMThread.getCurrentThread();
if (TRACE) {
VM.sysWrite("Frame size of ");
VM.sysWrite(optMethod.getMethod());
VM.sysWrite(" is ");
VM.sysWrite(optMethod.getFrameFixedSize());
VM.sysWriteln();
}
// reset sp to "empty params" state (ie same as it was after prologue)
Address sp = fp.minus(optMethod.getFrameFixedSize());
registers.getGPRs().set(STACK_POINTER.value(), sp.toWord());
// store exception object for later retrieval by catch block
int offset = optMethod.getUnsignedExceptionOffset();
if (offset != 0) {
// only put the exception object in the stackframe if the catch block is expecting it.
// (if the method hasn't allocated a stack slot for caught exceptions, then we can safely
// drop the exceptionObject on the floor).
Magic.setObjectAtOffset(Magic.addressAsObject(fp), Offset.fromIntSignExtend(-offset), exceptionObject);
if (TRACE) {
VM.sysWrite("Storing exception object ");
VM.sysWrite(Magic.objectAsAddress(exceptionObject));
VM.sysWrite(" at offset ");
VM.sysWrite(offset);
VM.sysWrite(" from framepoint ");
VM.sysWrite(fp);
VM.sysWriteln();
}
}
if (TRACE) {
VM.sysWrite("Registers before delivering exception in ");
VM.sysWrite(optMethod.getMethod());
VM.sysWriteln();
for (GPR reg : GPR.values()) {
VM.sysWrite(reg.toString());
VM.sysWrite(" = ");
VM.sysWrite(registers.getGPRs().get(reg.value()));
VM.sysWriteln();
}
}
// set address at which to resume executing frame
registers.setIP(catchBlockInstructionAddress);
if (TRACE) {
VM.sysWrite("Set ip to ");
VM.sysWrite(registers.getIP());
VM.sysWriteln();
}
// disabled right before RuntimeEntrypoints.deliverException was called
VM.enableGC();
if (VM.VerifyAssertions)
VM._assert(registers.getInUse());
registers.setInUse(false);
// 'give back' the portion of the stack we borrowed to run
// exception delivery code when invoked for a hardware trap.
// If this was a straight software trap (athrow) then setting
// the stacklimit should be harmless, since the stacklimit should already have exactly
// the value we are setting it too.
myThread.stackLimit = Magic.objectAsAddress(myThread.getStack()).plus(STACK_SIZE_GUARD);
// "branches" to catchBlockInstructionAddress
Magic.restoreHardwareExceptionState(registers);
if (VM.VerifyAssertions)
VM._assert(NOT_REACHED);
}
use of org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod in project JikesRVM by JikesRVM.
the class OptExceptionDeliverer method unwindStackFrame.
/**
* Unwind a stackframe.
*/
@Override
@Unpreemptible("Unwind stack possibly from unpreemptible code")
public void unwindStackFrame(CompiledMethod compiledMethod, AbstractRegisters registers) {
Address fp = registers.getInnermostFramePointer();
OptCompiledMethod optMethod = (OptCompiledMethod) compiledMethod;
if (TRACE) {
VM.sysWrite("Registers before unwinding frame for ");
VM.sysWrite(optMethod.getMethod());
VM.sysWriteln();
for (GPR reg : GPR.values()) {
VM.sysWrite(reg.toString());
VM.sysWrite(" = ");
VM.sysWrite(registers.getGPRs().get(reg.value()));
VM.sysWriteln();
}
}
// restore non-volatile registers
int frameOffset = optMethod.getUnsignedNonVolatileOffset();
for (int i = optMethod.getFirstNonVolatileGPR(); i < NUM_NONVOLATILE_GPRS; i++, frameOffset += BYTES_IN_ADDRESS) {
registers.getGPRs().set(NONVOLATILE_GPRS[i].value(), fp.minus(frameOffset).loadWord());
}
if (VM.VerifyAssertions)
VM._assert(NUM_NONVOLATILE_FPRS == 0);
registers.unwindStackFrame();
if (TRACE) {
VM.sysWrite("Registers after unwinding frame for ");
VM.sysWrite(optMethod.getMethod());
VM.sysWriteln();
for (GPR reg : GPR.values()) {
VM.sysWrite(reg.toString());
VM.sysWrite(" = ");
VM.sysWrite(registers.getGPRs().get(reg.value()));
VM.sysWriteln();
}
}
}
use of org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod in project JikesRVM by JikesRVM.
the class OptExceptionDeliverer method deliverException.
/**
* Pass control to a catch block.
*/
@Override
@Unpreemptible("Deliver exception possibly from unpreemptible code")
public void deliverException(CompiledMethod cm, Address catchBlockInstructionAddress, Throwable exceptionObject, AbstractRegisters registers) {
// store exception object for later retrieval by catch block
OptCompiledMethod compiledMethod = (OptCompiledMethod) cm;
Offset offset = Offset.fromIntSignExtend(compiledMethod.getUnsignedExceptionOffset());
if (!offset.isZero()) {
// only put the exception object in the stackframe if the catch block is expecting it.
// (if the method hasn't allocated a stack slot for caught exceptions, then we can safely
// drop the exceptionObject on the floor).
Address fp = registers.getInnermostFramePointer();
Magic.setObjectAtOffset(Magic.addressAsObject(fp), offset, exceptionObject);
}
// set address at which to resume executing frame
registers.setIP(catchBlockInstructionAddress);
// disabled right before Runtime.deliverException was called
VM.enableGC();
if (VM.VerifyAssertions)
VM._assert(registers.getInUse());
registers.setInUse(false);
// "branches" to catchBlockInstructionAddress
Magic.restoreHardwareExceptionState(registers);
if (VM.VerifyAssertions)
VM._assert(NOT_REACHED);
}
Aggregations