Search in sources :

Example 1 with ArchBaselineCompiledMethod

use of org.jikesrvm.compilers.baseline.ia32.ArchBaselineCompiledMethod in project JikesRVM by JikesRVM.

the class BaselineExecutionStateExtractor method extractState.

/**
 * Implements ExecutionStateExtractor.extractState.
 *
 * @param thread : the suspended thread, the registers and stack frames are used.
 * @param osrFPoff : the osr method's stack frame offset
 * @param methFPoff : the real method's stack frame offset
 * @param cmid   : the top application method ( system calls are unwounded ).
 *
 * return a ExecutionStateExtractor object.
 */
@Override
public ExecutionState extractState(RVMThread thread, Offset osrFPoff, Offset methFPoff, int cmid) {
    if (VM.TraceOnStackReplacement) {
        VM.sysWriteln("BASE execStateExtractor starting ...");
    }
    byte[] stack = thread.getStack();
    if (VM.VerifyAssertions) {
        int fooCmid = Magic.getIntAtOffset(stack, methFPoff.plus(STACKFRAME_METHOD_ID_OFFSET));
        if (VM.TraceOnStackReplacement) {
            VM.sysWriteln("fooCmid = " + fooCmid);
            VM.sysWriteln("   cmid = " + cmid);
        }
        VM._assert(fooCmid == cmid);
    }
    ArchBaselineCompiledMethod fooCM = (ArchBaselineCompiledMethod) CompiledMethods.getCompiledMethod(cmid);
    NormalMethod fooM = (NormalMethod) fooCM.getMethod();
    VM.disableGC();
    Address rowIP = Magic.objectAsAddress(stack).loadAddress(osrFPoff.plus(STACKFRAME_RETURN_ADDRESS_OFFSET));
    Offset ipOffset = fooCM.getInstructionOffset(rowIP);
    VM.enableGC();
    // CAUTION: IP Offset should point to next instruction
    int bcIndex = fooCM.findBytecodeIndexForInstruction(ipOffset.plus(INSTRUCTION_WIDTH));
    // assertions
    if (VM.VerifyAssertions) {
        if (bcIndex == -1) {
            VM.sysWriteln("osrFPoff = ", osrFPoff);
            VM.sysWriteln("instr_beg = ", Magic.objectAsAddress(fooCM.getEntryCodeArray()));
            for (int i = (osrFPoff.toInt()) - 10; i < (osrFPoff.toInt()) + 10; i++) {
                VM.sysWriteln("  stack[" + i + "] = " + stack[i]);
            }
            Offset ipIndex = ipOffset.toWord().rsha(LG_INSTRUCTION_WIDTH).toOffset();
            VM.sysWriteln("ipIndex : ", ipIndex);
            VM.sysWriteln("bcIndex : " + bcIndex);
        }
        VM._assert(bcIndex != -1);
    }
    // create execution state object
    ExecutionState state = new ExecutionState(thread, methFPoff, cmid, bcIndex, osrFPoff);
    /* extract values for local and stack, but first of all
     * we need to get type information for current PC.
     */
    BytecodeTraverser typer = new BytecodeTraverser();
    typer.computeLocalStackTypes(fooM, bcIndex);
    byte[] localTypes = typer.getLocalTypes();
    byte[] stackTypes = typer.getStackTypes();
    if (VM.TraceOnStackReplacement) {
        VM.sysWriteln("BC Index : " + bcIndex);
        VM.sysWrite("Local Types :");
        for (byte localType : localTypes) {
            VM.sysWrite(" " + (char) localType);
        }
        VM.sysWriteln();
        VM.sysWrite("Stack Types :");
        for (byte stackType : stackTypes) {
            VM.sysWrite(" " + (char) stackType);
        }
        VM.sysWriteln();
    }
    // type. We should remove non-reference type
    for (int i = 0, n = localTypes.length; i < n; i++) {
        // then set the localType to uninitialized, see VM spec, bytecode verifier
        if (localTypes[i] == ClassTypeCode) {
            if (!fooCM.referenceMaps.isLocalRefType(fooM, ipOffset.plus(1 << LG_INSTRUCTION_WIDTH), i)) {
                localTypes[i] = VoidTypeCode;
                if (VM.TraceOnStackReplacement) {
                    VM.sysWriteln("GC maps disagrees with type matcher at " + i + "th local");
                    VM.sysWriteln();
                }
            }
        }
    }
    // go through the stack frame and extract values
    // In the variable value list, we keep the order as follows:
    // L0, L1, ..., S0, S1, ....
    // adjust local offset and stack offset
    // NOTE: do not call BaselineCompilerImpl.getFirstLocalOffset(method)
    Offset startLocalOffset = methFPoff.plus(BaselineCompilerImpl.locationToOffset(fooCM.getGeneralLocalLocation(0)));
    Offset stackOffset = methFPoff.plus(fooCM.getEmptyStackOffset());
    // for locals
    getVariableValue(stack, startLocalOffset, localTypes, fooCM, LOCAL, state);
    // for stacks
    getVariableValue(stack, stackOffset, stackTypes, fooCM, STACK, state);
    if (VM.TraceOnStackReplacement) {
        state.printState();
    }
    if (VM.TraceOnStackReplacement) {
        VM.sysWriteln("BASE executionStateExtractor done ");
    }
    return state;
}
Also used : ArchBaselineCompiledMethod(org.jikesrvm.compilers.baseline.ia32.ArchBaselineCompiledMethod) ExecutionState(org.jikesrvm.osr.ExecutionState) Address(org.vmmagic.unboxed.Address) NormalMethod(org.jikesrvm.classloader.NormalMethod) BytecodeTraverser(org.jikesrvm.osr.BytecodeTraverser) Offset(org.vmmagic.unboxed.Offset)

Aggregations

NormalMethod (org.jikesrvm.classloader.NormalMethod)1 ArchBaselineCompiledMethod (org.jikesrvm.compilers.baseline.ia32.ArchBaselineCompiledMethod)1 BytecodeTraverser (org.jikesrvm.osr.BytecodeTraverser)1 ExecutionState (org.jikesrvm.osr.ExecutionState)1 Address (org.vmmagic.unboxed.Address)1 Offset (org.vmmagic.unboxed.Offset)1