Search in sources :

Example 16 with TIB

use of org.jikesrvm.objectmodel.TIB in project JikesRVM by JikesRVM.

the class Barriers method initializeObjectReferenceFields.

/**
 * Initializes the reference fields of a given object reference. Most collectors
 * won't need to use this method.
 * <p>
 * The Poisoned collector uses this method. Without using this method,
 * all reference fields would be initialized to {@code Word.zero()}. However,
 * the value for {@code null} in the Poisoned collector is actually
 * {@code Poisoned.poison(ObjectReference.fromObject(null))}, which is
 * {@code Word.one()} at the time of this writing. Not initializing the value
 * to the real value of {@code null} leads to problems when the value isn't
 * explicitly initialized before it is read (i.e. when the programmer relies
 * on the JVM to initialize the value to {@code null}). This can occur when
 * using intrinsics such as compare-and-swap.
 *
 * @param ref the object that has the reference field(s)
 * @param tibAddr the object's type TIB
 */
@Override
public final void initializeObjectReferenceFields(ObjectReference ref, ObjectReference tibAddr) {
    ObjectReference nullValue = Word.zero().toAddress().toObjectReference();
    // location is actually unknown. I suppose we could try mapping the
    // reference offsets to field offsets if we really needed it.
    Word location = Word.zero();
    TIB tib = Magic.addressAsTIB(tibAddr.toAddress());
    RVMType type = tib.getType();
    int[] referenceOffsets = type.getReferenceOffsets();
    if (referenceOffsets == RVMType.REFARRAY_OFFSET_ARRAY) {
        if (VM.VERIFY_ASSERTIONS)
            VM.assertions._assert(type.isArrayType() && type.asArray().getElementType().isReferenceType());
        int arrayLength = ObjectModel.getArrayLength(ref.toObject());
        for (int i = 0; i < arrayLength; i++) {
            Word offset = Offset.fromIntSignExtend(i << LOG_BYTES_IN_ADDRESS).toWord();
            Address slotAddress = ref.toAddress().plus(i << LOG_BYTES_IN_ADDRESS);
            VM.activePlan.mutator().objectReferenceWrite(ref, slotAddress, nullValue, offset, location, ARRAY_ELEMENT);
        }
    } else {
        if (VM.VERIFY_ASSERTIONS)
            VM.assertions._assert(type.isClassType() || (type.isArrayType() && !type.asArray().getElementType().isReferenceType()));
        for (int i = 0; i < referenceOffsets.length; i++) {
            Word offset = Offset.fromIntSignExtend(referenceOffsets[i]).toWord();
            Address slotAddress = ref.toAddress().plus(referenceOffsets[i]);
            VM.activePlan.mutator().objectReferenceWrite(ref, slotAddress, nullValue, offset, location, INSTANCE_FIELD);
        }
    }
}
Also used : RVMType(org.jikesrvm.classloader.RVMType) TIB(org.jikesrvm.objectmodel.TIB)

Example 17 with TIB

use of org.jikesrvm.objectmodel.TIB 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)

Example 18 with TIB

use of org.jikesrvm.objectmodel.TIB in project JikesRVM by JikesRVM.

the class BootImageWriter method copyArrayToBootImage.

/**
 * Write array to boot image
 * @param arrayCount
 * @param arrayImageAddress
 * @param jdkObject
 * @param jdkType
 * @param rvmArrayType
 * @param allocOnly
 * @param overwriteAddress
 * @param parentObject
 * @param untraced
 * @return
 * @throws IllegalAccessException
 */
private static Address copyArrayToBootImage(int arrayCount, Address arrayImageAddress, Object jdkObject, Class<?> jdkType, RVMArray rvmArrayType, boolean allocOnly, Address overwriteAddress, Object parentObject, boolean untraced) throws IllegalAccessException {
    if (verbosity.isAtLeast(DETAILED)) {
        if (depth == DEPTH_CUTOFF)
            say(SPACES.substring(0, depth + 1), "TOO DEEP: cutting off");
        else if (depth < DEPTH_CUTOFF) {
            String tab = SPACES.substring(0, depth + 1);
            if (depth == 0 && jtocCount >= 0)
                tab = tab + "jtoc #" + String.valueOf(jtocCount) + ": ";
            int arraySize = rvmArrayType.getInstanceSize(arrayCount);
            say(tab, "Copying array  ", jdkType.getName(), "   length=", String.valueOf(arrayCount), (arraySize >= LARGE_ARRAY_SIZE) ? " large object!!!" : "");
        }
    }
    RVMType rvmElementType = rvmArrayType.getElementType();
    // recurse on values that are references
    if (rvmElementType.isPrimitiveType()) {
        // array element is logical or numeric type
        if (rvmElementType.equals(RVMType.BooleanType)) {
            boolean[] values = (boolean[]) jdkObject;
            for (int i = 0; i < arrayCount; ++i) bootImage.setByte(arrayImageAddress.plus(i), values[i] ? 1 : 0);
        } else if (rvmElementType.equals(RVMType.ByteType)) {
            byte[] values = (byte[]) jdkObject;
            for (int i = 0; i < arrayCount; ++i) bootImage.setByte(arrayImageAddress.plus(i), values[i]);
        } else if (rvmElementType.equals(RVMType.CharType)) {
            char[] values = (char[]) jdkObject;
            for (int i = 0; i < arrayCount; ++i) bootImage.setHalfWord(arrayImageAddress.plus(i << LOG_BYTES_IN_CHAR), values[i]);
        } else if (rvmElementType.equals(RVMType.ShortType)) {
            short[] values = (short[]) jdkObject;
            for (int i = 0; i < arrayCount; ++i) bootImage.setHalfWord(arrayImageAddress.plus(i << LOG_BYTES_IN_SHORT), values[i]);
        } else if (rvmElementType.equals(RVMType.IntType)) {
            int[] values = (int[]) jdkObject;
            for (int i = 0; i < arrayCount; ++i) bootImage.setFullWord(arrayImageAddress.plus(i << LOG_BYTES_IN_INT), values[i]);
        } else if (rvmElementType.equals(RVMType.LongType)) {
            long[] values = (long[]) jdkObject;
            for (int i = 0; i < arrayCount; ++i) bootImage.setDoubleWord(arrayImageAddress.plus(i << LOG_BYTES_IN_LONG), values[i]);
        } else if (rvmElementType.equals(RVMType.FloatType)) {
            float[] values = (float[]) jdkObject;
            for (int i = 0; i < arrayCount; ++i) bootImage.setFullWord(arrayImageAddress.plus(i << LOG_BYTES_IN_FLOAT), Float.floatToIntBits(values[i]));
        } else if (rvmElementType.equals(RVMType.DoubleType)) {
            double[] values = (double[]) jdkObject;
            for (int i = 0; i < arrayCount; ++i) bootImage.setDoubleWord(arrayImageAddress.plus(i << LOG_BYTES_IN_DOUBLE), Double.doubleToLongBits(values[i]));
        } else {
            fail("unexpected primitive array type: " + rvmArrayType);
        }
    } else {
        // array element is reference type
        boolean isTIB = parentObject instanceof TIB;
        Object[] values = (Object[]) jdkObject;
        Class<?> jdkClass = jdkObject.getClass();
        if (!allocOnly) {
            for (int i = 0; i < arrayCount; ++i) {
                if (values[i] != null) {
                    if (verbosity.isAtLeast(DETAILED))
                        traceContext.push(values[i].getClass().getName(), jdkClass.getName(), i);
                    if (isTIB && values[i] instanceof Word) {
                        bootImage.setAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), (Word) values[i], false, false);
                    } else if (isTIB && values[i] == LazyCompilationTrampoline.getInstructions()) {
                        Address codeAddress = arrayImageAddress.plus(((TIB) parentObject).lazyMethodInvokerTrampolineIndex() << LOG_BYTES_IN_ADDRESS);
                        bootImage.setAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), codeAddress.toWord(), false, false);
                    } else {
                        copyReferenceFieldToBootImage(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), values[i], jdkObject, !untraced, !untraced, null, null);
                    }
                    if (verbosity.isAtLeast(DETAILED))
                        traceContext.pop();
                } else {
                    bootImage.setNullAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), !untraced, !untraced, true);
                }
            }
        }
    }
    return arrayImageAddress;
}
Also used : Word(org.vmmagic.unboxed.Word) Address(org.vmmagic.unboxed.Address) RVMType(org.jikesrvm.classloader.RVMType) TIB(org.jikesrvm.objectmodel.TIB)

Example 19 with TIB

use of org.jikesrvm.objectmodel.TIB in project JikesRVM by JikesRVM.

the class ObjectModel method getAlignWhenCopied.

@Override
public int getAlignWhenCopied(ObjectReference object) {
    TIB tib = org.jikesrvm.objectmodel.ObjectModel.getTIB(object);
    RVMType type = tib.getType();
    if (type.isArrayType()) {
        return org.jikesrvm.objectmodel.ObjectModel.getAlignment(type.asArray(), object.toObject());
    } else {
        return org.jikesrvm.objectmodel.ObjectModel.getAlignment(type.asClass(), object.toObject());
    }
}
Also used : RVMType(org.jikesrvm.classloader.RVMType) TIB(org.jikesrvm.objectmodel.TIB)

Example 20 with TIB

use of org.jikesrvm.objectmodel.TIB in project JikesRVM by JikesRVM.

the class ObjectModel method isAcyclic.

@Override
@Inline
public boolean isAcyclic(ObjectReference typeRef) {
    TIB tib = Magic.addressAsTIB(typeRef.toAddress());
    RVMType type = tib.getType();
    return type.isAcyclicReference();
}
Also used : RVMType(org.jikesrvm.classloader.RVMType) TIB(org.jikesrvm.objectmodel.TIB) Inline(org.vmmagic.pragma.Inline)

Aggregations

TIB (org.jikesrvm.objectmodel.TIB)36 Entrypoint (org.vmmagic.pragma.Entrypoint)16 RVMArray (org.jikesrvm.classloader.RVMArray)14 RVMType (org.jikesrvm.classloader.RVMType)13 NoInline (org.vmmagic.pragma.NoInline)9 Interruptible (org.vmmagic.pragma.Interruptible)8 Address (org.vmmagic.unboxed.Address)7 Test (org.junit.Test)5 CodeArray (org.jikesrvm.compilers.common.CodeArray)4 ITable (org.jikesrvm.objectmodel.ITable)4 RVMClass (org.jikesrvm.classloader.RVMClass)3 RVMMethod (org.jikesrvm.classloader.RVMMethod)3 Offset (org.vmmagic.unboxed.Offset)3 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)2 IMT (org.jikesrvm.objectmodel.IMT)2 ITableArray (org.jikesrvm.objectmodel.ITableArray)2 Inline (org.vmmagic.pragma.Inline)2 BufferedOutputStream (java.io.BufferedOutputStream)1 FileOutputStream (java.io.FileOutputStream)1 PrintStream (java.io.PrintStream)1