Search in sources :

Example 1 with VariableElement

use of org.jikesrvm.osr.VariableElement in project JikesRVM by JikesRVM.

the class BaselineExecutionStateExtractor method getVariableValue.

/* go over local/stack array, and build VariableElement. */
private static void getVariableValue(byte[] stack, Offset offset, byte[] types, ArchBaselineCompiledMethod compiledMethod, boolean kind, ExecutionState state) {
    int size = types.length;
    Offset vOffset = offset;
    for (int i = 0; i < size; i++) {
        if (VM.TraceOnStackReplacement) {
            Word content = Magic.getWordAtOffset(stack, vOffset.minus(BYTES_IN_ADDRESS));
            VM.sysWrite("0x", vOffset.minus(BYTES_IN_ADDRESS), "    0x");
            VM.sysWriteln(content);
            if ((types[i] == LongTypeCode) || (types[i] == DoubleTypeCode)) {
                content = Magic.getWordAtOffset(stack, vOffset.minus(2 * BYTES_IN_ADDRESS));
                VM.sysWrite("0x", vOffset.minus(2 * BYTES_IN_ADDRESS), "    0x");
                VM.sysWriteln(content);
            }
        }
        switch(types[i]) {
            case VoidTypeCode:
                vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
                break;
            case BooleanTypeCode:
            case ByteTypeCode:
            case ShortTypeCode:
            case CharTypeCode:
            case IntTypeCode:
            case FloatTypeCode:
                {
                    int value = Magic.getIntAtOffset(stack, vOffset.minus(BYTES_IN_STACKSLOT));
                    vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
                    byte tcode = (types[i] == FloatTypeCode) ? FLOAT : INT;
                    state.add(new VariableElement(kind, i, tcode, value));
                    break;
                }
            case LongTypeCode:
            case DoubleTypeCode:
                {
                    // KV: this code would be nicer if VoidTypeCode would always follow a 64-bit value. Rigth now for LOCAL it follows, for STACK it proceeds
                    Offset memoff = (kind == LOCAL) ? vOffset.minus(2 * BYTES_IN_STACKSLOT) : vOffset.minus(BYTES_IN_STACKSLOT);
                    long value = Magic.getLongAtOffset(stack, memoff);
                    byte tcode = (types[i] == LongTypeCode) ? LONG : DOUBLE;
                    state.add(new VariableElement(kind, i, tcode, value));
                    if (kind == LOCAL) {
                        // KV:VoidTypeCode is next
                        vOffset = vOffset.minus(2 * BYTES_IN_STACKSLOT);
                        i++;
                    } else {
                        // KV:VoidTypeCode was already in front
                        vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
                    }
                    break;
                }
            case ReturnAddressTypeCode:
                {
                    VM.disableGC();
                    Address rowIP = Magic.objectAsAddress(stack).loadAddress(vOffset);
                    Offset ipOffset = compiledMethod.getInstructionOffset(rowIP);
                    VM.enableGC();
                    vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
                    if (VM.TraceOnStackReplacement) {
                        Offset ipIndex = ipOffset.toWord().rsha(LG_INSTRUCTION_WIDTH).toOffset();
                        VM.sysWrite("baseline ret_addr ip ", ipIndex, " --> ");
                    }
                    int bcIndex = compiledMethod.findBytecodeIndexForInstruction(ipOffset.plus(INSTRUCTION_WIDTH));
                    if (VM.TraceOnStackReplacement) {
                        VM.sysWriteln(" bc " + bcIndex);
                    }
                    state.add(new VariableElement(kind, i, RET_ADDR, bcIndex));
                    break;
                }
            case ClassTypeCode:
            case ArrayTypeCode:
                {
                    VM.disableGC();
                    Object ref = Magic.getObjectAtOffset(stack, vOffset.minus(BYTES_IN_ADDRESS));
                    VM.enableGC();
                    vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
                    state.add(new VariableElement(kind, i, REF, ref));
                    break;
                }
            case WordTypeCode:
                {
                    Word value = Magic.getWordAtOffset(stack, vOffset.minus(BYTES_IN_ADDRESS));
                    vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
                    state.add(new VariableElement(kind, i, WORD, value));
                    break;
                }
            default:
                if (VM.VerifyAssertions)
                    VM._assert(VM.NOT_REACHED);
                break;
        }
    // switch
    }
// for loop
}
Also used : Word(org.vmmagic.unboxed.Word) Address(org.vmmagic.unboxed.Address) VariableElement(org.jikesrvm.osr.VariableElement) Offset(org.vmmagic.unboxed.Offset)

Example 2 with VariableElement

use of org.jikesrvm.osr.VariableElement in project JikesRVM by JikesRVM.

the class OptExecutionStateExtractor method getExecStateSequence.

private ExecutionState getExecStateSequence(RVMThread thread, byte[] stack, Offset ipOffset, Offset fpOffset, int cmid, Offset tsFPOffset, TempRegisters registers, EncodedOSRMap osrmap) {
    // go through the stack frame and extract values
    // In the variable value list, we keep the order as follows:
    // L0, L1, ..., S0, S1, ....
    /* go over osr map element, build list of VariableElement.
    * assuming iterator has ordered element as
    *     L0, L1, ..., S0, S1, ...
    *
    *     ThreadSwitch
    *     threadSwitchFromOsr
    *     FOO                                        <-- fpOffset
    *
    * Also, all registers saved by threadSwitchFromDeopt method
    * is restored in "registers", address for object is converted
    * back to object references.
    *
    * This method should be called in non-GC critical section since
    * it allocates many objects.
    */
    // for 64-bit type values which have two int parts.
    // this holds the high part.
    int lvalue_one = 0;
    int lvtype_one = 0;
    // now recover execution states
    OSRMapIterator iterator = osrmap.getOsrMapIteratorForMCOffset(ipOffset);
    if (VM.VerifyAssertions)
        VM._assert(iterator != null);
    ExecutionState state = new ExecutionState(thread, fpOffset, cmid, iterator.getBcIndex(), tsFPOffset);
    MethodReference mref = MemberReference.getMethodRef(iterator.getMethodId());
    state.setMethod((NormalMethod) mref.peekResolvedMethod());
    // this is not caller, but the callee, reverse it when outside
    // of this function.
    state.callerState = null;
    if (VM.TraceOnStackReplacement) {
        VM.sysWriteln("osr map table of " + state.meth.toString());
    }
    while (iterator.hasMore()) {
        if (iterator.getMethodId() != state.meth.getId()) {
            ExecutionState newstate = new ExecutionState(thread, fpOffset, cmid, iterator.getBcIndex(), tsFPOffset);
            mref = MemberReference.getMethodRef(iterator.getMethodId());
            newstate.setMethod((NormalMethod) mref.peekResolvedMethod());
            // this is not caller, but the callee, reverse it when outside
            // of this function.
            newstate.callerState = state;
            state = newstate;
            if (VM.TraceOnStackReplacement) {
                VM.sysWriteln("osr map table of " + state.meth.toString());
            }
        }
        // create a VariableElement for it.
        boolean kind = iterator.getKind();
        char num = iterator.getNumber();
        byte tcode = iterator.getTypeCode();
        byte vtype = iterator.getValueType();
        int value = iterator.getValue();
        iterator.moveToNext();
        if (VM.TraceOnStackReplacement) {
            VM.sysWrite((kind == LOCAL) ? "L" : "S");
            VM.sysWrite((int) num);
            VM.sysWrite(" , ");
            if (vtype == ICONST) {
                VM.sysWrite("ICONST ");
                VM.sysWrite(value);
            } else if (vtype == PHYREG) {
                VM.sysWrite("PHYREG ");
                VM.sysWrite(GPR.lookup(value).toString());
            } else if (vtype == SPILL) {
                VM.sysWrite("SPILL  ");
                VM.sysWrite(value);
            }
            VM.sysWriteln();
        }
        switch(tcode) {
            case INT:
                {
                    int ibits = getIntBitsFrom(vtype, value, stack, fpOffset, registers);
                    state.add(new VariableElement(kind, num, tcode, ibits));
                    break;
                }
            case FLOAT:
                {
                    float fv = (float) getDoubleFrom(vtype, value, stack, fpOffset, registers);
                    int ibits = Magic.floatAsIntBits(fv);
                    state.add(new VariableElement(kind, num, tcode, ibits));
                    break;
                }
            case HIGH_64BIT:
                {
                    lvalue_one = value;
                    lvtype_one = vtype;
                    break;
                }
            case LONG:
                {
                    long lbits = getLongBitsFrom(lvtype_one, lvalue_one, vtype, value, stack, fpOffset, registers);
                    lvalue_one = 0;
                    lvtype_one = 0;
                    state.add(new VariableElement(kind, num, LONG, lbits));
                    break;
                }
            case DOUBLE:
                {
                    double dv = getDoubleFrom(vtype, value, stack, fpOffset, registers);
                    long lbits = Magic.doubleAsLongBits(dv);
                    state.add(new VariableElement(kind, num, tcode, lbits));
                    break;
                }
            // To be VERIFIED.
            case RET_ADDR:
                {
                    int bcIndex = getIntBitsFrom(vtype, value, stack, fpOffset, registers);
                    state.add(new VariableElement(kind, num, tcode, bcIndex));
                    break;
                }
            case WORD:
                {
                    // KV:TODO
                    if (VM.BuildFor64Addr) {
                        if (VM.VerifyAssertions) {
                            VM._assert(VM.NOT_REACHED);
                        } else {
                            VM.sysFail("Case not yet implemented for 64-bit addresssing.");
                        }
                    }
                    int word = getIntBitsFrom(vtype, value, stack, fpOffset, registers);
                    state.add(new VariableElement(kind, num, tcode, word));
                    break;
                }
            case REF:
                {
                    Object ref = getObjectFrom(vtype, value, stack, fpOffset, registers);
                    state.add(new VariableElement(kind, num, tcode, ref));
                    break;
                }
            default:
                if (VM.VerifyAssertions)
                    VM._assert(VM.NOT_REACHED);
                break;
        }
    // switch
    }
    return state;
}
Also used : ExecutionState(org.jikesrvm.osr.ExecutionState) MethodReference(org.jikesrvm.classloader.MethodReference) OSRMapIterator(org.jikesrvm.osr.OSRMapIterator) VariableElement(org.jikesrvm.osr.VariableElement)

Example 3 with VariableElement

use of org.jikesrvm.osr.VariableElement in project JikesRVM by JikesRVM.

the class BaselineExecutionStateExtractor method getVariableValue.

/* go over local/stack array, and build VariableElement. */
private static void getVariableValue(byte[] stack, Offset offset, byte[] types, ArchBaselineCompiledMethod compiledMethod, boolean kind, ExecutionState state) {
    int size = types.length;
    Offset vOffset = offset;
    for (int i = 0; i < size; i++) {
        switch(types[i]) {
            case VoidTypeCode:
                vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
                break;
            case BooleanTypeCode:
            case ByteTypeCode:
            case ShortTypeCode:
            case CharTypeCode:
            case IntTypeCode:
            case FloatTypeCode:
                {
                    int value = Magic.getIntAtOffset(stack, vOffset.minus(BYTES_IN_INT));
                    vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
                    byte tcode = (types[i] == FloatTypeCode) ? FLOAT : INT;
                    state.add(new VariableElement(kind, i, tcode, value));
                    break;
                }
            case LongTypeCode:
            case DoubleTypeCode:
                {
                    // KV: this code would be nicer if VoidTypeCode would always follow a 64-bit value. Rigth now for LOCAL it follows, for STACK it proceeds
                    Offset memoff = (kind == LOCAL) ? vOffset.minus(BYTES_IN_DOUBLE) : VM.BuildFor64Addr ? vOffset : vOffset.minus(BYTES_IN_STACKSLOT);
                    long value = Magic.getLongAtOffset(stack, memoff);
                    byte tcode = (types[i] == LongTypeCode) ? LONG : DOUBLE;
                    state.add(new VariableElement(kind, i, tcode, value));
                    if (kind == LOCAL) {
                        // KV:VoidTypeCode is next
                        vOffset = vOffset.minus(2 * BYTES_IN_STACKSLOT);
                        // KV:skip VoidTypeCode
                        i++;
                    } else {
                        // KV:VoidTypeCode was already in front
                        vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
                    }
                    break;
                }
            case ReturnAddressTypeCode:
                {
                    VM.disableGC();
                    Address rowIP = Magic.objectAsAddress(stack).loadAddress(vOffset.minus(BYTES_IN_ADDRESS));
                    Offset ipOffset = compiledMethod.getInstructionOffset(rowIP);
                    VM.enableGC();
                    vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
                    if (VM.TraceOnStackReplacement) {
                        Offset ipIndex = ipOffset.toWord().rsha(LG_INSTRUCTION_WIDTH).toOffset();
                        VM.sysWrite("baseline ret_addr ip ", ipIndex, " --> ");
                    }
                    int bcIndex = compiledMethod.findBytecodeIndexForInstruction(ipOffset.plus(INSTRUCTION_WIDTH));
                    if (VM.TraceOnStackReplacement) {
                        VM.sysWriteln(" bc " + bcIndex);
                    }
                    state.add(new VariableElement(kind, i, RET_ADDR, bcIndex));
                    break;
                }
            case ClassTypeCode:
            case ArrayTypeCode:
                {
                    VM.disableGC();
                    Object ref = Magic.getObjectAtOffset(stack, vOffset.minus(BYTES_IN_ADDRESS));
                    VM.enableGC();
                    vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
                    state.add(new VariableElement(kind, i, REF, ref));
                    break;
                }
            case WordTypeCode:
                {
                    Word value = Magic.getWordAtOffset(stack, vOffset.minus(BYTES_IN_ADDRESS));
                    vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
                    state.add(new VariableElement(kind, i, WORD, value));
                    break;
                }
            default:
                if (VM.VerifyAssertions)
                    VM._assert(VM.NOT_REACHED);
                break;
        }
    // switch
    }
// for loop
}
Also used : Word(org.vmmagic.unboxed.Word) Address(org.vmmagic.unboxed.Address) VariableElement(org.jikesrvm.osr.VariableElement) Offset(org.vmmagic.unboxed.Offset)

Example 4 with VariableElement

use of org.jikesrvm.osr.VariableElement in project JikesRVM by JikesRVM.

the class OptExecutionStateExtractor method getExecStateSequence.

private ExecutionState getExecStateSequence(RVMThread thread, byte[] stack, Offset ipOffset, Offset fpOffset, int cmid, Offset tsFPOffset, TempRegisters registers, EncodedOSRMap osrmap) {
    // go through the stack frame and extract values
    // In the variable value list, we keep the order as follows:
    // L0, L1, ..., S0, S1, ....
    /* go over osr map element, build list of VariableElement.
    * assuming iterator has ordered element as
    *     L0, L1, ..., S0, S1, ...
    *
    *     RVMThread.ThreadSwitch
    *     OptSaveVolatile.threadSwitchFromDeopt
    *     FOO                                        <-- fpOffset
    *
    * Also, all registers saved by threadSwitchFromDeopt method
    * is restored in "registers", address for object is converted
    * back to object references.
    *
    * This method should be called in non-GC critical section since
    * it allocates many objects.
    */
    // for 64-bit type values which have two int parts.
    // this holds the high part.
    int lpart_one = 0;
    // now recover execution states
    OSRMapIterator iterator = osrmap.getOsrMapIteratorForMCOffset(ipOffset);
    if (VM.VerifyAssertions)
        VM._assert(iterator != null);
    ExecutionState state = new ExecutionState(thread, fpOffset, cmid, iterator.getBcIndex(), tsFPOffset);
    MethodReference mref = MemberReference.getMethodRef(iterator.getMethodId());
    state.setMethod((NormalMethod) mref.peekResolvedMethod());
    state.callerState = null;
    while (iterator.hasMore()) {
        if (iterator.getMethodId() != state.meth.getId()) {
            ExecutionState newstate = new ExecutionState(thread, fpOffset, cmid, iterator.getBcIndex(), tsFPOffset);
            mref = MemberReference.getMethodRef(iterator.getMethodId());
            newstate.setMethod((NormalMethod) mref.peekResolvedMethod());
            // this is not caller, but the callee, reverse it when outside
            // of this function.
            newstate.callerState = state;
            state = newstate;
        }
        // create a VariableElement for it.
        boolean kind = iterator.getKind();
        int num = iterator.getNumber();
        byte tcode = iterator.getTypeCode();
        byte vtype = iterator.getValueType();
        int value = iterator.getValue();
        iterator.moveToNext();
        switch(tcode) {
            case INT:
                {
                    int ibits = getIntBitsFrom(vtype, value, stack, fpOffset, registers);
                    state.add(new VariableElement(kind, num, tcode, ibits));
                    break;
                }
            case FLOAT:
                {
                    float fv = (float) getDoubleFrom(vtype, value, stack, fpOffset, registers);
                    int ibits = Magic.floatAsIntBits(fv);
                    state.add(new VariableElement(kind, num, tcode, ibits));
                    break;
                }
            case HIGH_64BIT:
                {
                    lpart_one = value;
                    break;
                }
            case LONG:
                {
                    long lbits = getLongBitsFrom(vtype, lpart_one, value, stack, fpOffset, registers);
                    lpart_one = 0;
                    state.add(new // not use LONG2,
                    VariableElement(// not use LONG2,
                    kind, // not use LONG2,
                    num, // not use LONG2,
                    LONG, lbits));
                    break;
                }
            case DOUBLE:
                {
                    double dv = getDoubleFrom(vtype, value, stack, fpOffset, registers);
                    long lbits = Magic.doubleAsLongBits(dv);
                    state.add(new VariableElement(kind, num, tcode, lbits));
                    break;
                }
            // To be VERIFIED.
            case RET_ADDR:
                {
                    int bcIndex = getIntBitsFrom(vtype, value, stack, fpOffset, registers);
                    state.add(new VariableElement(kind, num, tcode, bcIndex));
                    break;
                }
            case REF:
                {
                    Object ref = getObjectFrom(vtype, value, stack, fpOffset, registers);
                    state.add(new VariableElement(kind, num, tcode, ref));
                    break;
                }
            case WORD:
                {
                    if (VM.BuildFor32Addr) {
                        int word = getIntBitsFrom(vtype, value, stack, fpOffset, registers);
                        state.add(new VariableElement(kind, num, tcode, word));
                    } else {
                        long word = getLongBitsFrom(vtype, lpart_one, value, stack, fpOffset, registers);
                        lpart_one = 0;
                        state.add(new VariableElement(kind, num, tcode, word));
                    }
                    break;
                }
            default:
                if (VM.VerifyAssertions)
                    VM._assert(VM.NOT_REACHED);
                break;
        }
    // switch
    }
    return state;
}
Also used : ExecutionState(org.jikesrvm.osr.ExecutionState) MethodReference(org.jikesrvm.classloader.MethodReference) OSRMapIterator(org.jikesrvm.osr.OSRMapIterator) VariableElement(org.jikesrvm.osr.VariableElement)

Aggregations

VariableElement (org.jikesrvm.osr.VariableElement)4 MethodReference (org.jikesrvm.classloader.MethodReference)2 ExecutionState (org.jikesrvm.osr.ExecutionState)2 OSRMapIterator (org.jikesrvm.osr.OSRMapIterator)2 Address (org.vmmagic.unboxed.Address)2 Offset (org.vmmagic.unboxed.Offset)2 Word (org.vmmagic.unboxed.Word)2