Search in sources :

Example 51 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_deferred_prologue.

/**
 * Emit deferred prologue
 */
@Override
protected void emit_deferred_prologue() {
    if (VM.VerifyAssertions)
        VM._assert(method.isForOsrSpecialization());
    if (isInterruptible) {
        Offset offset = Entrypoints.stackLimitField.getOffset();
        if (VM.BuildFor32Addr) {
            // S0<-limit
            asm.emitMOV_Reg_RegDisp(S0, THREAD_REGISTER, offset);
            asm.emitSUB_Reg_Reg(S0, SP);
            asm.emitADD_Reg_Imm(S0, method.getOperandWords() << LG_WORDSIZE);
        } else {
            // S0<-limit
            asm.emitMOV_Reg_RegDisp_Quad(S0, THREAD_REGISTER, offset);
            asm.emitSUB_Reg_Reg_Quad(S0, SP);
            asm.emitADD_Reg_Imm_Quad(S0, method.getOperandWords() << LG_WORDSIZE);
        }
        asm.emitBranchLikelyNextInstruction();
        // Jmp around trap
        ForwardReference fr = asm.forwardJcc(LT);
        // trap
        asm.emitINT_Imm(RuntimeEntrypoints.TRAP_STACK_OVERFLOW + RVM_TRAP_BASE);
        fr.resolve(asm);
    } else {
    // TODO!! make sure stackframe of uninterruptible method doesn't overflow
    }
    /* never do monitor enter for synced method since the specialized
     * code starts after original monitor enter.
     */
    genThreadSwitchTest(RVMThread.PROLOGUE);
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference) Offset(org.vmmagic.unboxed.Offset)

Example 52 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_instanceof_resolvedClass.

@Override
protected void emit_instanceof_resolvedClass(RVMClass type) {
    int LHSDepth = type.getTypeDepth();
    int LHSId = type.getId();
    // load object from stack
    asm.emitPOP_Reg(ECX);
    // test for null
    ForwardReference isNull = asm.forwardJECXZ();
    // get superclass display from object's TIB
    asm.baselineEmitLoadTIB(S0, ECX);
    if (VM.BuildFor32Addr) {
        asm.emitMOV_Reg_RegDisp(S0, S0, Offset.fromIntZeroExtend(TIB_SUPERCLASS_IDS_INDEX << LG_WORDSIZE));
    } else {
        asm.emitMOV_Reg_RegDisp_Quad(S0, S0, Offset.fromIntZeroExtend(TIB_SUPERCLASS_IDS_INDEX << LG_WORDSIZE));
    }
    ForwardReference outOfBounds = null;
    if (DynamicTypeCheck.MIN_SUPERCLASS_IDS_SIZE <= LHSDepth) {
        // must do arraybounds check of superclass display
        if (ARRAY_LENGTH_BYTES == 4) {
            asm.emitCMP_RegDisp_Imm(S0, ObjectModel.getArrayLengthOffset(), LHSDepth);
        } else {
            asm.emitCMP_RegDisp_Imm_Quad(S0, ObjectModel.getArrayLengthOffset(), LHSDepth);
        }
        outOfBounds = asm.forwardJcc(LLE);
    }
    // Load id from display at required depth and compare against target id; push true if matched
    asm.emitMOVZX_Reg_RegDisp_Word(S0, S0, Offset.fromIntZeroExtend(LHSDepth << LOG_BYTES_IN_SHORT));
    asm.emitCMP_Reg_Imm(S0, LHSId);
    ForwardReference notMatched = asm.forwardJcc(NE);
    asm.emitPUSH_Imm(1);
    ForwardReference done = asm.forwardJMP();
    // push false
    isNull.resolve(asm);
    if (outOfBounds != null)
        outOfBounds.resolve(asm);
    notMatched.resolve(asm);
    asm.emitPUSH_Imm(0);
    done.resolve(asm);
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference)

Example 53 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_tableswitch.

@Override
protected void emit_tableswitch(int defaultval, int low, int high) {
    int bTarget = biStart + defaultval;
    int mTarget = bytecodeMap[bTarget];
    // n = number of normal cases (0..n-1)
    int n = high - low + 1;
    // T1 is index of desired case
    asm.emitPOP_Reg(T1);
    // relativize T1
    asm.emitSUB_Reg_Imm(T1, low);
    // 0 <= relative index < n
    asm.emitCMP_Reg_Imm(T1, n);
    if (!VM.runningTool && ((BaselineCompiledMethod) compiledMethod).hasCounterArray()) {
        int firstCounter = edgeCounterIdx;
        edgeCounterIdx += (n + 1);
        // Jump around code for default case
        ForwardReference fr = asm.forwardJcc(LLT);
        incEdgeCounter(S0, null, firstCounter + n);
        asm.emitJMP_ImmOrLabel(mTarget, bTarget);
        fr.resolve(asm);
        // Increment counter for the appropriate case
        incEdgeCounter(S0, T1, firstCounter);
    } else {
        // if not, goto default case
        asm.emitJCC_Cond_ImmOrLabel(LGE, mTarget, bTarget);
    }
    // T0 = EIP at start of method
    asm.emitMETHODSTART_Reg(T0);
    asm.emitTableswitchCode(T0, T1);
    // loaded for the cases
    for (int i = 0; i < n; i++) {
        int offset = bcodes.getTableSwitchOffset(i);
        bTarget = biStart + offset;
        mTarget = bytecodeMap[bTarget];
        asm.emitOFFSET_Imm_ImmOrLabel(i, mTarget, bTarget);
    }
    bcodes.skipTableSwitchOffsets(n);
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference)

Example 54 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method genBoundsCheck.

/**
 * Generate an array bounds check trapping if the array bound check fails,
 * otherwise falling through.
 * @param asm the assembler to generate into
 * @param indexReg the register containing the index
 * @param arrayRefReg the register containing the array reference
 */
@Inline(value = Inline.When.ArgumentsAreConstant, arguments = { 1, 2 })
static void genBoundsCheck(Assembler asm, GPR indexReg, GPR arrayRefReg) {
    // compare index to array length
    if (ARRAY_LENGTH_BYTES == 4) {
        asm.emitCMP_RegDisp_Reg(arrayRefReg, ObjectModel.getArrayLengthOffset(), indexReg);
    } else {
        asm.emitCMP_RegDisp_Reg_Quad(arrayRefReg, ObjectModel.getArrayLengthOffset(), indexReg);
    }
    // Jmp around trap if index is OK
    asm.emitBranchLikelyNextInstruction();
    ForwardReference fr = asm.forwardJcc(LGT);
    // "pass" index param to C trap handler
    asm.emitMOV_RegDisp_Reg(THREAD_REGISTER, ArchEntrypoints.arrayIndexTrapParamField.getOffset(), indexReg);
    // trap
    asm.emitINT_Imm(RuntimeEntrypoints.TRAP_ARRAY_BOUNDS + RVM_TRAP_BASE);
    fr.resolve(asm);
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference) Inline(org.vmmagic.pragma.Inline)

Example 55 with ForwardReference

use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_DFcmpGL_if.

@Override
protected void emit_DFcmpGL_if(boolean single, boolean unorderedGT, int bTarget, BranchCondition bc) {
    if (SSE2_BASE) {
        if (single) {
            // XMM0 = value2
            asm.emitMOVSS_Reg_RegInd(XMM0, SP);
            // XMM1 = value1
            asm.emitMOVSS_Reg_RegDisp(XMM1, SP, ONE_SLOT);
            // throw away slots
            adjustStack(WORDSIZE * 2, true);
        } else {
            // XMM0 = value2
            asm.emitMOVSD_Reg_RegInd(XMM0, SP);
            // XMM1 = value1
            asm.emitMOVSD_Reg_RegDisp(XMM1, SP, TWO_SLOTS);
            // throw away slots
            adjustStack(WORDSIZE * 4, true);
        }
    } else {
        if (single) {
            // Setup value2 into FP1,
            asm.emitFLD_Reg_RegInd(FP0, SP);
            // value1 into FP0
            asm.emitFLD_Reg_RegDisp(FP0, SP, ONE_SLOT);
            // throw away slots
            adjustStack(WORDSIZE * 2, true);
        } else {
            // Setup value2 into FP1,
            asm.emitFLD_Reg_RegInd_Quad(FP0, SP);
            // value1 into FP0
            asm.emitFLD_Reg_RegDisp_Quad(FP0, SP, TWO_SLOTS);
            // throw away slots
            adjustStack(WORDSIZE * 4, true);
        }
    }
    if (SSE2_BASE) {
        if (single) {
            // compare value1 and value2
            asm.emitUCOMISS_Reg_Reg(XMM1, XMM0);
        } else {
            // compare value1 and value2
            asm.emitUCOMISD_Reg_Reg(XMM1, XMM0);
        }
    } else {
        // compare and pop FPU *1
        asm.emitFUCOMIP_Reg_Reg(FP0, FP1);
        // pop FPU*1
        asm.emitFSTP_Reg_Reg(FP0, FP0);
    }
    byte asm_bc = -1;
    boolean unordered_taken = false;
    switch(bc) {
        case EQ:
            asm_bc = EQ;
            unordered_taken = false;
            break;
        case NE:
            asm_bc = NE;
            unordered_taken = true;
            break;
        case LT:
            asm_bc = LLT;
            unordered_taken = !unorderedGT;
            break;
        case GE:
            asm_bc = LGE;
            unordered_taken = unorderedGT;
            break;
        case GT:
            asm_bc = LGT;
            unordered_taken = unorderedGT;
            break;
        case LE:
            asm_bc = LLE;
            unordered_taken = !unorderedGT;
            break;
        default:
            if (VM.VerifyAssertions)
                VM._assert(VM.NOT_REACHED);
    }
    int mTarget = bytecodeMap[bTarget];
    if (!VM.runningTool && ((BaselineCompiledMethod) compiledMethod).hasCounterArray()) {
        // Allocate two counters: taken and not taken
        int entry = edgeCounterIdx;
        edgeCounterIdx += 2;
        if (!unordered_taken) {
            ForwardReference notTaken1 = asm.forwardJcc(PE);
            ForwardReference notTaken2 = asm.forwardJcc(asm.flipCode(asm_bc));
            // Increment taken counter & jump to target
            incEdgeCounter(T1, null, entry + EdgeCounts.TAKEN);
            asm.emitJMP_ImmOrLabel(mTarget, bTarget);
            // Increment not taken counter
            notTaken1.resolve(asm);
            notTaken2.resolve(asm);
            incEdgeCounter(T1, null, entry + EdgeCounts.NOT_TAKEN);
        } else {
            ForwardReference taken1 = asm.forwardJcc(PE);
            ForwardReference taken2 = asm.forwardJcc(asm_bc);
            // Increment taken counter & jump to target
            incEdgeCounter(T1, null, entry + EdgeCounts.NOT_TAKEN);
            ForwardReference notTaken = asm.forwardJMP();
            // Increment taken counter
            taken1.resolve(asm);
            taken2.resolve(asm);
            incEdgeCounter(T1, null, entry + EdgeCounts.TAKEN);
            asm.emitJMP_ImmOrLabel(mTarget, bTarget);
            notTaken.resolve(asm);
        }
    } else {
        if (unordered_taken) {
            asm.emitJCC_Cond_ImmOrLabel(PE, mTarget, bTarget);
            asm.emitJCC_Cond_ImmOrLabel(asm_bc, mTarget, bTarget);
        } else {
            ForwardReference notTaken = asm.forwardJcc(PE);
            asm.emitJCC_Cond_ImmOrLabel(asm_bc, mTarget, bTarget);
            notTaken.resolve(asm);
        }
    }
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference)

Aggregations

ForwardReference (org.jikesrvm.compilers.common.assembler.ForwardReference)71 Offset (org.vmmagic.unboxed.Offset)13 TypeReference (org.jikesrvm.classloader.TypeReference)5 RVMClass (org.jikesrvm.classloader.RVMClass)4 Assembler (org.jikesrvm.compilers.common.assembler.ppc.Assembler)4 RVMMethod (org.jikesrvm.classloader.RVMMethod)3 GPR (org.jikesrvm.ia32.RegisterConstants.GPR)3 XMM (org.jikesrvm.ia32.RegisterConstants.XMM)3 InterfaceMethodSignature (org.jikesrvm.classloader.InterfaceMethodSignature)2 RVMArray (org.jikesrvm.classloader.RVMArray)2 Assembler (org.jikesrvm.compilers.common.assembler.ia32.Assembler)2 FloatingPointMachineRegister (org.jikesrvm.ia32.RegisterConstants.FloatingPointMachineRegister)2 JNICompiledMethod (org.jikesrvm.jni.JNICompiledMethod)2 Entrypoint (org.vmmagic.pragma.Entrypoint)2 Inline (org.vmmagic.pragma.Inline)2 Address (org.vmmagic.unboxed.Address)2 Atom (org.jikesrvm.classloader.Atom)1 FieldReference (org.jikesrvm.classloader.FieldReference)1 MethodReference (org.jikesrvm.classloader.MethodReference)1 RVMType (org.jikesrvm.classloader.RVMType)1