Search in sources :

Example 36 with CompiledMethod

use of org.jikesrvm.compilers.common.CompiledMethod in project JikesRVM by JikesRVM.

the class StackTrace method countFramesUninterruptible.

/**
 * Walk the stack counting the number of stack frames encountered.
 * The stack being walked is our stack, so code is Uninterruptible to stop the
 * stack moving.
 *
 * @param stackTraceThread the thread whose stack is walked
 * @return number of stack frames encountered
 */
@Uninterruptible
@NoInline
private int countFramesUninterruptible(RVMThread stackTraceThread) {
    int stackFrameCount = 0;
    Address fp;
    /* Stack trace for the thread */
    if (stackTraceThread == RVMThread.getCurrentThread()) {
        fp = Magic.getFramePointer();
    } else {
        AbstractRegisters contextRegisters = stackTraceThread.getContextRegisters();
        fp = contextRegisters.getInnermostFramePointer();
    }
    fp = Magic.getCallerFramePointer(fp);
    while (Magic.getCallerFramePointer(fp).NE(StackFrameLayout.getStackFrameSentinelFP())) {
        int compiledMethodId = Magic.getCompiledMethodID(fp);
        if (compiledMethodId != StackFrameLayout.getInvisibleMethodID()) {
            CompiledMethod compiledMethod = CompiledMethods.getCompiledMethod(compiledMethodId);
            if ((compiledMethod.getCompilerType() != CompiledMethod.TRAP) && compiledMethod.hasBridgeFromNativeAnnotation()) {
                // skip native frames, stopping at last native frame preceeding the
                // Java To C transition frame
                fp = RuntimeEntrypoints.unwindNativeStackFrame(fp);
            }
        }
        stackFrameCount++;
        fp = Magic.getCallerFramePointer(fp);
    }
    // VM.sysWriteln("stack frame count = ",stackFrameCount);
    return stackFrameCount;
}
Also used : Address(org.vmmagic.unboxed.Address) AbstractRegisters(org.jikesrvm.architecture.AbstractRegisters) BaselineCompiledMethod(org.jikesrvm.compilers.baseline.BaselineCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) Uninterruptible(org.vmmagic.pragma.Uninterruptible) NoInline(org.vmmagic.pragma.NoInline)

Example 37 with CompiledMethod

use of org.jikesrvm.compilers.common.CompiledMethod in project JikesRVM by JikesRVM.

the class StackTrace method countFrames.

/**
 * Count number of stack frames including those inlined by the opt compiler
 * @param first the first compiled method to look from
 * @param last the last compiled method to look to
 * @return the number of stack frames
 */
private int countFrames(int first, int last) {
    int numElements = 0;
    if (!VM.BuildForOptCompiler) {
        numElements = last - first + 1;
    } else {
        for (int i = first; i <= last; i++) {
            CompiledMethod compiledMethod = getCompiledMethod(i);
            if ((compiledMethod == null) || (compiledMethod.getCompilerType() != CompiledMethod.OPT)) {
                // Invisible or non-opt compiled method
                numElements++;
            } else {
                Offset instructionOffset = Offset.fromIntSignExtend(instructionOffsets[i]);
                OptCompiledMethod optInfo = (OptCompiledMethod) compiledMethod;
                OptMachineCodeMap map = optInfo.getMCMap();
                int iei = map.getInlineEncodingForMCOffset(instructionOffset);
                if (iei < 0) {
                    numElements++;
                } else {
                    int[] inlineEncoding = map.inlineEncoding;
                    for (; iei >= 0; iei = OptEncodedCallSiteTree.getParent(iei, inlineEncoding)) {
                        numElements++;
                    }
                }
            }
        }
    }
    return numElements;
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) OptMachineCodeMap(org.jikesrvm.compilers.opt.runtimesupport.OptMachineCodeMap) 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 38 with CompiledMethod

use of org.jikesrvm.compilers.common.CompiledMethod in project JikesRVM by JikesRVM.

the class StackTrace method lastRealMethod.

/**
 * Find the first non-VM method at the end of the stack trace
 * @param first the first real method of the stack trace
 * @return compiledMethods.length-1 if no non-VM methods found else the index of
 *         the method
 */
private int lastRealMethod(int first) {
    /* We expect an exception on the main thread to look like:
     * at <invisible method>(Unknown Source:0)
     * at org.jikesrvm.runtime.Reflection.invoke(Reflection.java:132)
     * at org.jikesrvm.scheduler.MainThread.run(MainThread.java:195)
     * at org.jikesrvm.scheduler.RVMThread.run(RVMThread.java:534)
     * at org.jikesrvm.scheduler.RVMThread.startoff(RVMThread.java:1113
     *
     * and on another thread to look like:
     * at org.jikesrvm.scheduler.RVMThread.run(RVMThread.java:534)
     * at org.jikesrvm.scheduler.RVMThread.startoff(RVMThread.java:1113)
     */
    int max = compiledMethods.length - 1;
    if (Options.stackTraceFull) {
        return max;
    } else {
        // Start at end of array and elide a frame unless we find a place to stop
        for (int i = max; i >= first; i--) {
            if (compiledMethods[i] == StackFrameLayout.getInvisibleMethodID()) {
                // we found an invisible method, assume next method if this is sane
                if (i - 1 >= 0) {
                    return i - 1;
                } else {
                    // not sane => return max
                    return max;
                }
            }
            CompiledMethod compiledMethod = getCompiledMethod(i);
            if (compiledMethod.getCompilerType() == CompiledMethod.TRAP) {
                // looks like we've gone too low
                return max;
            }
            Class<?> frameClass = compiledMethod.getMethod().getDeclaringClass().getClassForType();
            if ((frameClass != org.jikesrvm.scheduler.MainThread.class) && (frameClass != org.jikesrvm.scheduler.RVMThread.class) && (frameClass != org.jikesrvm.runtime.Reflection.class)) {
                // Found a non-VM method
                return i;
            }
        }
        // No frame found
        return max;
    }
}
Also used : RVMThread(org.jikesrvm.scheduler.RVMThread) BaselineCompiledMethod(org.jikesrvm.compilers.baseline.BaselineCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)

Example 39 with CompiledMethod

use of org.jikesrvm.compilers.common.CompiledMethod in project JikesRVM by JikesRVM.

the class CodeInstaller method install.

public static boolean install(ExecutionState state, CompiledMethod cm) {
    RVMThread thread = state.getThread();
    byte[] stack = thread.getStack();
    Offset tsfromFPOffset = state.getTSFPOffset();
    Offset fooFPOffset = state.getFPOffset();
    int foomid = Magic.getIntAtOffset(stack, fooFPOffset.plus(STACKFRAME_METHOD_ID_OFFSET));
    CompiledMethod foo = CompiledMethods.getCompiledMethod(foomid);
    int cType = foo.getCompilerType();
    // this offset is used to adjust SP to FP right after return
    // from a call. 1 stack slot for return address and
    // 1 stack slot for saved FP of tsfrom.
    Offset sp2fpOffset = fooFPOffset.minus(tsfromFPOffset).minus(2 * BYTES_IN_STACKSLOT);
    // should given an estimated length, and print the instructions
    // for debugging
    Assembler asm = new Assembler(50, VM.TraceOnStackReplacement);
    // 1. generate bridge instructions to recover saved registers
    if (cType == CompiledMethod.BASELINE) {
        // unwind stack pointer, SP is FP now
        if (VM.BuildFor32Addr) {
            asm.emitADD_Reg_Imm(SP, sp2fpOffset.toInt());
        } else {
            asm.emitADD_Reg_Imm_Quad(SP, sp2fpOffset.toInt());
        }
        asm.generateJTOCloadWord(S0, cm.getOsrJTOCoffset());
        // restore saved EDI
        if (VM.BuildFor32Addr) {
            asm.emitMOV_Reg_RegDisp(EDI, SP, EDI_SAVE_OFFSET);
        } else {
            asm.emitMOV_Reg_RegDisp_Quad(EDI, SP, EDI_SAVE_OFFSET);
        }
        // restore saved EBX
        if (VM.BuildFor32Addr) {
            asm.emitMOV_Reg_RegDisp(EBX, SP, EBX_SAVE_OFFSET);
        } else {
            asm.emitMOV_Reg_RegDisp_Quad(EBX, SP, EBX_SAVE_OFFSET);
        }
        // restore frame pointer
        asm.emitPOP_RegDisp(TR, ArchEntrypoints.framePointerField.getOffset());
        // do not pop return address and parameters,
        // we make a faked call to newly compiled method
        asm.emitJMP_Reg(S0);
    } else if (cType == CompiledMethod.OPT) {
        // /////////////////////////////////////////////////
        // recover saved registers from foo's stack frame
        // /////////////////////////////////////////////////
        OptCompiledMethod fooOpt = (OptCompiledMethod) foo;
        // foo definitely not save volatile
        boolean saveVolatile = fooOpt.isSaveVolatile();
        if (VM.VerifyAssertions) {
            VM._assert(!saveVolatile);
        }
        // assume SP is on foo's stack frame,
        int firstNonVolatile = fooOpt.getFirstNonVolatileGPR();
        int nonVolatiles = fooOpt.getNumberOfNonvolatileGPRs();
        int nonVolatileOffset = fooOpt.getUnsignedNonVolatileOffset();
        for (int i = firstNonVolatile; i < firstNonVolatile + nonVolatiles; i++) {
            if (VM.BuildFor32Addr) {
                asm.emitMOV_Reg_RegDisp(NONVOLATILE_GPRS[i], SP, sp2fpOffset.minus(nonVolatileOffset));
            } else {
                asm.emitMOV_Reg_RegDisp_Quad(NONVOLATILE_GPRS[i], SP, sp2fpOffset.minus(nonVolatileOffset));
            }
            nonVolatileOffset += BYTES_IN_STACKSLOT;
        }
        // adjust SP to frame pointer
        if (VM.BuildFor32Addr) {
            asm.emitADD_Reg_Imm(SP, sp2fpOffset.toInt());
        } else {
            asm.emitADD_Reg_Imm_Quad(SP, sp2fpOffset.toInt());
        }
        // restore frame pointer
        asm.emitPOP_RegDisp(TR, ArchEntrypoints.framePointerField.getOffset());
        // branch to the newly compiled instructions
        asm.generateJTOCjmp(cm.getOsrJTOCoffset());
    }
    if (VM.TraceOnStackReplacement) {
        VM.sysWrite("new CM instr addr ");
        VM.sysWriteHex(Statics.getSlotContentsAsAddress(cm.getOsrJTOCoffset()));
        VM.sysWriteln();
        VM.sysWrite("JTOC register ");
        VM.sysWriteHex(Magic.getTocPointer());
        VM.sysWriteln();
        VM.sysWrite("Thread register ");
        VM.sysWriteHex(Magic.objectAsAddress(Magic.getThreadRegister()));
        VM.sysWriteln();
        VM.sysWriteln("tsfromFPOffset ", tsfromFPOffset);
        VM.sysWriteln("fooFPOffset ", fooFPOffset);
        VM.sysWriteln("SP + ", sp2fpOffset.plus(BYTES_IN_STACKSLOT));
    }
    // 3. set thread flags
    thread.isWaitingForOsr = true;
    thread.bridgeInstructions = asm.getMachineCodes();
    thread.fooFPOffset = fooFPOffset;
    thread.tsFPOffset = tsfromFPOffset;
    Address bridgeaddr = Magic.objectAsAddress(thread.bridgeInstructions);
    Memory.sync(bridgeaddr, thread.bridgeInstructions.length() << LG_INSTRUCTION_WIDTH);
    AOSLogging.logger.logOsrEvent("OSR code installation succeeded");
    return true;
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) Address(org.vmmagic.unboxed.Address) RVMThread(org.jikesrvm.scheduler.RVMThread) Assembler(org.jikesrvm.compilers.common.assembler.ia32.Assembler) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) Offset(org.vmmagic.unboxed.Offset)

Example 40 with CompiledMethod

use of org.jikesrvm.compilers.common.CompiledMethod 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 <tsfrom> 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) {
            for (Offset o = osrFPoff; o.sGE(methFPoff.minus(2 * BYTES_IN_ADDRESS)); o = o.minus(BYTES_IN_ADDRESS)) {
                VM.sysWriteHex(Magic.objectAsAddress(stack).plus(o));
                VM.sysWrite(" : ");
                VM.sysWriteHex(Magic.getWordAtOffset(stack, o).toAddress());
                VM.sysWriteln();
            }
            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.
     */
    // get the next machine code offset of the real method
    VM.disableGC();
    Address methFP = Magic.objectAsAddress(stack).plus(methFPoff);
    Address nextIP = Magic.getNextInstructionAddress(methFP);
    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
    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("OptExecutionState : recovered states");
        ExecutionState temp = state;
        while (temp != null) {
            VM.sysWriteln(temp.toString());
            temp = temp.callerState;
        }
    }
    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

CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)97 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)56 NormalMethod (org.jikesrvm.classloader.NormalMethod)41 Test (org.junit.Test)33 OptOptions (org.jikesrvm.compilers.opt.OptOptions)32 Address (org.vmmagic.unboxed.Address)30 DefaultInlineOracle (org.jikesrvm.compilers.opt.inlining.DefaultInlineOracle)28 InlineOracle (org.jikesrvm.compilers.opt.inlining.InlineOracle)28 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)20 Offset (org.vmmagic.unboxed.Offset)20 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)19 InlineSequence (org.jikesrvm.compilers.opt.inlining.InlineSequence)17 RVMMethod (org.jikesrvm.classloader.RVMMethod)14 ExceptionHandlerBasicBlockBag (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag)14 TypeReference (org.jikesrvm.classloader.TypeReference)13 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)13 ExceptionHandlerBasicBlock (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)13 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)13 BaselineCompiledMethod (org.jikesrvm.compilers.baseline.BaselineCompiledMethod)10 RVMClass (org.jikesrvm.classloader.RVMClass)7