Search in sources :

Example 31 with OptCompiledMethod

use of org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod in project JikesRVM by JikesRVM.

the class GenerationContextTest method inliningInstanceMethodWithRegisterReceiver.

@Test
public void inliningInstanceMethodWithRegisterReceiver() throws Exception {
    NormalMethod nm = getNormalMethodForTest("methodForInliningTests");
    CompiledMethod cm = new OptCompiledMethod(-1, nm);
    OptOptions opts = new OptOptions();
    InlineOracle io = new DefaultInlineOracle();
    GenerationContext gc = new GenerationContext(nm, null, cm, opts, io);
    Class<?>[] argumentTypes = { Object.class, double.class, int.class, long.class };
    NormalMethod callee = getNormalMethodForTest("emptyInstanceMethodWithParams", argumentTypes);
    MethodOperand methOp = MethodOperand.VIRTUAL(callee.getMemberRef().asMethodReference(), callee);
    Instruction callInstr = Call.create(CALL, null, null, methOp, 5);
    RegisterOperand receiver = createMockRegisterOperand(TypeReference.JavaLangObject);
    assertFalse(receiver.isPreciseType());
    assertFalse(receiver.isDeclaredType());
    receiver.setPreciseType();
    Call.setParam(callInstr, 0, receiver);
    RegisterOperand objectParam = prepareCallWithObjectParam(callInstr);
    RegisterOperand doubleParam = prepareCallWithDoubleParam(callInstr);
    RegisterOperand intParam = prepareCallWithIntParam(callInstr);
    RegisterOperand longParam = prepareCallWithLongParam(callInstr);
    callInstr.setPosition(new InlineSequence(nm));
    ExceptionHandlerBasicBlockBag ebag = getMockEbag();
    int nodeNumber = 12345;
    gc.getCfg().setNumberOfNodes(nodeNumber);
    GenerationContext child = gc.createChildContext(ebag, callee, callInstr);
    assertThatStateIsCopiedFromParentToChild(gc, callee, child, ebag);
    assertThatReturnValueIsVoid(child);
    RegisterOperand thisArg = child.getArguments()[0].asRegister();
    assertFalse(thisArg.isPreciseType());
    assertTrue(thisArg.isDeclaredType());
    TypeReference calleeClass = callee.getDeclaringClass().getTypeRef();
    assertSame(thisArg.getType(), calleeClass);
    RegisterOperand expectedLocalForReceiverParam = child.makeLocal(0, thisArg);
    assertTrue(thisArg.sameRegisterPropertiesAs(expectedLocalForReceiverParam));
    RegisterOperand firstArg = child.getArguments()[1].asRegister();
    RegisterOperand expectedLocalForObjectParam = child.makeLocal(1, firstArg);
    assertTrue(firstArg.sameRegisterPropertiesAs(expectedLocalForObjectParam));
    RegisterOperand secondArg = child.getArguments()[2].asRegister();
    RegisterOperand expectedLocalForDoubleParam = child.makeLocal(2, secondArg);
    assertTrue(secondArg.sameRegisterPropertiesAs(expectedLocalForDoubleParam));
    RegisterOperand thirdArg = child.getArguments()[3].asRegister();
    RegisterOperand expectedLocalForIntParam = child.makeLocal(4, thirdArg);
    assertTrue(thirdArg.sameRegisterPropertiesAs(expectedLocalForIntParam));
    RegisterOperand fourthArg = child.getArguments()[4].asRegister();
    RegisterOperand expectedLocalForLongParam = child.makeLocal(5, fourthArg);
    assertTrue(fourthArg.sameRegisterPropertiesAs(expectedLocalForLongParam));
    InlineSequence expectedInlineSequence = new InlineSequence(callee, callInstr.position(), callInstr);
    assertEquals(expectedInlineSequence, child.getInlineSequence());
    assertThatPrologueAndEpilogueAreWiredCorrectlyForChildContext(ebag, nodeNumber, child);
    Enumeration<Instruction> prologueRealInstr = child.getPrologue().forwardRealInstrEnumerator();
    Instruction receiverMove = prologueRealInstr.nextElement();
    RegisterOperand expectedReceiver = receiver.copy().asRegister();
    narrowRegOpToCalleeClass(expectedReceiver, calleeClass);
    assertMoveOperationIsCorrect(callInstr, REF_MOVE, expectedLocalForReceiverParam, expectedReceiver, receiverMove);
    Instruction objectMove = prologueRealInstr.nextElement();
    RegisterOperand objectParamCopy = objectParam.copy().asRegister();
    assertMoveOperationIsCorrect(callInstr, REF_MOVE, expectedLocalForObjectParam, objectParamCopy, objectMove);
    Instruction doubleMove = prologueRealInstr.nextElement();
    RegisterOperand doubleParamCopy = doubleParam.copy().asRegister();
    assertMoveOperationIsCorrect(callInstr, DOUBLE_MOVE, expectedLocalForDoubleParam, doubleParamCopy, doubleMove);
    Instruction intMove = prologueRealInstr.nextElement();
    RegisterOperand intParamCopy = intParam.copy().asRegister();
    assertMoveOperationIsCorrect(callInstr, INT_MOVE, expectedLocalForIntParam, intParamCopy, intMove);
    Instruction longMove = prologueRealInstr.nextElement();
    RegisterOperand longParamCopy = longParam.copy().asRegister();
    assertMoveOperationIsCorrect(callInstr, LONG_MOVE, expectedLocalForLongParam, longParamCopy, longMove);
    assertThatNoMoreInstructionsExist(prologueRealInstr);
    BasicBlock epilogue = child.getEpilogue();
    assertThatEpilogueLabelIsCorrectForInlinedMethod(child, expectedInlineSequence, epilogue);
    assertThatEpilogueIsEmpty(epilogue);
    assertThatNoRethrowBlockExists(child);
    assertThatChecksWontBeSkipped(gc);
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) DefaultInlineOracle(org.jikesrvm.compilers.opt.inlining.DefaultInlineOracle) InlineOracle(org.jikesrvm.compilers.opt.inlining.InlineOracle) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) OptOptions(org.jikesrvm.compilers.opt.OptOptions) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) ExceptionHandlerBasicBlockBag(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) NormalMethod(org.jikesrvm.classloader.NormalMethod) DefaultInlineOracle(org.jikesrvm.compilers.opt.inlining.DefaultInlineOracle) InlineSequence(org.jikesrvm.compilers.opt.inlining.InlineSequence) TypeReference(org.jikesrvm.classloader.TypeReference) Test(org.junit.Test)

Example 32 with OptCompiledMethod

use of org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod in project JikesRVM by JikesRVM.

the class StackTrace method buildStackTrace.

private Element[] buildStackTrace(int first, int last) {
    Element[] elements = new Element[countFrames(first, last)];
    if (!VM.BuildForOptCompiler) {
        int element = 0;
        for (int i = first; i <= last; i++) {
            elements[element] = createStandardStackTraceElement(getCompiledMethod(i), instructionOffsets[i]);
            element++;
        }
    } else {
        int element = 0;
        for (int i = first; i <= last; i++) {
            CompiledMethod compiledMethod = getCompiledMethod(i);
            if ((compiledMethod == null) || (compiledMethod.getCompilerType() != CompiledMethod.OPT)) {
                // Invisible or non-opt compiled method
                elements[element] = createStandardStackTraceElement(compiledMethod, instructionOffsets[i]);
                element++;
            } else {
                Offset instructionOffset = Offset.fromIntSignExtend(instructionOffsets[i]);
                OptCompiledMethod optInfo = (OptCompiledMethod) compiledMethod;
                OptMachineCodeMap map = optInfo.getMCMap();
                int iei = map.getInlineEncodingForMCOffset(instructionOffset);
                if (iei < 0) {
                    elements[element] = createStandardStackTraceElement(compiledMethod, instructionOffsets[i]);
                    element++;
                } else {
                    int[] inlineEncoding = map.inlineEncoding;
                    int bci = map.getBytecodeIndexForMCOffset(instructionOffset);
                    for (; iei >= 0; iei = OptEncodedCallSiteTree.getParent(iei, inlineEncoding)) {
                        int mid = OptEncodedCallSiteTree.getMethodID(iei, inlineEncoding);
                        RVMMethod method = MemberReference.getMethodRef(mid).getResolvedMember();
                        int lineNumber = ((NormalMethod) method).getLineNumberForBCIndex(bci);
                        elements[element] = createOptStackTraceElement(method, lineNumber, instructionOffset, bci);
                        element++;
                        if (iei > 0) {
                            bci = OptEncodedCallSiteTree.getByteCodeOffset(iei, inlineEncoding);
                        }
                    }
                }
            }
        }
    }
    return elements;
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) RVMMethod(org.jikesrvm.classloader.RVMMethod) OptMachineCodeMap(org.jikesrvm.compilers.opt.runtimesupport.OptMachineCodeMap) NormalMethod(org.jikesrvm.classloader.NormalMethod) BaselineCompiledMethod(org.jikesrvm.compilers.baseline.BaselineCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) Offset(org.vmmagic.unboxed.Offset)

Example 33 with OptCompiledMethod

use of org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod in project JikesRVM by JikesRVM.

the class OptExecutionStateExtractor method dumpStackContent.

@SuppressWarnings("unused")
private static void dumpStackContent(byte[] stack, Offset fpOffset) {
    int cmid = Magic.getIntAtOffset(stack, fpOffset.plus(STACKFRAME_METHOD_ID_OFFSET));
    OptCompiledMethod cm = (OptCompiledMethod) CompiledMethods.getCompiledMethod(cmid);
    int firstNonVolatile = cm.getFirstNonVolatileGPR();
    int nonVolatiles = cm.getNumberOfNonvolatileGPRs();
    int nonVolatileOffset = cm.getUnsignedNonVolatileOffset() + (nonVolatiles - 1) * BYTES_IN_STACKSLOT;
    VM.sysWriteln("stack of " + cm.getMethod());
    VM.sysWriteln("      fp offset ", fpOffset);
    VM.sysWriteln(" NV area offset ", nonVolatileOffset);
    VM.sysWriteln("   first NV GPR ", firstNonVolatile);
    Address aFP = Magic.objectAsAddress(stack).plus(fpOffset);
    for (Address a = aFP.plus(nonVolatileOffset); a.GE(aFP); a = a.minus(BYTES_IN_STACKSLOT)) {
        Word content = a.loadWord();
        VM.sysWriteHex(a);
        VM.sysWrite("  ");
        VM.sysWrite(content);
        VM.sysWriteln();
    }
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) Word(org.vmmagic.unboxed.Word) Address(org.vmmagic.unboxed.Address)

Example 34 with OptCompiledMethod

use of org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod in project JikesRVM by JikesRVM.

the class OptExecutionStateExtractor method restoreValuesFromOptSaveVolatile.

/* OptSaveVolatile has different stack layout from DynamicBridge
    * Have to separately recover them now, but there should be unified
    * later on.
    *
    *    |----------|
    *    |   NON    |
    *    |Volatiles |
    *    |          | <-- volatile offset
    *    |Volatiles |
    *    |          |
    *    |FPR states|
    *    |__________|  ___ FP
  */
private void restoreValuesFromOptSaveVolatile(byte[] stack, Offset osrFPoff, TempRegisters registers, int regmap, CompiledMethod cm) {
    OptCompiledMethod tsfromCM = (OptCompiledMethod) cm;
    boolean saveVolatile = tsfromCM.isSaveVolatile();
    if (VM.VerifyAssertions) {
        VM._assert(saveVolatile);
    }
    WordArray gprs = registers.gprs;
    // enter critical section
    // precall methods potientially causing dynamic compilation
    int firstNonVolatile = tsfromCM.getFirstNonVolatileGPR();
    int nonVolatiles = tsfromCM.getNumberOfNonvolatileGPRs();
    int nonVolatileOffset = tsfromCM.getUnsignedNonVolatileOffset() + (nonVolatiles - 1) * BYTES_IN_STACKSLOT;
    VM.disableGC();
    // recover nonvolatile GPRs
    for (int i = firstNonVolatile + nonVolatiles - 1; i >= firstNonVolatile; i--) {
        gprs.set(NONVOLATILE_GPRS[i].value(), Magic.objectAsAddress(stack).loadWord(osrFPoff.minus(nonVolatileOffset)));
        nonVolatileOffset -= BYTES_IN_STACKSLOT;
    }
    // restore with VOLATILES yet
    int volatileOffset = nonVolatileOffset;
    for (int i = NUM_VOLATILE_GPRS - 1; i >= 0; i--) {
        gprs.set(VOLATILE_GPRS[i].value(), Magic.objectAsAddress(stack).loadWord(osrFPoff.minus(volatileOffset)));
        volatileOffset -= BYTES_IN_STACKSLOT;
    }
    // powerPC starts from register 1
    for (int i = 0; i < NUM_GPRS; i++) {
        if (EncodedOSRMap.registerIsSet(regmap, i)) {
            registers.objs[i] = Magic.addressAsObject(registers.gprs.get(i).toAddress());
        }
    }
    VM.enableGC();
    if (VM.TraceOnStackReplacement) {
        for (GPR reg : GPR.values()) {
            VM.sysWrite(reg.toString());
            VM.sysWrite(" = ");
            VM.sysWrite(registers.gprs.get(reg.value()).toAddress());
            VM.sysWriteln();
        }
    }
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) WordArray(org.vmmagic.unboxed.WordArray) GPR(org.jikesrvm.ia32.RegisterConstants.GPR)

Example 35 with OptCompiledMethod

use of org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod in project JikesRVM by JikesRVM.

the class OptExecutionStateExtractor method extractState.

@Override
public ExecutionState extractState(RVMThread thread, Offset osrFPoff, Offset methFPoff, int cmid) {
    /* perform machine and compiler dependent operations here
    * osrFPoff is the fp offset of
    * OptSaveVolatile.threadSwithFrom<...>
    *
    *  (stack grows downward)
    *          foo
    *     |->     <-- methFPoff
    *     |
    *     |    <tsfrom>
    *     |--     <-- osrFPoff
    *
    *
    * The threadSwitchFrom method saves all volatiles, nonvolatiles, and
    * scratch registers. All register values for 'foo' can be obtained
    * from the register save area of '<tsfrom>' method.
    */
    byte[] stack = thread.getStack();
    // get registers for the caller ( real method )
    TempRegisters registers = new TempRegisters(thread.getContextRegisters());
    if (VM.VerifyAssertions) {
        int foocmid = Magic.getIntAtOffset(stack, methFPoff.plus(STACKFRAME_METHOD_ID_OFFSET));
        if (foocmid != cmid) {
            CompiledMethod cm = CompiledMethods.getCompiledMethod(cmid);
            VM.sysWriteln("unmatch method, it should be " + cm.getMethod());
            CompiledMethod foo = CompiledMethods.getCompiledMethod(foocmid);
            VM.sysWriteln("but now it is " + foo.getMethod());
            walkOnStack(stack, osrFPoff);
        }
        VM._assert(foocmid == cmid);
    }
    OptCompiledMethod fooCM = (OptCompiledMethod) CompiledMethods.getCompiledMethod(cmid);
    /* Following code get the machine code offset to the
     * next instruction. All operation of the stack frame
     * are kept in GC critical section.
     * All code in the section should not cause any GC
     * activities, and avoid lazy compilation.
     */
    /* Following code is architecture dependent. In IA32, the return address
     * saved in caller stack frames, so use osrFP to get the next instruction
     * address of foo
     */
    // get the next machine code offset of the real method
    VM.disableGC();
    Address osrFP = Magic.objectAsAddress(stack).plus(osrFPoff);
    Address nextIP = Magic.getReturnAddressUnchecked(osrFP);
    Offset ipOffset = fooCM.getInstructionOffset(nextIP);
    VM.enableGC();
    EncodedOSRMap fooOSRMap = fooCM.getOSRMap();
    /* get register reference map from OSR map
     * we are using this map to convert addresses to objects,
     * thus we can operate objects out of GC section.
     */
    int regmap = fooOSRMap.getRegisterMapForMCOffset(ipOffset);
    {
        int bufCMID = Magic.getIntAtOffset(stack, osrFPoff.plus(STACKFRAME_METHOD_ID_OFFSET));
        CompiledMethod bufCM = CompiledMethods.getCompiledMethod(bufCMID);
        // SaveVolatile can only be compiled by OPT compiler
        if (VM.VerifyAssertions)
            VM._assert(bufCM instanceof OptCompiledMethod);
        restoreValuesFromOptSaveVolatile(stack, osrFPoff, registers, regmap, bufCM);
    }
    // return a list of states: from caller to callee
    // if the osr happens in an inlined method, the state is
    // a chain of recoverd methods.
    ExecutionState state = getExecStateSequence(thread, stack, ipOffset, methFPoff, cmid, osrFPoff, registers, fooOSRMap);
    // reverse callerState points, it becomes callee -> caller
    ExecutionState prevState = null;
    ExecutionState nextState = state;
    while (nextState != null) {
        // 1. current node
        state = nextState;
        // 1. hold the next state first
        nextState = nextState.callerState;
        // 2. redirect pointer
        state.callerState = prevState;
        // 3. move prev to current
        prevState = state;
    }
    if (VM.TraceOnStackReplacement) {
        VM.sysWriteln("OptExecState : recovered states " + thread.toString());
        ExecutionState temp = state;
        do {
            VM.sysWriteln(temp.toString());
            temp = temp.callerState;
        } while (temp != null);
    }
    return state;
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) ExecutionState(org.jikesrvm.osr.ExecutionState) Address(org.vmmagic.unboxed.Address) EncodedOSRMap(org.jikesrvm.osr.EncodedOSRMap) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) Offset(org.vmmagic.unboxed.Offset)

Aggregations

OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)53 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)43 NormalMethod (org.jikesrvm.classloader.NormalMethod)31 OptOptions (org.jikesrvm.compilers.opt.OptOptions)29 DefaultInlineOracle (org.jikesrvm.compilers.opt.inlining.DefaultInlineOracle)28 InlineOracle (org.jikesrvm.compilers.opt.inlining.InlineOracle)28 Test (org.junit.Test)28 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)19 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)18 InlineSequence (org.jikesrvm.compilers.opt.inlining.InlineSequence)17 ExceptionHandlerBasicBlockBag (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag)14 Offset (org.vmmagic.unboxed.Offset)13 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)12 ExceptionHandlerBasicBlock (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)12 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)12 Address (org.vmmagic.unboxed.Address)12 TypeReference (org.jikesrvm.classloader.TypeReference)7 ClassConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand)6 ObjectConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand)6 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)6