use of org.jikesrvm.compilers.opt.OptOptions in project JikesRVM by JikesRVM.
the class SpecialCompiler method optCompile.
/**
* <ol>
* <li>generate prologue PSEUDO_bytecode from the state.
* <li>make new bytecodes with prologue.
* <li>set method's bytecode to specialized one.
* <li>adjust exception map, line number map.
* <li>compile the method.
* <li>restore bytecode, exception, linenumber map to the original one.
* </ol>
*
* @param state the execution state for the compilation
* @return the compiled method produced by the optimizing compiler
*/
public static CompiledMethod optCompile(ExecutionState state) {
NormalMethod method = state.getMethod();
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("OPT : starts compiling " + method);
}
ControllerPlan latestPlan = ControllerMemory.findLatestPlan(method);
OptOptions _options = null;
if (latestPlan != null) {
_options = latestPlan.getCompPlan().options.dup();
} else {
// no previous compilation plan, a long run loop promoted from baseline.
// this only happens when testing, not in real code
_options = new OptOptions();
_options.setOptLevel(0);
}
// disable OSR points in specialized method
_options.OSR_GUARDED_INLINING = false;
CompilationPlan compPlan = new CompilationPlan(method, (OptimizationPlanElement[]) RuntimeCompiler.optimizationPlan, null, _options);
// it is also necessary to recompile the current method
// without OSR.
/* generate prologue bytes */
byte[] prologue = state.generatePrologue();
int prosize = prologue.length;
method.setForOsrSpecialization(prologue, state.getMaxStackHeight());
int[] oldStartPCs = null;
int[] oldEndPCs = null;
int[] oldHandlerPCs = null;
/* adjust exception table. */
{
// if (VM.TraceOnStackReplacement) {
// VM.sysWriteln("OPT adjust exception table.");
// }
ExceptionHandlerMap exceptionHandlerMap = method.getExceptionHandlerMap();
if (exceptionHandlerMap != null) {
oldStartPCs = exceptionHandlerMap.getStartPC();
oldEndPCs = exceptionHandlerMap.getEndPC();
oldHandlerPCs = exceptionHandlerMap.getHandlerPC();
int n = oldStartPCs.length;
int[] newStartPCs = new int[n];
System.arraycopy(oldStartPCs, 0, newStartPCs, 0, n);
exceptionHandlerMap.setStartPC(newStartPCs);
int[] newEndPCs = new int[n];
System.arraycopy(oldEndPCs, 0, newEndPCs, 0, n);
exceptionHandlerMap.setEndPC(newEndPCs);
int[] newHandlerPCs = new int[n];
System.arraycopy(oldHandlerPCs, 0, newHandlerPCs, 0, n);
exceptionHandlerMap.setHandlerPC(newHandlerPCs);
for (int i = 0; i < n; i++) {
newStartPCs[i] += prosize;
newEndPCs[i] += prosize;
newHandlerPCs[i] += prosize;
}
}
}
CompiledMethod newCompiledMethod = RuntimeCompiler.recompileWithOptOnStackSpecialization(compPlan);
// restore original bytecode, exception table, and line number table
method.finalizeOsrSpecialization();
{
ExceptionHandlerMap exceptionHandlerMap = method.getExceptionHandlerMap();
if (exceptionHandlerMap != null) {
exceptionHandlerMap.setStartPC(oldStartPCs);
exceptionHandlerMap.setEndPC(oldEndPCs);
exceptionHandlerMap.setHandlerPC(oldHandlerPCs);
}
}
// reverse back to the baseline
if (newCompiledMethod == null) {
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("OPT : fialed, because compilation in progress, " + "fall back to baseline");
}
return baselineCompile(state);
}
// mark the method is a specialized one
newCompiledMethod.setSpecialForOSR();
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("OPT : done");
VM.sysWriteln();
}
return newCompiledMethod;
}
use of org.jikesrvm.compilers.opt.OptOptions in project JikesRVM by JikesRVM.
the class GenerationContextTest method makeNullCheckGuardReturnsSameGuardForSameRegister.
@Test
public void makeNullCheckGuardReturnsSameGuardForSameRegister() throws Exception {
NormalMethod nm = TestingTools.getNormalMethod(MethodsForTests.class, "emptyInstanceMethodWithoutAnnotations");
OptOptions opts = new OptOptions();
GenerationContext gc = new GenerationContext(nm, null, null, opts, null);
int localNumber = 0;
TypeReference localType = nm.getDeclaringClass().getTypeRef();
RegisterOperand regOp = gc.makeLocal(localNumber, localType);
Register reg = regOp.getRegister();
RegisterOperand expectedNullCheckGuard = gc.makeNullCheckGuard(reg);
RegisterOperand actual = gc.makeNullCheckGuard(reg);
assertTrue(actual.sameRegisterPropertiesAs(expectedNullCheckGuard));
}
use of org.jikesrvm.compilers.opt.OptOptions in project JikesRVM by JikesRVM.
the class GenerationContextTest method prologueAndEpilogueForSynchronizedInstanceMethodHaveMonitorEnterAndExit.
@Test
public void prologueAndEpilogueForSynchronizedInstanceMethodHaveMonitorEnterAndExit() throws Exception {
NormalMethod nm = getNormalMethodForTest("emptySynchronizedInstanceMethod");
CompiledMethod cm = new OptCompiledMethod(-1, nm);
OptOptions opts = new OptOptions();
InlineOracle io = new DefaultInlineOracle();
GenerationContext gc = new GenerationContext(nm, null, cm, opts, io);
InlineSequence inlineSequence = new InlineSequence(nm);
assertThatInlineSequenceWasSetCorrectly(gc, inlineSequence);
assertThatLocalsForInstanceMethodWithoutParametersAreCorrect(nm, gc);
RegisterOperand thisOperand = getThisOperand(gc);
BasicBlock prologue = gc.getPrologue();
assertThatPrologueBlockIsSetupCorrectly(gc, inlineSequence, prologue);
assertThatFirstInstructionInPrologueIsPrologue(inlineSequence, prologue);
Enumeration<Instruction> prologueInstructions = prologue.forwardRealInstrEnumerator();
prologueInstructions.nextElement();
Instruction secondInstruction = prologueInstructions.nextElement();
assertThatInstructionIsGuardMoveForPrologue(secondInstruction, thisOperand, gc);
Instruction lastInstruction = prologueInstructions.nextElement();
assertInstructionIsMonitorEnterInPrologue(lastInstruction, inlineSequence);
assertThatGuardIsCorrectForMonitorEnter(lastInstruction);
Operand lockObject = MonitorOp.getRef(lastInstruction);
Operand expectedLockObject = buildLockObjectForInstanceMethod(nm, thisOperand, gc);
assertTrue(expectedLockObject.similar(lockObject));
assertThatNumberOfRealInstructionsMatches(prologue, 3);
BasicBlock epilogue = gc.getEpilogue();
assertThatEpilogueBlockIsSetupCorrectly(gc, inlineSequence, epilogue);
assertThatFirstInstructionEpilogueIsMonitorExit(inlineSequence, epilogue);
assertThatLastInstructionInEpilogueIsReturn(gc, epilogue);
assertThatReturnInstructionReturnsVoid(epilogue);
assertThatNumberOfRealInstructionsMatches(epilogue, 2);
assertThatExitBlockIsSetCorrectly(gc);
assertThatRegisterPoolExists(gc);
assertThatDataIsSavedCorrectly(nm, cm, io, gc);
assertThatReturnValueIsVoid(gc);
assertThatExceptionHandlersWereGenerated(gc);
assertThatUnlockAndRethrowBlockIsCorrect(gc, inlineSequence, prologue, expectedLockObject, epilogue);
assertThatChecksWontBeSkipped(gc);
}
use of org.jikesrvm.compilers.opt.OptOptions in project JikesRVM by JikesRVM.
the class GenerationContextTest method isLocalReturnsTrueForRegistersCreatedViaMakeLocal.
@Test
public void isLocalReturnsTrueForRegistersCreatedViaMakeLocal() throws Exception {
Class<?>[] argumentTypes = { Object.class, double.class, int.class, long.class };
NormalMethod nm = getNormalMethodForTest("emptyInstanceMethodWithParams", argumentTypes);
CompiledMethod cm = new OptCompiledMethod(-1, nm);
OptOptions opts = new OptOptions();
InlineOracle io = new DefaultInlineOracle();
GenerationContext gc = new GenerationContext(nm, null, cm, opts, io);
int thisLocalNumber = 0;
TypeReference localType = nm.getDeclaringClass().getTypeRef();
RegisterOperand thisRegOp = gc.makeLocal(thisLocalNumber, localType);
assertTrue(gc.isLocal(thisRegOp, thisLocalNumber, localType));
}
use of org.jikesrvm.compilers.opt.OptOptions in project JikesRVM by JikesRVM.
the class GenerationContextTest method osrSpecializedMethodsDoNotHaveMonitorEnterButHaveMonitorExit.
@Test
public void osrSpecializedMethodsDoNotHaveMonitorEnterButHaveMonitorExit() throws Exception {
NormalMethod nm = getNormalMethodForTest("emptySynchronizedStaticMethodForOSR");
byte[] osrPrologue = {};
nm.setForOsrSpecialization(osrPrologue, (short) 0);
assertTrue(nm.isForOsrSpecialization());
CompiledMethod cm = new OptCompiledMethod(-1, nm);
OptOptions opts = new OptOptions();
InlineOracle io = new DefaultInlineOracle();
GenerationContext gc = new GenerationContext(nm, null, cm, opts, io);
InlineSequence inlineSequence = new InlineSequence(nm);
assertThatInlineSequenceWasSetCorrectly(gc, inlineSequence);
assertThatNumberOfParametersIs(gc, 0);
BasicBlock prologue = gc.getPrologue();
assertThatPrologueBlockIsSetupCorrectly(gc, inlineSequence, prologue);
assertThatFirstInstructionInPrologueIsPrologue(inlineSequence, prologue);
assertThatNumberOfRealInstructionsMatches(prologue, 1);
BasicBlock epilogue = gc.getEpilogue();
assertThatEpilogueBlockIsSetupCorrectly(gc, inlineSequence, epilogue);
assertThatFirstInstructionEpilogueIsMonitorExit(inlineSequence, epilogue);
assertThatLastInstructionInEpilogueIsReturn(gc, epilogue);
assertThatReturnInstructionReturnsVoid(epilogue);
assertThatNumberOfRealInstructionsMatches(epilogue, 2);
assertThatExitBlockIsSetCorrectly(gc);
assertThatRegisterPoolExists(gc);
assertThatDataIsSavedCorrectly(nm, cm, io, gc);
assertThatReturnValueIsVoid(gc);
assertThatExceptionHandlersWereGenerated(gc);
Operand expectedLockObject = buildLockObjectForStaticMethod(nm);
assertThatUnlockAndRethrowBlockIsCorrect(gc, inlineSequence, prologue, expectedLockObject, epilogue);
assertThatChecksWontBeSkipped(gc);
}
Aggregations