Search in sources :

Example 21 with TrueGuardOperand

use of org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand in project JikesRVM by JikesRVM.

the class BC2IR method do_NullCheck.

/**
 * Generates a null-check instruction for the given operand.
 * @param ref the reference to check for null
 * @return {@code true} if an unconditional throw is generated, {@code false} otherwise
 */
public boolean do_NullCheck(Operand ref) {
    if (gc.noNullChecks()) {
        setCurrentGuard(new TrueGuardOperand());
        return false;
    }
    if (ref.isDefinitelyNull()) {
        if (DBG_CF)
            db("generating definite exception: null_check of definitely null");
        endOfBasicBlock = true;
        rectifyStateWithNullPtrExceptionHandler();
        appendInstruction(Trap.create(TRAP, gc.getTemps().makeTempValidation(), TrapCodeOperand.NullPtr()));
        return true;
    }
    if (ref instanceof RegisterOperand) {
        RegisterOperand rop = (RegisterOperand) ref;
        if (hasGuard(rop)) {
            Operand guard = copyGuardFromOperand(rop);
            setCurrentGuard(guard);
            if (DBG_ELIMNULL) {
                db("null check of " + ref + " is not necessary; guarded by " + guard);
            }
            return false;
        }
        // rop is possibly null, insert the null check,
        // rectify with exception handler, update the guard state.
        RegisterOperand guard = gc.makeNullCheckGuard(rop.getRegister());
        appendInstruction(NullCheck.create(NULL_CHECK, guard, ref.copy()));
        rectifyStateWithNullPtrExceptionHandler();
        setCurrentGuard(guard);
        setGuardForRegOp(rop, guard);
        if (DBG_ELIMNULL)
            db(rop + " is guarded by " + guard);
        // RegisterOperands representing the same Register.
        if (rop.getRegister().isLocal()) {
            // We want to learn that downstream of this nullcheck, other
            // uses of this local variable will also be non-null.
            // BUT, we MUST NOT just directly set the guard of the appropriate
            // element of our locals array (operands in the local array
            // may appear in previously generated instructions).
            // Therefore we call getLocal (which internally makes a copy),
            // mark the copy with the new guard
            // and finally store the copy back into the local state.
            int number = gc.getLocalNumberFor(rop.getRegister(), rop.getType());
            if (number != -1) {
                Operand loc = getLocal(number);
                if (loc instanceof RegisterOperand) {
                    if (DBG_ELIMNULL) {
                        db("setting local #" + number + "(" + loc + ") to non-null");
                    }
                    setGuardForRegOp((RegisterOperand) loc, guard);
                }
                setLocal(number, loc);
            }
        }
        // the current basic block.
        for (int i = stack.getSize() - 1; i >= 0; --i) {
            Operand sop = stack.getFromTop(i);
            if (sop instanceof RegisterOperand) {
                RegisterOperand sreg = (RegisterOperand) sop;
                if (sreg.getRegister() == rop.getRegister()) {
                    if (hasGuard(sreg)) {
                        if (DBG_ELIMNULL) {
                            db(sreg + " on stack already with guard " + copyGuardFromOperand(sreg));
                        }
                    } else {
                        if (DBG_ELIMNULL) {
                            db("setting " + sreg + " on stack to be guarded by " + guard);
                        }
                        setGuardForRegOp(sreg, guard);
                    }
                }
            }
        }
        return false;
    } else {
        // cannot be null becuase it's not in a register.
        if (DBG_ELIMNULL) {
            db("skipped generation of a null-check instruction for non-register " + ref);
        }
        setCurrentGuard(new TrueGuardOperand());
        return false;
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) OsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.OsrTypeInfoOperand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)

Example 22 with TrueGuardOperand

use of org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand in project JikesRVM by JikesRVM.

the class BURS_Helpers method INT_2DOUBLE.

/**
 * taken from: The PowerPC Compiler Writer's Guide, pp. 83
 */
protected final void INT_2DOUBLE(Instruction s, RegisterOperand def, RegisterOperand left) {
    Register res = def.getRegister();
    Register src = left.getRegister();
    Register FP = regpool.getPhysicalRegisterSet().asPPC().getFP();
    RegisterOperand temp = regpool.makeTempInt();
    int p = burs.ir.stackManager.allocateSpaceForConversion();
    EMIT(MIR_Unary.mutate(s, PPC_LDIS, temp, IC(0x4330)));
    // TODO: valid location?
    EMIT(MIR_Store.create(PPC_STW, I(temp.getRegister()), A(FP), IC(p), new TrueGuardOperand()));
    Register t1 = regpool.getInteger();
    EMIT(MIR_Binary.create(PPC_XORIS, I(t1), I(src), IC(0x8000)));
    EMIT(MIR_Store.create(PPC_STW, I(t1), A(FP), IC(p + 4), new TrueGuardOperand()));
    EMIT(MIR_Load.create(PPC_LFD, D(res), A(FP), IC(p)));
    Register tempF = regpool.getDouble();
    emitLFtoc(PPC_LFD, tempF, Entrypoints.I2DconstantField);
    EMIT(MIR_Binary.create(PPC_FSUB, D(res), D(res), D(tempF)));
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)

Example 23 with TrueGuardOperand

use of org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand in project JikesRVM by JikesRVM.

the class BURS_Helpers method IFCMP.

/**
 * Generate a compare and branch sequence. Used in the expansion of trees
 * where INT_IFCMP is a root
 *
 * @param s the ifcmp instruction
 * @param guardResult the guard result of the ifcmp
 * @param val1 the first value operand
 * @param val2 the second value operand
 * @param cond the condition operand
 */
protected final void IFCMP(Instruction s, RegisterOperand guardResult, Operand val1, Operand val2, ConditionOperand cond) {
    if (VM.VerifyAssertions) {
        // We only need make sure the guard information is correct when
        // validating, the null check combining phase removes all guards
        EMIT(CPOS(s, Move.create(GUARD_MOVE, guardResult, new TrueGuardOperand())));
    }
    EMIT(CPOS(s, MIR_Compare.create(IA32_CMP, val1, val2)));
    EMIT(MIR_CondBranch.mutate(s, IA32_JCC, COND(cond), IfCmp.getTarget(s), IfCmp.getBranchProfile(s)));
}
Also used : TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)

Example 24 with TrueGuardOperand

use of org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand in project JikesRVM by JikesRVM.

the class GenerationContextTest method packagePrivateMakeLocalReturnsRegWithInheritedFlagsAndGuard.

@Test
public void packagePrivateMakeLocalReturnsRegWithInheritedFlagsAndGuard() throws Exception {
    NormalMethod nm = TestingTools.getNormalMethod(MethodsForTests.class, "emptyInstanceMethodWithoutAnnotations");
    OptOptions opts = new OptOptions();
    GenerationContext gc = new GenerationContext(nm, null, null, opts, null);
    int localNumber = 0;
    TypeReference localType = nm.getDeclaringClass().getTypeRef();
    RegisterOperand regOp = gc.makeLocal(localNumber, localType);
    TrueGuardOperand guard = new TrueGuardOperand();
    regOp.setGuard(guard);
    regOp.setParameter();
    regOp.setNonVolatile();
    regOp.setExtant();
    regOp.setDeclaredType();
    regOp.setPreciseType();
    regOp.setPositiveInt();
    RegisterOperand newRegOpWithInheritance = gc.makeLocal(localNumber, regOp);
    Operand scratchObject = newRegOpWithInheritance.getGuard();
    assertTrue(scratchObject.isTrueGuard());
    assertTrue(newRegOpWithInheritance.isParameter());
    assertTrue(newRegOpWithInheritance.isNonVolatile());
    assertTrue(newRegOpWithInheritance.isExtant());
    assertTrue(newRegOpWithInheritance.isDeclaredType());
    assertTrue(newRegOpWithInheritance.isPreciseType());
    assertTrue(newRegOpWithInheritance.isPositiveInt());
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) NormalMethod(org.jikesrvm.classloader.NormalMethod) OptOptions(org.jikesrvm.compilers.opt.OptOptions) TypeReference(org.jikesrvm.classloader.TypeReference) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) Test(org.junit.Test)

Example 25 with TrueGuardOperand

use of org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand in project JikesRVM by JikesRVM.

the class DynamicTypeCheckExpansion method arrayStoreCheck.

/**
 * Expand an object array store check into the LIR sequence that
 * implements it.
 *
 * @param s an OBJARRAY_STORE_CHECK instruction to expand
 * @param ir the enclosing IR
 * @param couldBeNull is it possible that the element being stored is null?
 * @return the last Instruction in the generated LIR sequence.
 */
static Instruction arrayStoreCheck(Instruction s, IR ir, boolean couldBeNull) {
    RegisterOperand guardResult = StoreCheck.getGuardResult(s);
    Operand arrayRef = StoreCheck.getClearRef(s);
    Operand elemRef = StoreCheck.getClearVal(s);
    Operand guard = StoreCheck.getClearGuard(s);
    if (elemRef instanceof NullConstantOperand) {
        Instruction continueAt = s.prevInstructionInCodeOrder();
        s.remove();
        return continueAt;
    }
    BasicBlock myBlock = s.getBasicBlock();
    BasicBlock contBlock = myBlock.splitNodeAt(s, ir);
    BasicBlock trapBlock = myBlock.createSubBlock(s.getBytecodeIndex(), ir, .0001f);
    BasicBlock curBlock = myBlock;
    Move.mutate(s, GUARD_MOVE, guardResult, new TrueGuardOperand());
    // Set up a block with a trap instruction that we can jump to if the
    // store check fails
    Instruction trap = Trap.create(TRAP, null, TrapCodeOperand.StoreCheck());
    trap.copyPosition(s);
    trapBlock.appendInstruction(trap);
    ir.cfg.addLastInCodeOrder(trapBlock);
    Operand rhsGuard = guard;
    if (couldBeNull) {
        // if rhs is null, then the checkcast succeeds
        rhsGuard = ir.regpool.makeTempValidation();
        contBlock.prependInstruction(Binary.create(GUARD_COMBINE, guardResult.copyRO(), guardResult.copyRO(), rhsGuard.copy()));
        curBlock.appendInstruction(IfCmp.create(REF_IFCMP, rhsGuard.asRegister(), elemRef, new NullConstantOperand(), ConditionOperand.EQUAL(), contBlock.makeJumpTarget(), new BranchProfileOperand()));
        curBlock.insertOut(contBlock);
        curBlock = advanceBlock(s.getBytecodeIndex(), curBlock, ir);
    }
    // Find out what we think the compile time type of the lhs is.
    // Based on this, we can do one of several things:
    // (1) If the compile time element type is a final proper class, then a
    // TIB comparision of the runtime elemRef type and the
    // compile time element type is definitive.
    // (2) If the compile time type is known to be the declared type,
    // then inject a short-circuit test to see if the
    // runtime lhs type is the same as the compile-time lhs type.
    // (3) If the compile time element type is a proper class other than
    // java.lang.Object, then a subclass test of the runtime LHS elem type
    // and the runtime elemRef type is definitive.  Note: we must exclude
    // java.lang.Object because if the compile time element type is
    // java.lang.Object, then the runtime-element type might actually be
    // an interface (ie not a proper class), and we won't be testing the right thing!
    // If we think the compile time type is JavaLangObjectType then
    // we lost type information due to unloaded classes causing
    // imprecise meets.  This should only happen once in a blue moon,
    // so don't bother trying anything clever when it does.
    RVMType compType = arrayRef.getType().peekType();
    if (compType != null && !compType.isJavaLangObjectType()) {
        // optionally (1) from above
        if (compType.getDimensionality() == 1) {
            RVMClass etc = (RVMClass) compType.asArray().getElementType();
            if (etc.isResolved() && etc.isFinal()) {
                if (VM.VerifyAssertions)
                    VM._assert(!etc.isInterface());
                Operand rhsTIB = getTIB(curBlock.lastInstruction(), ir, elemRef.copy(), rhsGuard.copy());
                Operand etTIB = getTIB(curBlock.lastInstruction(), ir, etc);
                curBlock.appendInstruction(IfCmp.create(REF_IFCMP, guardResult.copyRO(), rhsTIB, etTIB, ConditionOperand.NOT_EQUAL(), trapBlock.makeJumpTarget(), BranchProfileOperand.never()));
                curBlock.insertOut(trapBlock);
                curBlock.insertOut(contBlock);
                ir.cfg.linkInCodeOrder(curBlock, contBlock);
                return curBlock.lastInstruction();
            }
        }
        // optionally (2) from above
        Operand lhsTIB = getTIB(curBlock.lastInstruction(), ir, arrayRef, guard);
        if (((arrayRef instanceof RegisterOperand) && ((RegisterOperand) arrayRef).isDeclaredType()) || compType == RVMType.JavaLangObjectArrayType) {
            Operand declTIB = getTIB(curBlock.lastInstruction(), ir, compType);
            curBlock.appendInstruction(IfCmp.create(REF_IFCMP, guardResult.copyRO(), declTIB, lhsTIB, ConditionOperand.EQUAL(), contBlock.makeJumpTarget(), new BranchProfileOperand()));
            curBlock.insertOut(contBlock);
            curBlock = advanceBlock(s.getBytecodeIndex(), curBlock, ir);
        }
        // On our way to doing (3) from above attempt another short-circuit.
        // If lhsElemTIB == rhsTIB, then we are done.
        Operand rhsTIB = getTIB(curBlock.lastInstruction(), ir, elemRef.copy(), rhsGuard.copy());
        RegisterOperand lhsElemTIB = InsertUnary(curBlock.lastInstruction(), ir, GET_ARRAY_ELEMENT_TIB_FROM_TIB, TypeReference.TIB, lhsTIB.copy());
        curBlock.appendInstruction(IfCmp.create(REF_IFCMP, guardResult.copyRO(), rhsTIB, lhsElemTIB, ConditionOperand.EQUAL(), contBlock.makeJumpTarget(), new BranchProfileOperand()));
        curBlock.insertOut(contBlock);
        curBlock = advanceBlock(s.getBytecodeIndex(), curBlock, ir);
        // Optionally (3) from above
        if (compType.getDimensionality() == 1) {
            RVMClass etc = (RVMClass) compType.asArray().getElementType();
            if (etc.isResolved() && !etc.isInterface() && !etc.isJavaLangObjectType()) {
                RegisterOperand lhsElemType = InsertUnary(curBlock.lastInstruction(), ir, GET_TYPE_FROM_TIB, TypeReference.Type, lhsElemTIB.copyU2U());
                RegisterOperand rhsSuperclassIds = InsertUnary(curBlock.lastInstruction(), ir, GET_SUPERCLASS_IDS_FROM_TIB, TypeReference.ShortArray, rhsTIB.copy());
                RegisterOperand lhsElemDepth = getField(curBlock.lastInstruction(), ir, lhsElemType, Entrypoints.depthField, TG());
                RegisterOperand rhsSuperclassIdsLength = InsertGuardedUnary(curBlock.lastInstruction(), ir, ARRAYLENGTH, TypeReference.Int, rhsSuperclassIds.copyD2U(), TG());
                curBlock.appendInstruction(IfCmp.create(INT_IFCMP, guardResult.copyRO(), lhsElemDepth, rhsSuperclassIdsLength, ConditionOperand.GREATER_EQUAL(), trapBlock.makeJumpTarget(), BranchProfileOperand.never()));
                curBlock.insertOut(trapBlock);
                curBlock = advanceBlock(s.getBytecodeIndex(), curBlock, ir);
                RegisterOperand lhsElemId = getField(curBlock.lastInstruction(), ir, lhsElemType.copyD2U(), Entrypoints.idField, TG());
                RegisterOperand refCandidate = ir.regpool.makeTemp(TypeReference.Short);
                LocationOperand loc = new LocationOperand(TypeReference.Short);
                if (LOWER_ARRAY_ACCESS) {
                    RegisterOperand lhsDepthOffset = insertBinary(curBlock.lastInstruction(), ir, INT_SHL, TypeReference.Int, lhsElemDepth.copyD2U(), IC(1));
                    lhsDepthOffset = InsertUnary(curBlock.lastInstruction(), ir, INT_2ADDRZerExt, TypeReference.Offset, lhsDepthOffset.copy());
                    curBlock.appendInstruction(Load.create(USHORT_LOAD, refCandidate, rhsSuperclassIds, lhsDepthOffset, loc, TG()));
                } else {
                    curBlock.appendInstruction(ALoad.create(USHORT_ALOAD, refCandidate, rhsSuperclassIds, lhsElemDepth.copyRO(), loc, TG()));
                }
                curBlock.appendInstruction(IfCmp.create(INT_IFCMP, guardResult.copyRO(), refCandidate.copyD2U(), lhsElemId, ConditionOperand.NOT_EQUAL(), trapBlock.makeJumpTarget(), BranchProfileOperand.never()));
                curBlock.insertOut(trapBlock);
                curBlock.insertOut(contBlock);
                ir.cfg.linkInCodeOrder(curBlock, contBlock);
                return curBlock.lastInstruction();
            }
        }
    }
    // Call RuntimeEntrypoints.checkstore.
    RVMMethod target = Entrypoints.checkstoreMethod;
    Instruction call = Call.create2(CALL, null, AC(target.getOffset()), MethodOperand.STATIC(target), rhsGuard.copy(), arrayRef.copy(), elemRef.copy());
    call.copyPosition(s);
    curBlock.appendInstruction(call);
    curBlock.insertOut(contBlock);
    ir.cfg.linkInCodeOrder(curBlock, contBlock);
    return callHelper(call, ir);
}
Also used : NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) RVMMethod(org.jikesrvm.classloader.RVMMethod) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) RVMType(org.jikesrvm.classloader.RVMType) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) RVMClass(org.jikesrvm.classloader.RVMClass)

Aggregations

TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)26 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)22 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)16 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)11 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)10 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)9 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)9 TypeReference (org.jikesrvm.classloader.TypeReference)8 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)8 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)8 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)7 Register (org.jikesrvm.compilers.opt.ir.Register)6 ObjectConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand)6 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)6 ClassConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand)5 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)5 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)5 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)5 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)5 UnreachableOperand (org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand)4