Search in sources :

Example 51 with RVMClass

use of org.jikesrvm.classloader.RVMClass in project JikesRVM by JikesRVM.

the class VMInstrumentationImpl method getObjectSize.

static long getObjectSize(Object objectToSize) {
    Class<?> cl = objectToSize.getClass();
    RVMType vmType = java.lang.JikesRVMSupport.getTypeForClass(cl);
    if (cl.isArray()) {
        RVMArray vmArray = (RVMArray) vmType;
        int nelements = java.lang.reflect.Array.getLength(objectToSize);
        return vmArray.getInstanceSize(nelements);
    } else {
        RVMClass vmClass = (RVMClass) vmType;
        return vmClass.getInstanceSize();
    }
}
Also used : RVMArray(org.jikesrvm.classloader.RVMArray) RVMType(org.jikesrvm.classloader.RVMType) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 52 with RVMClass

use of org.jikesrvm.classloader.RVMClass in project JikesRVM by JikesRVM.

the class InterfaceHierarchy method allImplementors.

/**
 * @return the set of all classes known to implement the interface
 * @param I the implemented interface
 */
private static ImmutableEntryHashSetRVM<RVMClass> allImplementors(RVMClass I) {
    // get the set of classes registered as implementing I
    ImmutableEntryHashSetRVM<RVMClass> result = findOrCreateSet(I);
    // need to do this kludge to avoid recursive concurrent modification
    for (RVMClass subClass : I.getSubClasses()) {
        result.addAll(allImplementors(subClass));
    }
    // also add any sub-classes of these classes.
    // need to cache additions to avoid modifying the set while iterating
    ImmutableEntryHashSetRVM<RVMClass> toAdd = new ImmutableEntryHashSetRVM<RVMClass>(5);
    for (RVMClass c : result) {
        toAdd.addAll(allSubClasses(c));
    }
    result.addAll(toAdd);
    return result;
}
Also used : ImmutableEntryHashSetRVM(org.jikesrvm.util.ImmutableEntryHashSetRVM) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 53 with RVMClass

use of org.jikesrvm.classloader.RVMClass in project JikesRVM by JikesRVM.

the class ConvertToLowLevelIR method callHelper.

/**
 * Helper method for call expansion.
 * @param v the call instruction
 * @param ir the containing IR
 * @return the last expanded instruction
 */
static Instruction callHelper(Instruction v, IR ir) {
    if (!Call.hasMethod(v)) {
        if (VM.VerifyAssertions)
            VM._assert(Call.getAddress(v) instanceof RegisterOperand);
        // nothing to do....very low level call to address already in the register.
        return v;
    }
    MethodOperand methOp = Call.getMethod(v);
    // Handle recursive invocations.
    if (methOp.hasPreciseTarget() && methOp.getTarget() == ir.method) {
        Call.setAddress(v, new BranchOperand(ir.firstInstructionInCodeOrder()));
        return v;
    }
    // has been marked as a specialized call.
    if (VM.runningVM) {
        SpecializedMethod spMethod = methOp.spMethod;
        if (spMethod != null) {
            int smid = spMethod.getSpecializedMethodIndex();
            Call.setAddress(v, getSpecialMethod(v, ir, smid));
            return v;
        }
    }
    // Used mainly (only?) by OSR
    if (methOp.hasDesignatedTarget()) {
        Call.setAddress(v, InsertLoadOffsetJTOC(v, ir, REF_LOAD, TypeReference.CodeArray, methOp.jtocOffset));
        return v;
    }
    if (methOp.isStatic()) {
        if (VM.VerifyAssertions)
            VM._assert(Call.hasAddress(v));
        Call.setAddress(v, InsertLoadOffsetJTOC(v, ir, REF_LOAD, TypeReference.CodeArray, Call.getClearAddress(v)));
    } else if (methOp.isVirtual()) {
        if (VM.VerifyAssertions)
            VM._assert(Call.hasAddress(v));
        if (ir.options.H2L_CALL_VIA_JTOC && methOp.hasPreciseTarget()) {
            // Call to precise type can go via JTOC
            RVMMethod target = methOp.getTarget();
            Call.setAddress(v, InsertLoadOffsetJTOC(v, ir, REF_LOAD, TypeReference.CodeArray, target.findOrCreateJtocOffset()));
        } else {
            Operand tib = getTIB(v, ir, Call.getParam(v, 0).copy(), Call.getGuard(v).copy());
            Call.setAddress(v, InsertLoadOffset(v, ir, REF_LOAD, TypeReference.CodeArray, tib, Call.getClearAddress(v), null, TG()));
        }
    } else if (methOp.isSpecial()) {
        RVMMethod target = methOp.getTarget();
        if (target == null || target.isObjectInitializer() || target.isStatic()) {
            // target == null => we are calling an unresolved <init> method.
            Call.setAddress(v, InsertLoadOffsetJTOC(v, ir, REF_LOAD, TypeReference.CodeArray, Call.getClearAddress(v)));
        } else {
            if (ir.options.H2L_CALL_VIA_JTOC) {
                Call.setAddress(v, InsertLoadOffsetJTOC(v, ir, REF_LOAD, TypeReference.CodeArray, target.findOrCreateJtocOffset()));
            } else {
                // invoking a virtual method; do it via TIB of target's declaring class.
                Operand tib = getTIB(v, ir, target.getDeclaringClass());
                Call.setAddress(v, InsertLoadOffset(v, ir, REF_LOAD, TypeReference.CodeArray, tib, Call.getClearAddress(v), null, TG()));
            }
        }
    } else {
        if (VM.VerifyAssertions)
            VM._assert(methOp.isInterface());
        if (VM.VerifyAssertions)
            VM._assert(!Call.hasAddress(v));
        if (VM.BuildForIMTInterfaceInvocation) {
            // SEE ALSO: FinalMIRExpansion (for hidden parameter)
            Operand RHStib = getTIB(v, ir, Call.getParam(v, 0).copy(), Call.getGuard(v).copy());
            InterfaceMethodSignature sig = InterfaceMethodSignature.findOrCreate(methOp.getMemberRef());
            Offset offset = sig.getIMTOffset();
            RegisterOperand address = null;
            RegisterOperand IMT = InsertLoadOffset(v, ir, REF_LOAD, TypeReference.IMT, RHStib.copy(), Offset.fromIntZeroExtend(TIB_INTERFACE_DISPATCH_TABLE_INDEX << LOG_BYTES_IN_ADDRESS));
            address = InsertLoadOffset(v, ir, REF_LOAD, TypeReference.CodeArray, IMT.copyD2U(), offset);
            Call.setAddress(v, address);
        } else {
            int itableIndex = -1;
            if (VM.BuildForITableInterfaceInvocation && methOp.hasTarget()) {
                RVMClass I = methOp.getTarget().getDeclaringClass();
                // search ITable variant
                itableIndex = InterfaceInvocation.getITableIndex(I, methOp.getMemberRef().getName(), methOp.getMemberRef().getDescriptor());
            }
            if (itableIndex == -1) {
                // itable index is not known at compile-time.
                // call "invokeinterface" to resolve the object and method id
                // into a method address
                RegisterOperand realAddrReg = ir.regpool.makeTemp(TypeReference.CodeArray);
                RVMMethod target = Entrypoints.invokeInterfaceMethod;
                Instruction vp = Call.create2(CALL, realAddrReg, AC(target.getOffset()), MethodOperand.STATIC(target), Call.getParam(v, 0).asRegister().copyU2U(), IC(methOp.getMemberRef().getId()));
                vp.setSourcePosition(RUNTIME_SERVICES_BCI, v.position());
                v.insertBefore(vp);
                callHelper(vp, ir);
                Call.setAddress(v, realAddrReg.copyD2U());
                return v;
            } else {
                // itable index is known at compile-time.
                // call "findITable" to resolve object + interface id into
                // itable address
                RegisterOperand iTable = ir.regpool.makeTemp(TypeReference.ITable);
                Operand RHStib = getTIB(v, ir, Call.getParam(v, 0).copy(), Call.getGuard(v).copy());
                RVMMethod target = Entrypoints.findItableMethod;
                Instruction fi = Call.create2(CALL, iTable, AC(target.getOffset()), MethodOperand.STATIC(target), RHStib, IC(methOp.getTarget().getDeclaringClass().getInterfaceId()));
                fi.setSourcePosition(RUNTIME_SERVICES_BCI, v.position());
                v.insertBefore(fi);
                callHelper(fi, ir);
                RegisterOperand address = InsertLoadOffset(v, ir, REF_LOAD, TypeReference.CodeArray, iTable.copyD2U(), Offset.fromIntZeroExtend(itableIndex << LOG_BYTES_IN_ADDRESS));
                Call.setAddress(v, address);
                return v;
            }
        }
    }
    return v;
}
Also used : InterfaceMethodSignature(org.jikesrvm.classloader.InterfaceMethodSignature) RVMMethod(org.jikesrvm.classloader.RVMMethod) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) SpecializedMethod(org.jikesrvm.compilers.opt.specialization.SpecializedMethod) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) 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) 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) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) Offset(org.vmmagic.unboxed.Offset) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 54 with RVMClass

use of org.jikesrvm.classloader.RVMClass in project JikesRVM by JikesRVM.

the class DynamicTypeCheckExpansion method generateValueProducingTypeCheck.

/**
 * Generate a value-producing dynamic type check.
 * This routine assumes that the CFG and code order are
 * already correctly established.
 * This routine must either remove s or mutuate it.
 *
 * @param s        The Instruction that is to be replaced by
 *                  a value producing type check
 * @param ir       The IR containing the instruction to be expanded.
 * @param RHSobj   The RegisterOperand containing the rhs object.
 * @param LHStype  The RVMType to be tested against.
 * @param RHStib   The Operand containing the TIB of the rhs.
 * @param result   The RegisterOperand that the result of dynamic
 *                 type check is to be stored in.
 * @return the opt instruction immediately before the
 *         instruction to continue expansion.
 */
private static Instruction generateValueProducingTypeCheck(Instruction s, IR ir, Operand RHSobj, TypeReference LHStype, Operand RHStib, RegisterOperand result) {
    // Is LHStype a class?
    if (LHStype.isClassType()) {
        RVMClass LHSclass = (RVMClass) LHStype.peekType();
        if (LHSclass != null && LHSclass.isResolved()) {
            // resolved class or interface
            if (LHSclass.isInterface()) {
                // A resolved interface (case 4)
                int interfaceIndex = LHSclass.getDoesImplementIndex();
                int interfaceMask = LHSclass.getDoesImplementBitMask();
                RegisterOperand doesImpl = InsertUnary(s, ir, GET_DOES_IMPLEMENT_FROM_TIB, TypeReference.IntArray, RHStib);
                RegisterOperand entry = InsertLoadOffset(s, ir, INT_LOAD, TypeReference.Int, doesImpl, Offset.fromIntZeroExtend(interfaceIndex << 2), new LocationOperand(TypeReference.Int), TG());
                RegisterOperand bit = insertBinary(s, ir, INT_AND, TypeReference.Int, entry, IC(interfaceMask));
                // save to use the cheaper ADDR version of BOOLEAN_CMP
                s.insertBefore(BooleanCmp.create(BOOLEAN_CMP_ADDR, result, bit, AC(Address.zero()), ConditionOperand.NOT_EQUAL(), new BranchProfileOperand()));
                if (DynamicTypeCheck.MIN_DOES_IMPLEMENT_SIZE <= interfaceIndex) {
                    RegisterOperand doesImplLength = InsertGuardedUnary(s, ir, ARRAYLENGTH, TypeReference.Int, doesImpl.copy(), TG());
                    RegisterOperand boundscheck = ir.regpool.makeTempInt();
                    // save to use the cheaper ADDR version of BOOLEAN_CMP
                    s.insertBefore(BooleanCmp.create(BOOLEAN_CMP_ADDR, boundscheck, doesImplLength, AC(Address.fromIntSignExtend(interfaceIndex)), ConditionOperand.GREATER(), new BranchProfileOperand()));
                    s.insertBefore(Binary.create(INT_AND, result.copyD2D(), result.copyD2U(), boundscheck.copyD2U()));
                }
                Instruction continueAt = s.prevInstructionInCodeOrder();
                s.remove();
                return continueAt;
            } else {
                // A resolved class (cases 5 and 6 in DynamicTypeCheck)
                if (LHSclass.isFinal()) {
                    // For a final class, we can do a PTR compare of
                    // rhsTIB and the TIB of the class
                    Operand classTIB = getTIB(s, ir, LHSclass);
                    BooleanCmp.mutate(s, BOOLEAN_CMP_ADDR, result, RHStib, classTIB, ConditionOperand.EQUAL(), new BranchProfileOperand());
                    return s.prevInstructionInCodeOrder();
                } else {
                    // Do the full blown case 5 or 6 typecheck.
                    int LHSDepth = LHSclass.getTypeDepth();
                    int LHSId = LHSclass.getId();
                    RegisterOperand superclassIds = InsertUnary(s, ir, GET_SUPERCLASS_IDS_FROM_TIB, TypeReference.ShortArray, RHStib);
                    RegisterOperand refCandidate = InsertLoadOffset(s, ir, USHORT_LOAD, TypeReference.Short, superclassIds, Offset.fromIntZeroExtend(LHSDepth << 1), new LocationOperand(TypeReference.Short), TG());
                    // save to use the cheaper ADDR version of BOOLEAN_CMP
                    s.insertBefore(BooleanCmp.create(BOOLEAN_CMP_ADDR, result, refCandidate, AC(Address.fromIntZeroExtend(LHSId)), ConditionOperand.EQUAL(), new BranchProfileOperand()));
                    if (DynamicTypeCheck.MIN_SUPERCLASS_IDS_SIZE <= LHSDepth) {
                        RegisterOperand superclassIdsLength = InsertGuardedUnary(s, ir, ARRAYLENGTH, TypeReference.Int, superclassIds.copyD2U(), TG());
                        RegisterOperand boundscheck = ir.regpool.makeTempInt();
                        // save to use the cheaper ADDR version of BOOLEAN_CMP
                        s.insertBefore(BooleanCmp.create(BOOLEAN_CMP_ADDR, boundscheck, superclassIdsLength, AC(Address.fromIntSignExtend(LHSDepth)), ConditionOperand.GREATER(), new BranchProfileOperand()));
                        s.insertBefore(Binary.create(INT_AND, result.copyD2D(), result.copyD2U(), boundscheck.copyD2U()));
                    }
                    Instruction continueAt = s.prevInstructionInCodeOrder();
                    s.remove();
                    return continueAt;
                }
            }
        } else {
            // A non-resolved class or interface.
            // We expect these to be extremely uncommon in opt code in AOS.
            // Mutate s into a call to RuntimeEntrypoints.instanceOf
            RVMMethod target = Entrypoints.instanceOfMethod;
            Call.mutate2(s, CALL, result, AC(target.getOffset()), MethodOperand.STATIC(target), RHSobj, IC(LHStype.getId()));
            return callHelper(s, ir);
        }
    }
    if (LHStype.isArrayType()) {
        // Case 2 of DynamicTypeCheck: LHS is an array.
        RVMArray LHSArray = (RVMArray) LHStype.peekType();
        if (LHSArray != null) {
            RVMType innermostElementType = LHSArray.getInnermostElementType();
            if (innermostElementType.isPrimitiveType() || innermostElementType.isUnboxedType() || (innermostElementType.asClass().isResolved() && innermostElementType.asClass().isFinal())) {
                // [^k of primitive or [^k of final class. Just like final classes,
                // a PTR compare of rhsTIB and the TIB of the class gives the answer.
                Operand classTIB = getTIB(s, ir, LHSArray);
                BooleanCmp.mutate(s, BOOLEAN_CMP_ADDR, result, RHStib, classTIB, ConditionOperand.EQUAL(), new BranchProfileOperand());
                return s;
            }
        }
        // and do the real work there.
        return convertToBranchingTypeCheck(s, ir, RHSobj, LHStype, RHStib, result);
    }
    OptimizingCompilerException.UNREACHABLE();
    return null;
}
Also used : 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) RVMArray(org.jikesrvm.classloader.RVMArray) RVMType(org.jikesrvm.classloader.RVMType) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 55 with RVMClass

use of org.jikesrvm.classloader.RVMClass 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

RVMClass (org.jikesrvm.classloader.RVMClass)69 RVMMethod (org.jikesrvm.classloader.RVMMethod)28 TypeReference (org.jikesrvm.classloader.TypeReference)22 RVMType (org.jikesrvm.classloader.RVMType)20 Atom (org.jikesrvm.classloader.Atom)14 RVMField (org.jikesrvm.classloader.RVMField)11 RVMArray (org.jikesrvm.classloader.RVMArray)8 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)8 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)8 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)8 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)8 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)8 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)7 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)7 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)7 Address (org.vmmagic.unboxed.Address)7 NormalMethod (org.jikesrvm.classloader.NormalMethod)6 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)6 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)6 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)5