Search in sources :

Example 51 with TypeReference

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

the class OptTestHarness method processOptionString.

private void processOptionString(String[] args) {
    for (int i = 0, n = args.length; i < n; i++) {
        try {
            String arg = args[i];
            if (arg.startsWith("-oc:") && options.processAsOption("-X:irc:", arg.substring(4))) {
            // handled in processAsOption
            } else if ("-useBootOptions".equals(arg)) {
                OptimizingCompiler.setBootOptions(options);
            } else if ("-longcommandline".equals(arg)) {
                // the -longcommandline option reads options from a file.
                String fileName = args[++i];
                String[] optionString = fileAccess.readOptionStringFromFile(fileName);
                processOptionString(optionString);
            } else if ("+baseline".equals(arg)) {
                useBaselineCompiler = true;
            } else if ("-baseline".equals(arg)) {
                useBaselineCompiler = false;
            } else if ("-load".equals(arg)) {
                loadClass(args[++i]);
            } else if ("-class".equals(arg)) {
                RVMClass klass = loadClass(args[++i]);
                processClass(klass, options);
                duplicateOptions();
            } else if ("-method".equals(arg) || "-methodOpt".equals(arg) || "-methodBase".equals(arg)) {
                // Default for this method is determined by BASELINE var
                boolean isBaseline = useBaselineCompiler;
                // Unless specified by these options
                if ("-methodOpt".equals(arg)) {
                    isBaseline = false;
                }
                if ("-methodBase".equals(arg)) {
                    isBaseline = true;
                }
                RVMClass klass = null;
                try {
                    klass = loadClass(args[++i]);
                } catch (Exception e) {
                    output.sysErrPrintln("WARNING: Skipping method from " + args[i]);
                }
                if (klass == null)
                    continue;
                String name = args[++i];
                String desc = args[++i];
                RVMMethod method = findDeclaredOrFirstMethod(klass, name, desc);
                if (method == null || method.isAbstract() || method.isNative()) {
                    output.sysErrPrintln("WARNING: Skipping method " + args[i - 2] + "." + name);
                } else {
                    processMethod(method, options, isBaseline);
                }
                duplicateOptions();
            } else if ("-performance".equals(arg)) {
                perf = new Performance(output);
            } else if ("-disableClassLoading".equals(arg)) {
                disableClassloading = true;
            } else if ("-er".equals(arg)) {
                executeWithReflection = true;
                RVMClass klass = loadClass(args[++i]);
                String name = args[++i];
                String desc = args[++i];
                NormalMethod method = (NormalMethod) findDeclaredOrFirstMethod(klass, name, desc);
                CompiledMethod cm = null;
                if (method == null) {
                    output.sysErrPrintln("Canceling further option processing to prevent assertion failures.");
                    return;
                }
                if (useBaselineCompiler) {
                    cm = BaselineCompiler.compile(method);
                } else {
                    CompilationPlan cp = new CompilationPlan(method, OptimizationPlanner.createOptimizationPlan(options), null, options);
                    try {
                        cm = OptimizingCompiler.compile(cp);
                    } catch (Throwable e) {
                        output.sysErrPrintln("SKIPPING method:" + method + "Due to exception: " + e);
                    }
                }
                if (cm != null) {
                    method.replaceCompiledMethod(cm);
                    if (printCodeAddress) {
                        output.sysOutPrintln(compiledMethodMessage(method));
                    }
                }
                TypeReference[] argDesc = method.getDescriptor().parseForParameterTypes(klass.getClassLoader());
                Object[] reflectMethodArgs = new Object[argDesc.length];
                i = parseMethodArgs(argDesc, args, i, reflectMethodArgs);
                java.lang.reflect.Method reflectoid = java.lang.reflect.JikesRVMSupport.createMethod(method);
                reflectoidVector.add(reflectoid);
                reflectMethodVector.add(method);
                reflectMethodArgsVector.add(reflectMethodArgs);
                duplicateOptions();
            } else if ("-main".equals(arg)) {
                executeMainMethod = true;
                i++;
                mainClass = loadClass(args[i]);
                i++;
                mainArgs = new String[args.length - i];
                for (int j = 0, z = mainArgs.length; j < z; j++) {
                    mainArgs[j] = args[i + j];
                }
                break;
            } else {
                output.sysErrPrintln("Unrecognized argument: " + arg + " - ignored");
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            output.sysErrPrintln("Uncaught ArrayIndexOutOfBoundsException, possibly" + " not enough command-line arguments - aborting");
            printFormatString();
            e.printStackTrace(output.getSystemErr());
            break;
        } catch (Exception e) {
            output.sysErrPrintln(e.toString());
            e.printStackTrace(output.getSystemErr());
            break;
        }
    }
}
Also used : CompilationPlan(org.jikesrvm.compilers.opt.driver.CompilationPlan) InvocationTargetException(java.lang.reflect.InvocationTargetException) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) RVMClass(org.jikesrvm.classloader.RVMClass) RVMMethod(org.jikesrvm.classloader.RVMMethod) NormalMethod(org.jikesrvm.classloader.NormalMethod) TypeReference(org.jikesrvm.classloader.TypeReference) Method(java.lang.reflect.Method)

Example 52 with TypeReference

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

the class DynamicTypeCheckExpansion method instanceOf.

/**
 * Expand an instanceof instruction into the LIR sequence that implements
 * the dynamic type check.  Ref may contain a null ptr at runtime.
 *
 * @param s an INSTANCEOF or INSTANCEOF_UNRESOLVED instruction to expand
 * @param ir the enclosing IR
 * @return the last Instruction in the generated LIR sequence.
 */
static Instruction instanceOf(Instruction s, IR ir) {
    RegisterOperand result = InstanceOf.getClearResult(s);
    TypeReference LHStype = InstanceOf.getType(s).getTypeRef();
    Operand ref = InstanceOf.getClearRef(s);
    Instruction next = s.nextInstructionInCodeOrder();
    if (next.operator() == INT_IFCMP && IfCmp.getVal1(next) instanceof RegisterOperand && result.similar(IfCmp.getVal1(next))) {
        // The result of instanceof is being consumed by a conditional branch.
        // Optimize this case by generating a branching type check
        // instead of producing a value.
        // TODO: This is really not safe: suppose the if is NOT the
        // only use of the result of the instanceof.
        // The way to fix this is to add ifInstanceOf and ifNotInstanceOf
        // operators to the IR and have Simple transform
        // instanceof, intIfCmp based on the U/D chains.
        // See defect 2114.
        Operand val2 = IfCmp.getVal2(next);
        if (VM.VerifyAssertions)
            VM._assert(val2.isIntConstant());
        int ival2 = ((IntConstantOperand) val2).value;
        ConditionOperand cond = IfCmp.getCond(next);
        boolean branchCondition = (((ival2 == 0) && (cond.isNOT_EQUAL() || cond.isLESS_EQUAL())) || ((ival2 == 1) && (cond.isEQUAL() || cond.isGREATER_EQUAL())));
        BasicBlock branchBB = next.getBranchTarget();
        RegisterOperand oldGuard = IfCmp.getGuardResult(next);
        next.remove();
        BasicBlock fallThroughBB = fallThroughBB(s, ir);
        BasicBlock falseBranch = branchCondition ? fallThroughBB : branchBB;
        BasicBlock trueBranch = branchCondition ? branchBB : fallThroughBB;
        BranchProfileOperand bp = IfCmp.getClearBranchProfile(next);
        if (branchCondition)
            bp = bp.flip();
        Instruction nullComp = IfCmp.create(REF_IFCMP, oldGuard.copyRO(), ref.copy(), new NullConstantOperand(), ConditionOperand.EQUAL(), falseBranch.makeJumpTarget(), BranchProfileOperand.unlikely());
        s.insertBefore(nullComp);
        BasicBlock myBlock = s.getBasicBlock();
        BasicBlock instanceOfBlock = myBlock.splitNodeAt(nullComp, ir);
        myBlock.insertOut(instanceOfBlock);
        myBlock.insertOut(falseBranch);
        ir.cfg.linkInCodeOrder(myBlock, instanceOfBlock);
        Operand RHStib = getTIB(s, ir, ref, oldGuard.copyRO());
        return generateBranchingTypeCheck(s, ir, ref.copy(), LHStype, RHStib, trueBranch, falseBranch, oldGuard.copy().asRegister(), bp);
    } else {
        // Not a branching pattern
        RegisterOperand guard = ir.regpool.makeTempValidation();
        BasicBlock instanceOfBlock = s.getBasicBlock().segregateInstruction(s, ir);
        BasicBlock prevBB = instanceOfBlock.prevBasicBlockInCodeOrder();
        BasicBlock nextBB = instanceOfBlock.nextBasicBlockInCodeOrder();
        BasicBlock nullCaseBB = instanceOfBlock.createSubBlock(s.getBytecodeIndex(), ir, .01f);
        prevBB.appendInstruction(IfCmp.create(REF_IFCMP, guard, ref.copy(), new NullConstantOperand(), ConditionOperand.EQUAL(), nullCaseBB.makeJumpTarget(), BranchProfileOperand.unlikely()));
        nullCaseBB.appendInstruction(Move.create(INT_MOVE, result.copyD2D(), IC(0)));
        nullCaseBB.appendInstruction(Goto.create(GOTO, nextBB.makeJumpTarget()));
        // Stitch together the CFG; add nullCaseBB to the end of code array.
        prevBB.insertOut(nullCaseBB);
        nullCaseBB.insertOut(nextBB);
        ir.cfg.addLastInCodeOrder(nullCaseBB);
        Operand RHStib = getTIB(s, ir, ref, guard.copyD2U());
        return generateValueProducingTypeCheck(s, ir, ref.copy(), LHStype, RHStib, result);
    }
}
Also used : NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) 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) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) TypeReference(org.jikesrvm.classloader.TypeReference) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 53 with TypeReference

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

the class ExpandRuntimeServices method perform.

/**
 * Given an HIR, expand operators that are implemented as calls to
 * runtime service methods. This method should be called as one of the
 * first steps in lowering HIR into LIR.
 *
 * @param ir  The HIR to expand
 */
@Override
public void perform(IR ir) {
    // resync generation context -- yuck...
    ir.getGc().resync();
    for (Instruction inst = ir.firstInstructionInCodeOrder(); inst != null; inst = next) {
        next = inst.nextInstructionInCodeOrder();
        int opcode = inst.getOpcode();
        switch(opcode) {
            case NEW_opcode:
                {
                    TypeOperand Type = New.getClearType(inst);
                    RVMClass cls = (RVMClass) Type.getVMType();
                    IntConstantOperand hasFinalizer = IRTools.IC(cls.hasFinalizer() ? 1 : 0);
                    RVMMethod callSite = inst.position().getMethod();
                    IntConstantOperand allocator = IRTools.IC(MemoryManager.pickAllocator(cls, callSite));
                    IntConstantOperand align = IRTools.IC(ObjectModel.getAlignment(cls));
                    IntConstantOperand offset = IRTools.IC(ObjectModel.getOffsetForAlignment(cls, false));
                    Operand tib = ConvertToLowLevelIR.getTIB(inst, ir, Type);
                    if (VM.BuildForIA32 && VM.runningVM) {
                        // shield BC2IR from address constants
                        RegisterOperand tmp = ir.regpool.makeTemp(TypeReference.TIB);
                        inst.insertBefore(Move.create(REF_MOVE, tmp, tib));
                        tib = tmp.copyRO();
                    }
                    IntConstantOperand site = IRTools.IC(MemoryManager.getAllocationSite(true));
                    RVMMethod target = Entrypoints.resolvedNewScalarMethod;
                    Call.mutate7(inst, CALL, New.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), IRTools.IC(cls.getInstanceSize()), tib, hasFinalizer, allocator, align, offset, site);
                    next = inst.prevInstructionInCodeOrder();
                    if (ir.options.H2L_INLINE_NEW) {
                        if (inst.getBasicBlock().getInfrequent())
                            container.counter1++;
                        container.counter2++;
                        if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) {
                            inline(inst, ir);
                        }
                    }
                }
                break;
            case NEW_UNRESOLVED_opcode:
                {
                    int typeRefId = New.getType(inst).getTypeRef().getId();
                    RVMMethod target = Entrypoints.unresolvedNewScalarMethod;
                    IntConstantOperand site = IRTools.IC(MemoryManager.getAllocationSite(true));
                    Call.mutate2(inst, CALL, New.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), IRTools.IC(typeRefId), site);
                }
                break;
            case NEWARRAY_opcode:
                {
                    TypeOperand Array = NewArray.getClearType(inst);
                    RVMArray array = (RVMArray) Array.getVMType();
                    Operand numberElements = NewArray.getClearSize(inst);
                    boolean inline = numberElements instanceof IntConstantOperand;
                    Operand width = IRTools.IC(array.getLogElementSize());
                    Operand headerSize = IRTools.IC(ObjectModel.computeArrayHeaderSize(array));
                    RVMMethod callSite = inst.position().getMethod();
                    IntConstantOperand allocator = IRTools.IC(MemoryManager.pickAllocator(array, callSite));
                    IntConstantOperand align = IRTools.IC(ObjectModel.getAlignment(array));
                    IntConstantOperand offset = IRTools.IC(ObjectModel.getOffsetForAlignment(array, false));
                    Operand tib = ConvertToLowLevelIR.getTIB(inst, ir, Array);
                    if (VM.BuildForIA32 && VM.runningVM) {
                        // shield BC2IR from address constants
                        RegisterOperand tmp = ir.regpool.makeTemp(TypeReference.TIB);
                        inst.insertBefore(Move.create(REF_MOVE, tmp, tib));
                        tib = tmp.copyRO();
                    }
                    IntConstantOperand site = IRTools.IC(MemoryManager.getAllocationSite(true));
                    RVMMethod target = Entrypoints.resolvedNewArrayMethod;
                    Call.mutate8(inst, CALL, NewArray.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), numberElements, width, headerSize, tib, allocator, align, offset, site);
                    next = inst.prevInstructionInCodeOrder();
                    if (inline && ir.options.H2L_INLINE_NEW) {
                        if (inst.getBasicBlock().getInfrequent())
                            container.counter1++;
                        container.counter2++;
                        if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) {
                            inline(inst, ir);
                        }
                    }
                }
                break;
            case NEWARRAY_UNRESOLVED_opcode:
                {
                    int typeRefId = NewArray.getType(inst).getTypeRef().getId();
                    Operand numberElements = NewArray.getClearSize(inst);
                    RVMMethod target = Entrypoints.unresolvedNewArrayMethod;
                    IntConstantOperand site = IRTools.IC(MemoryManager.getAllocationSite(true));
                    Call.mutate3(inst, CALL, NewArray.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), numberElements, IRTools.IC(typeRefId), site);
                }
                break;
            case NEWOBJMULTIARRAY_opcode:
                {
                    int dimensions = Multianewarray.getNumberOfDimensions(inst);
                    RVMMethod callSite = inst.position().getMethod();
                    int typeRefId = Multianewarray.getType(inst).getTypeRef().getId();
                    if (dimensions == 2) {
                        RVMMethod target = Entrypoints.optNew2DArrayMethod;
                        Call.mutate4(inst, CALL, Multianewarray.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), IRTools.IC(callSite.getId()), Multianewarray.getClearDimension(inst, 0), Multianewarray.getClearDimension(inst, 1), IRTools.IC(typeRefId));
                    } else {
                        // Step 1: Create an int array to hold the dimensions.
                        TypeOperand dimArrayType = new TypeOperand(RVMArray.IntArray);
                        RegisterOperand dimArray = ir.regpool.makeTemp(TypeReference.IntArray);
                        dimArray.setPreciseType();
                        next = NewArray.create(NEWARRAY, dimArray, dimArrayType, new IntConstantOperand(dimensions));
                        inst.insertBefore(next);
                        // Step 2: Assign the dimension values to dimArray
                        for (int i = 0; i < dimensions; i++) {
                            LocationOperand loc = new LocationOperand(TypeReference.Int);
                            inst.insertBefore(AStore.create(INT_ASTORE, Multianewarray.getClearDimension(inst, i), dimArray.copyD2U(), IRTools.IC(i), loc, IRTools.TG()));
                        }
                        // Step 3. Plant call to OptLinker.newArrayArray
                        RVMMethod target = Entrypoints.optNewArrayArrayMethod;
                        Call.mutate3(inst, CALL, Multianewarray.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), IRTools.IC(callSite.getId()), dimArray.copyD2U(), IRTools.IC(typeRefId));
                    }
                }
                break;
            case ATHROW_opcode:
                {
                    RVMMethod target = Entrypoints.athrowMethod;
                    MethodOperand methodOp = MethodOperand.STATIC(target);
                    // Record the fact that this is a non-returning call.
                    methodOp.setIsNonReturningCall(true);
                    Call.mutate1(inst, CALL, null, IRTools.AC(target.getOffset()), methodOp, Athrow.getClearValue(inst));
                }
                break;
            case MONITORENTER_opcode:
                {
                    Operand ref = MonitorOp.getClearRef(inst);
                    RVMType refType = ref.getType().peekType();
                    if (refType != null && !refType.getThinLockOffset().isMax()) {
                        RVMMethod target = Entrypoints.inlineLockMethod;
                        Call.mutate2(inst, CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), MonitorOp.getClearGuard(inst), ref, IRTools.AC(refType.getThinLockOffset()));
                        next = inst.prevInstructionInCodeOrder();
                        if (inst.getBasicBlock().getInfrequent())
                            container.counter1++;
                        container.counter2++;
                        if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) {
                            inline(inst, ir);
                        }
                    } else {
                        RVMMethod target = Entrypoints.lockMethod;
                        Call.mutate1(inst, CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), MonitorOp.getClearGuard(inst), ref);
                    }
                }
                break;
            case MONITOREXIT_opcode:
                {
                    Operand ref = MonitorOp.getClearRef(inst);
                    RVMType refType = ref.getType().peekType();
                    if (refType != null && !refType.getThinLockOffset().isMax()) {
                        RVMMethod target = Entrypoints.inlineUnlockMethod;
                        Call.mutate2(inst, CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), MonitorOp.getClearGuard(inst), ref, IRTools.AC(refType.getThinLockOffset()));
                        next = inst.prevInstructionInCodeOrder();
                        if (inst.getBasicBlock().getInfrequent())
                            container.counter1++;
                        container.counter2++;
                        if (!ir.options.FREQ_FOCUS_EFFORT || !inst.getBasicBlock().getInfrequent()) {
                            inline(inst, ir);
                        }
                    } else {
                        RVMMethod target = Entrypoints.unlockMethod;
                        Call.mutate1(inst, CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), MonitorOp.getClearGuard(inst), ref);
                    }
                }
                break;
            case REF_ASTORE_opcode:
                {
                    if (NEEDS_OBJECT_ASTORE_BARRIER) {
                        RVMMethod target = Entrypoints.objectArrayWriteBarrierMethod;
                        Instruction wb = Call.create3(CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), AStore.getClearGuard(inst), AStore.getArray(inst).copy(), AStore.getIndex(inst).copy(), AStore.getValue(inst).copy());
                        replaceInstructionWithBarrier(inst, wb);
                        if (ir.options.H2L_INLINE_WRITE_BARRIER) {
                            inline(wb, ir, true);
                        }
                    }
                }
                break;
            case BYTE_ASTORE_opcode:
                {
                    if (NEEDS_BYTE_ASTORE_BARRIER) {
                        primitiveArrayStoreHelper(Entrypoints.byteArrayWriteBarrierMethod, inst, ir);
                    }
                }
                break;
            case DOUBLE_ASTORE_opcode:
                {
                    if (NEEDS_DOUBLE_ASTORE_BARRIER) {
                        primitiveArrayStoreHelper(Entrypoints.doubleArrayWriteBarrierMethod, inst, ir);
                    }
                }
                break;
            case FLOAT_ASTORE_opcode:
                {
                    if (NEEDS_FLOAT_ASTORE_BARRIER) {
                        primitiveArrayStoreHelper(Entrypoints.floatArrayWriteBarrierMethod, inst, ir);
                    }
                }
                break;
            case INT_ASTORE_opcode:
                {
                    if (NEEDS_INT_ASTORE_BARRIER) {
                        primitiveArrayStoreHelper(Entrypoints.intArrayWriteBarrierMethod, inst, ir);
                    }
                }
                break;
            case LONG_ASTORE_opcode:
                {
                    if (NEEDS_LONG_ASTORE_BARRIER) {
                        primitiveArrayStoreHelper(Entrypoints.longArrayWriteBarrierMethod, inst, ir);
                    }
                }
                break;
            case SHORT_ASTORE_opcode:
                {
                    TypeReference type = AStore.getLocation(inst).getElementType();
                    if (NEEDS_SHORT_ASTORE_BARRIER && type.isShortType()) {
                        primitiveArrayStoreHelper(Entrypoints.shortArrayWriteBarrierMethod, inst, ir);
                    } else if (NEEDS_CHAR_ASTORE_BARRIER) {
                        if (VM.VerifyAssertions)
                            VM._assert(type.isCharType());
                        primitiveArrayStoreHelper(Entrypoints.charArrayWriteBarrierMethod, inst, ir);
                    }
                }
                break;
            case REF_ALOAD_opcode:
                {
                    if (NEEDS_OBJECT_ALOAD_BARRIER) {
                        RVMMethod target = Entrypoints.objectArrayReadBarrierMethod;
                        Instruction rb = Call.create2(CALL, ALoad.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), ALoad.getClearGuard(inst), ALoad.getArray(inst).copy(), ALoad.getIndex(inst).copy());
                        replaceInstructionWithBarrier(inst, rb);
                        inline(rb, ir, true);
                    }
                }
                break;
            case PUTFIELD_opcode:
                {
                    if (NEEDS_OBJECT_PUTFIELD_BARRIER) {
                        LocationOperand loc = PutField.getLocation(inst);
                        FieldReference fieldRef = loc.getFieldRef();
                        if (!fieldRef.getFieldContentsType().isPrimitiveType()) {
                            // reference PUTFIELD
                            RVMField field = fieldRef.peekResolvedField();
                            if (field == null || !field.isUntraced()) {
                                RVMMethod target = Entrypoints.objectFieldWriteBarrierMethod;
                                Instruction wb = Call.create4(CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), PutField.getClearGuard(inst), PutField.getRef(inst).copy(), PutField.getValue(inst).copy(), PutField.getOffset(inst).copy(), IRTools.IC(fieldRef.getId()));
                                replaceInstructionWithBarrier(inst, wb);
                                if (ir.options.H2L_INLINE_WRITE_BARRIER) {
                                    inline(wb, ir, true);
                                }
                            }
                        } else {
                            // primitive PUTFIELD
                            if (NEEDS_BOOLEAN_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isBooleanType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.booleanFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_BYTE_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isByteType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.byteFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_CHAR_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isCharType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.charFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_DOUBLE_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isDoubleType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.doubleFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_FLOAT_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isFloatType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.floatFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_INT_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isIntType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.intFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_LONG_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isLongType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.longFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_SHORT_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isShortType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.shortFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_WORD_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isWordType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.wordFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_ADDRESS_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isAddressType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.addressFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_EXTENT_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isExtentType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.extentFieldWriteBarrierMethod, inst, ir, fieldRef);
                            } else if (NEEDS_OFFSET_PUTFIELD_BARRIER && fieldRef.getFieldContentsType().isOffsetType()) {
                                primitiveObjectFieldStoreHelper(Entrypoints.offsetFieldWriteBarrierMethod, inst, ir, fieldRef);
                            }
                        }
                    }
                }
                break;
            case GETFIELD_opcode:
                {
                    if (NEEDS_OBJECT_GETFIELD_BARRIER) {
                        LocationOperand loc = GetField.getLocation(inst);
                        FieldReference fieldRef = loc.getFieldRef();
                        if (GetField.getResult(inst).getType().isReferenceType()) {
                            RVMField field = fieldRef.peekResolvedField();
                            if (field == null || !field.isUntraced()) {
                                RVMMethod target = Entrypoints.objectFieldReadBarrierMethod;
                                Instruction rb = Call.create3(CALL, GetField.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), GetField.getClearGuard(inst), GetField.getRef(inst).copy(), GetField.getOffset(inst).copy(), IRTools.IC(fieldRef.getId()));
                                replaceInstructionWithBarrier(inst, rb);
                                inline(rb, ir, true);
                            }
                        }
                    }
                }
                break;
            case PUTSTATIC_opcode:
                {
                    if (NEEDS_OBJECT_PUTSTATIC_BARRIER) {
                        LocationOperand loc = PutStatic.getLocation(inst);
                        FieldReference field = loc.getFieldRef();
                        if (!field.getFieldContentsType().isPrimitiveType()) {
                            RVMMethod target = Entrypoints.objectStaticWriteBarrierMethod;
                            Instruction wb = Call.create3(CALL, null, IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), PutStatic.getValue(inst).copy(), PutStatic.getOffset(inst).copy(), IRTools.IC(field.getId()));
                            replaceInstructionWithBarrier(inst, wb);
                            if (ir.options.H2L_INLINE_WRITE_BARRIER) {
                                inline(wb, ir, true);
                            }
                        }
                    }
                }
                break;
            case GETSTATIC_opcode:
                {
                    if (NEEDS_OBJECT_GETSTATIC_BARRIER) {
                        LocationOperand loc = GetStatic.getLocation(inst);
                        FieldReference field = loc.getFieldRef();
                        if (!field.getFieldContentsType().isPrimitiveType()) {
                            RVMMethod target = Entrypoints.objectStaticReadBarrierMethod;
                            Instruction rb = Call.create2(CALL, GetStatic.getClearResult(inst), IRTools.AC(target.getOffset()), MethodOperand.STATIC(target), GetStatic.getOffset(inst).copy(), IRTools.IC(field.getId()));
                            replaceInstructionWithBarrier(inst, rb);
                            inline(rb, ir, true);
                        }
                    }
                }
                break;
            default:
                break;
        }
    }
    // If we actually inlined anything, clean up the mess
    if (didSomething) {
        if (branchOpts == null) {
            branchOpts = new BranchOptimizations(-1, true, true);
        }
        branchOpts.perform(ir, true);
        if (_os == null) {
            _os = new Simple(1, false, false, false, false);
        }
        _os.perform(ir);
    }
    // signal that we do not intend to use the gc in other phases anymore.
    ir.getGc().close();
}
Also used : IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) FieldReference(org.jikesrvm.classloader.FieldReference) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) RVMType(org.jikesrvm.classloader.RVMType) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) RVMClass(org.jikesrvm.classloader.RVMClass) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) Simple(org.jikesrvm.compilers.opt.Simple) RVMMethod(org.jikesrvm.classloader.RVMMethod) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) RVMArray(org.jikesrvm.classloader.RVMArray) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) BranchOptimizations(org.jikesrvm.compilers.opt.controlflow.BranchOptimizations)

Example 54 with TypeReference

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

the class Reflection method outOfLineInvoke.

private static Object outOfLineInvoke(RVMMethod method, Object thisArg, Object[] otherArgs, boolean isNonvirtual) {
    // the class must be initialized before we can invoke a method
    // 
    RVMClass klass = method.getDeclaringClass();
    if (!klass.isInitialized()) {
        RuntimeEntrypoints.initializeClassForDynamicLink(klass);
    }
    // remember return type
    // Determine primitive type-ness early to avoid call (possible yield)
    // later while refs are possibly being held in int arrays.
    // 
    TypeReference returnType = method.getReturnType();
    boolean returnIsPrimitive = returnType.isPrimitiveType();
    // decide how to pass parameters
    // 
    int triple = 0;
    if (VM.BuildForIA32) {
        triple = org.jikesrvm.ia32.MachineReflection.countParameters(method);
    } else {
        if (VM.VerifyAssertions)
            VM._assert(VM.BuildForPowerPC);
        triple = org.jikesrvm.ppc.MachineReflection.countParameters(method);
    }
    int gprs = triple & REFLECTION_GPRS_MASK;
    WordArray GPRs = (gprs > 0) ? WordArray.create(gprs) : emptyWordArray;
    int fprs = (triple >> REFLECTION_GPRS_BITS) & 0x1F;
    double[] FPRs = (fprs > 0) ? new double[fprs] : emptyDoubleArray;
    byte[] FPRmeta;
    if (BuildForSSE2Full) {
        FPRmeta = (fprs > 0) ? new byte[fprs] : emptyByteArray;
    } else {
        FPRmeta = null;
    }
    int spillCount = triple >> (REFLECTION_GPRS_BITS + REFLECTION_FPRS_BITS);
    WordArray Spills = (spillCount > 0) ? WordArray.create(spillCount) : emptyWordArray;
    if (firstUse) {
        // force dynamic link sites in unwrappers to get resolved,
        // before disabling gc.
        // this is a bit silly, but I can't think of another way to do it [--DL]
        unwrapBoolean(wrapBoolean(0));
        unwrapByte(wrapByte((byte) 0));
        unwrapChar(wrapChar((char) 0));
        unwrapShort(wrapShort((short) 0));
        unwrapInt(wrapInt(0));
        unwrapLong(wrapLong(0));
        unwrapFloat(wrapFloat(0));
        unwrapDouble(wrapDouble(0));
        firstUse = false;
    }
    // choose actual method to be called
    // 
    RVMMethod targetMethod;
    if (isNonvirtual || method.isStatic() || method.isObjectInitializer()) {
        targetMethod = method;
    } else {
        RVMClass C = Magic.getObjectType(thisArg).asClass();
        if (!method.getDeclaringClass().isInterface()) {
            int tibIndex = method.getOffset().toInt() >>> LOG_BYTES_IN_ADDRESS;
            targetMethod = C.getVirtualMethods()[tibIndex - TIB_FIRST_VIRTUAL_METHOD_INDEX];
        } else {
            RVMClass I = method.getDeclaringClass();
            if (!RuntimeEntrypoints.isAssignableWith(I, C))
                throw new IncompatibleClassChangeError();
            targetMethod = C.findVirtualMethod(method.getName(), method.getDescriptor());
            if (targetMethod == null)
                throw new IncompatibleClassChangeError();
        }
    }
    // getCurrentCompiledMethod is synchronized but Unpreemptible.
    // Therefore there are no possible yieldpoints from the time
    // the compiledMethod is loaded in getCurrentCompiledMethod
    // to when we disable GC below.
    // We can't allow any yieldpoints between these points because of the way in which
    // we GC compiled code.  Once a method is marked as obsolete, if it is not
    // executing on the stack of some thread, then the process of collecting the
    // code and meta-data might be initiated.
    targetMethod.compile();
    CompiledMethod cm = targetMethod.getCurrentCompiledMethod();
    while (cm == null) {
        targetMethod.compile();
        cm = targetMethod.getCurrentCompiledMethod();
    }
    RVMThread.getCurrentThread().disableYieldpoints();
    CodeArray code = cm.getEntryCodeArray();
    if (VM.BuildForIA32) {
        org.jikesrvm.ia32.MachineReflection.packageParameters(method, thisArg, otherArgs, GPRs, FPRs, FPRmeta, Spills);
    } else {
        if (VM.VerifyAssertions)
            VM._assert(VM.BuildForPowerPC);
        org.jikesrvm.ppc.MachineReflection.packageParameters(method, thisArg, otherArgs, GPRs, FPRs, FPRmeta, Spills);
    }
    // critical: no yieldpoints/GCpoints between here and the invoke of code!
    // We may have references hidden in the GPRs and Spills arrays!!!
    RVMThread.getCurrentThread().enableYieldpoints();
    if (!returnIsPrimitive) {
        return Magic.invokeMethodReturningObject(code, GPRs, FPRs, FPRmeta, Spills);
    }
    if (returnType.isVoidType()) {
        Magic.invokeMethodReturningVoid(code, GPRs, FPRs, FPRmeta, Spills);
        return null;
    }
    if (returnType.isBooleanType()) {
        int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
        return x == 1;
    }
    if (returnType.isByteType()) {
        int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
        return (byte) x;
    }
    if (returnType.isShortType()) {
        int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
        return (short) x;
    }
    if (returnType.isCharType()) {
        int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
        return (char) x;
    }
    if (returnType.isIntType()) {
        return Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
    }
    if (returnType.isLongType()) {
        return Magic.invokeMethodReturningLong(code, GPRs, FPRs, FPRmeta, Spills);
    }
    if (returnType.isFloatType()) {
        return Magic.invokeMethodReturningFloat(code, GPRs, FPRs, FPRmeta, Spills);
    }
    if (returnType.isDoubleType()) {
        return Magic.invokeMethodReturningDouble(code, GPRs, FPRs, FPRmeta, Spills);
    }
    if (VM.VerifyAssertions)
        VM._assert(NOT_REACHED);
    return null;
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) CodeArray(org.jikesrvm.compilers.common.CodeArray) WordArray(org.vmmagic.unboxed.WordArray) TypeReference(org.jikesrvm.classloader.TypeReference) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 55 with TypeReference

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

the class RuntimeEntrypoints method instanceOf.

// ---------------------------------------------------------------//
// Type Checking.                            //
// ---------------------------------------------------------------//
/**
 * Test if object is instance of target class/array or
 * implements target interface.
 * @param object object to be tested
 * @param targetID type reference id corresponding to target
 *                 class/array/interface
 * @return true iff is object instance of target type?
 */
@Entrypoint
static boolean instanceOf(Object object, int targetID) throws NoClassDefFoundError {
    /*  Here, LHS and RHS refer to the way we would treat these if they were
        arguments to an assignment operator and we were testing for
        assignment-compatibility.  In Java, "rhs instanceof lhs" means that
        the operation "lhs = rhs" would succeed.   This of course is backwards
        if one is looking at it from the point of view of the "instanceof"
        operator.  */
    TypeReference tRef = TypeReference.getTypeRef(targetID);
    RVMType lhsType = tRef.peekType();
    if (lhsType == null) {
        lhsType = tRef.resolve();
    }
    if (!lhsType.isResolved()) {
        // forces loading/resolution of super class/interfaces
        lhsType.resolve();
    }
    /* Test for null only AFTER we have resolved the type of targetID. */
    if (object == null) {
        // null is not an instance of any type
        return false;
    }
    RVMType rhsType = ObjectModel.getObjectType(object);
    /* RHS must already be resolved, since we have a non-null object that is
       an instance of RHS  */
    if (VM.VerifyAssertions)
        VM._assert(rhsType.isResolved());
    if (VM.VerifyAssertions)
        VM._assert(lhsType.isResolved());
    return lhsType == rhsType || DynamicTypeCheck.instanceOfResolved(lhsType, rhsType);
}
Also used : RVMType(org.jikesrvm.classloader.RVMType) TypeReference(org.jikesrvm.classloader.TypeReference) Entrypoint(org.vmmagic.pragma.Entrypoint)

Aggregations

TypeReference (org.jikesrvm.classloader.TypeReference)164 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)58 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)43 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)38 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)30 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)28 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)27 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)25 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)24 RVMClass (org.jikesrvm.classloader.RVMClass)23 RVMField (org.jikesrvm.classloader.RVMField)21 Register (org.jikesrvm.compilers.opt.ir.Register)21 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)21 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)21 Address (org.vmmagic.unboxed.Address)21 RVMType (org.jikesrvm.classloader.RVMType)18 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)18 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)18 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)18 RVMMethod (org.jikesrvm.classloader.RVMMethod)17