Search in sources :

Example 11 with RVMArray

use of org.jikesrvm.classloader.RVMArray 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 12 with RVMArray

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

the class RuntimeEntrypoints method buildTwoDimensionalArray.

/**
 * Build a two-dimensional array.
 * @param methodId  TODO document me
 * @param dim0 the arraylength for arrays in dimension 0
 * @param dim1 the arraylength for arrays in dimension 1
 * @param arrayType type of array that will result
 * @return array object
 */
public static Object buildTwoDimensionalArray(int methodId, int dim0, int dim1, RVMArray arrayType) {
    RVMMethod method = MemberReference.getMethodRef(methodId).peekResolvedMethod();
    if (VM.VerifyAssertions)
        VM._assert(method != null);
    if (!arrayType.isInstantiated()) {
        arrayType.resolve();
        arrayType.instantiate();
    }
    Object[] newArray = (Object[]) resolvedNewArray(dim0, arrayType);
    RVMArray innerArrayType = arrayType.getElementType().asArray();
    if (!innerArrayType.isInstantiated()) {
        innerArrayType.resolve();
        innerArrayType.instantiate();
    }
    for (int i = 0; i < dim0; i++) {
        newArray[i] = resolvedNewArray(dim1, innerArrayType);
    }
    return newArray;
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) RVMArray(org.jikesrvm.classloader.RVMArray) Entrypoint(org.vmmagic.pragma.Entrypoint)

Example 13 with RVMArray

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

the class MultianewarrayHelper method newArrayArray.

/**
 * Allocate something like {@code new Foo[cnt0][cnt1]...[cntN-1]},
 *                      or {@code new int[cnt0][cnt1]...[cntN-1]}.
 * @param methodId      id of caller
 * @param numDimensions number of array dimensions
 * @param typeId        {@link TypeReference} id of type of array
 * @param argOffset     position of word *above* `cnt0' argument within caller's frame
 *                      This is used to access the number of elements to
 *                      be allocated for each dimension.
 * See also: bytecode 0xc5 ("multianewarray") in Compiler
 * @return the new array
 */
@Entrypoint
static Object newArrayArray(int methodId, int numDimensions, int typeId, int argOffset) throws NoClassDefFoundError, NegativeArraySizeException, OutOfMemoryError {
    if (numDimensions == 2) {
        int dim0, dim1;
        // fetch number of elements to be allocated for each array dimension
        VM.disableGC();
        Address argp = Magic.getFramePointer().loadAddress().plus(argOffset);
        int offset = (BYTES_IN_STACKSLOT * 0) + BYTES_IN_INT;
        dim0 = argp.minus(offset).loadInt();
        offset = (BYTES_IN_STACKSLOT * 1) + BYTES_IN_INT;
        dim1 = argp.minus(offset).loadInt();
        VM.enableGC();
        // validate arguments
        if ((dim0 < 0) || (dim1 < 0))
            throw new NegativeArraySizeException();
        // create array
        TypeReference tRef = TypeReference.getTypeRef(typeId);
        RVMArray array = tRef.resolve().asArray();
        return RuntimeEntrypoints.buildTwoDimensionalArray(methodId, dim0, dim1, array);
    } else {
        // fetch number of elements to be allocated for each array dimension
        int[] numElements = new int[numDimensions];
        VM.disableGC();
        Address argp = Magic.getFramePointer().loadAddress().plus(argOffset);
        for (int i = 0; i < numDimensions; ++i) {
            int offset = (BYTES_IN_STACKSLOT * i) + BYTES_IN_INT;
            numElements[i] = argp.minus(offset).loadInt();
        }
        VM.enableGC();
        // validate arguments
        for (int elements : numElements) {
            if (elements < 0)
                throw new NegativeArraySizeException();
        }
        // create array
        TypeReference tRef = TypeReference.getTypeRef(typeId);
        RVMArray array = tRef.resolve().asArray();
        return RuntimeEntrypoints.buildMultiDimensionalArray(methodId, numElements, array);
    }
}
Also used : Address(org.vmmagic.unboxed.Address) RVMArray(org.jikesrvm.classloader.RVMArray) TypeReference(org.jikesrvm.classloader.TypeReference) Entrypoint(org.vmmagic.pragma.Entrypoint) Entrypoint(org.vmmagic.pragma.Entrypoint)

Example 14 with RVMArray

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

the class ObjectModel method copyTo.

/**
 * @param region The start (or an address less than) the region that was reserved for this object.
 */
@Override
@Inline
public Address copyTo(ObjectReference from, ObjectReference to, Address region) {
    TIB tib = org.jikesrvm.objectmodel.ObjectModel.getTIB(from);
    RVMType type = tib.getType();
    int bytes;
    boolean copy = (from != to);
    if (copy) {
        if (type.isClassType()) {
            RVMClass classType = type.asClass();
            bytes = org.jikesrvm.objectmodel.ObjectModel.bytesRequiredWhenCopied(from.toObject(), classType);
            org.jikesrvm.objectmodel.ObjectModel.moveObject(from.toObject(), to.toObject(), bytes, classType);
        } else {
            RVMArray arrayType = type.asArray();
            int elements = Magic.getArrayLength(from.toObject());
            bytes = org.jikesrvm.objectmodel.ObjectModel.bytesRequiredWhenCopied(from.toObject(), arrayType, elements);
            org.jikesrvm.objectmodel.ObjectModel.moveObject(from.toObject(), to.toObject(), bytes, arrayType);
        }
    } else {
        bytes = getCurrentSize(to);
    }
    Address start = org.jikesrvm.objectmodel.ObjectModel.objectStartRef(to);
    Allocator.fillAlignmentGap(region, start);
    return start.plus(bytes);
}
Also used : Address(org.vmmagic.unboxed.Address) RVMArray(org.jikesrvm.classloader.RVMArray) RVMType(org.jikesrvm.classloader.RVMType) TIB(org.jikesrvm.objectmodel.TIB) RVMClass(org.jikesrvm.classloader.RVMClass) Inline(org.vmmagic.pragma.Inline)

Example 15 with RVMArray

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

the class BootImageWriter method copyToBootImage.

/**
 * Copy an object (and, recursively, any of its fields or elements that
 * are references) from host jdk address space into image.
 *
 * @param jdkObject object to be copied
 * @param allocOnly if allocOnly is true, the TIB and other reference fields are not recursively copied
 * @param overwriteAddress if !overwriteAddress.isMax(), then copy object to given address
 * @param parentObject
 * @param untraced Do not report any fields of this object as references
 * @param alignCode Alignment-encoded value (TIB allocation only)
 * @return offset of copied object within image, in bytes
 *         (OBJECT_NOT_PRESENT --> object not copied:
 *            it's not part of bootimage)
 */
private static Address copyToBootImage(Object jdkObject, boolean allocOnly, Address overwriteAddress, Object parentObject, boolean untraced, int alignCode) throws IllegalAccessException {
    try {
        // Return object if it is already copied and not being overwritten
        BootImageMap.Entry mapEntry = BootImageMap.findOrCreateEntry(jdkObject);
        if ((!mapEntry.imageAddress.EQ(OBJECT_NOT_ALLOCATED)) && overwriteAddress.isMax()) {
            return mapEntry.imageAddress;
        }
        if (verbosity.isAtLeast(DETAILED))
            depth++;
        // fetch object's type information
        Class<?> jdkType = jdkObject.getClass();
        RVMType rvmType = getRvmType(jdkType);
        if (rvmType == null) {
            if (verbosity.isAtLeast(DETAILED))
                traverseObject(jdkObject);
            if (verbosity.isAtLeast(DETAILED))
                depth--;
            // object not part of bootimage
            return OBJECT_NOT_PRESENT;
        }
        // copy object to image
        if (jdkType.isArray()) {
            // allocate space in image prior to recursing
            int arrayCount = Array.getLength(jdkObject);
            RVMArray rvmArrayType = rvmType.asArray();
            boolean needsIdentityHash = mapEntry.requiresIdentityHashCode();
            int identityHashValue = mapEntry.getIdentityHashCode();
            Address arrayImageAddress = (overwriteAddress.isMax()) ? bootImage.allocateArray(rvmArrayType, arrayCount, needsIdentityHash, identityHashValue, alignCode) : overwriteAddress;
            mapEntry.imageAddress = arrayImageAddress;
            mapEntry.imageAddress = copyArrayToBootImage(arrayCount, arrayImageAddress, jdkObject, jdkType, rvmArrayType, allocOnly, overwriteAddress, parentObject, untraced);
            // already
            if (!allocOnly) {
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.push("", jdkObject.getClass().getName(), "tib");
                Address tibImageAddress = copyToBootImage(rvmType.getTypeInformationBlock(), allocOnly, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.pop();
                if (tibImageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
                    fail("can't copy tib for " + jdkObject);
                }
                ObjectModel.setTIB(bootImage, mapEntry.imageAddress, tibImageAddress, rvmType);
            }
        } else if (jdkObject instanceof TIB) {
            Object backing = ((RuntimeTable<?>) jdkObject).getBacking();
            int alignCodeValue = ((TIB) jdkObject).getAlignData();
            if (verbosity.isAtLeast(DETAILED))
                say("Encoding value " + alignCodeValue + " into tib");
            /* Copy the backing array, and then replace its TIB */
            mapEntry.imageAddress = copyToBootImage(backing, allocOnly, overwriteAddress, jdkObject, rvmType.getTypeRef().isRuntimeTable(), alignCodeValue);
            if (verbosity.isAtLeast(DETAILED))
                say(String.format("TIB address = %x, encoded value = %d, requested = %d%n", mapEntry.imageAddress.toInt(), AlignmentEncoding.extractTibCode(mapEntry.imageAddress), alignCodeValue));
            if (!allocOnly) {
                copyTIBToBootImage(rvmType, jdkObject, mapEntry.imageAddress);
            }
        } else if (rvmType == RVMType.ObjectReferenceArrayType || rvmType.getTypeRef().isRuntimeTable()) {
            Object backing = ((RuntimeTable<?>) jdkObject).getBacking();
            /* Copy the backing array, and then replace its TIB */
            mapEntry.imageAddress = copyToBootImage(backing, allocOnly, overwriteAddress, jdkObject, rvmType.getTypeRef().isRuntimeTable(), AlignmentEncoding.ALIGN_CODE_NONE);
            if (!allocOnly) {
                copyTIBToBootImage(rvmType, jdkObject, mapEntry.imageAddress);
            }
        } else if (jdkObject instanceof RuntimeTable) {
            Object backing = ((RuntimeTable<?>) jdkObject).getBacking();
            mapEntry.imageAddress = copyMagicArrayToBootImage(backing, rvmType.asArray(), allocOnly, overwriteAddress, parentObject);
        } else if (rvmType == RVMType.CodeArrayType) {
            // Handle the code array that is represented as either byte or int arrays
            if (verbosity.isAtLeast(DETAILED))
                depth--;
            Object backing = ((CodeArray) jdkObject).getBacking();
            return copyMagicArrayToBootImage(backing, rvmType.asArray(), allocOnly, overwriteAddress, parentObject);
        } else if (rvmType.getTypeRef().isMagicType()) {
            say("Unhandled copying of magic type: " + rvmType.getDescriptor().toString() + " in object of type " + parentObject.getClass().toString());
            fail("incomplete boot image support");
        } else {
            // allocate space in image
            if (rvmType instanceof RVMArray)
                fail("This isn't a scalar " + rvmType);
            RVMClass rvmScalarType = rvmType.asClass();
            boolean needsIdentityHash = mapEntry.requiresIdentityHashCode();
            int identityHashValue = mapEntry.getIdentityHashCode();
            Address scalarImageAddress = (overwriteAddress.isMax()) ? bootImage.allocateScalar(rvmScalarType, needsIdentityHash, identityHashValue) : overwriteAddress;
            mapEntry.imageAddress = scalarImageAddress;
            mapEntry.imageAddress = copyClassToBootImage(scalarImageAddress, jdkObject, jdkType, rvmScalarType, allocOnly, overwriteAddress, parentObject, untraced);
            // already
            if (!allocOnly) {
                copyTIBToBootImage(rvmType, jdkObject, mapEntry.imageAddress);
            }
        }
        if (verbosity.isAtLeast(DETAILED))
            depth--;
        return mapEntry.imageAddress;
    } catch (Error e) {
        e = new Error(e.getMessage() + "\nwhile copying " + jdkObject + (jdkObject != null ? ":" + jdkObject.getClass() : "") + " from " + parentObject + (parentObject != null ? ":" + parentObject.getClass() : ""), e.getCause() != null ? e.getCause() : e);
        throw e;
    }
}
Also used : Address(org.vmmagic.unboxed.Address) RVMType(org.jikesrvm.classloader.RVMType) TIB(org.jikesrvm.objectmodel.TIB) RVMClass(org.jikesrvm.classloader.RVMClass) RuntimeTable(org.jikesrvm.objectmodel.RuntimeTable) CodeArray(org.jikesrvm.compilers.common.CodeArray) RVMArray(org.jikesrvm.classloader.RVMArray)

Aggregations

RVMArray (org.jikesrvm.classloader.RVMArray)32 TIB (org.jikesrvm.objectmodel.TIB)14 Entrypoint (org.vmmagic.pragma.Entrypoint)14 RVMType (org.jikesrvm.classloader.RVMType)11 RVMClass (org.jikesrvm.classloader.RVMClass)9 NoInline (org.vmmagic.pragma.NoInline)8 TypeReference (org.jikesrvm.classloader.TypeReference)7 Interruptible (org.vmmagic.pragma.Interruptible)7 RVMMethod (org.jikesrvm.classloader.RVMMethod)6 Address (org.vmmagic.unboxed.Address)6 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)4 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)4 Test (org.junit.Test)4 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)3 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)3 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)3 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)3 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)3 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)3 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)3