Search in sources :

Example 36 with RVMType

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

the class ClassLoader method defineClass0.

/**
 * Loads new type into the classloader name space.
 * The class loader is marked as defining class loader.
 */
private Class<?> defineClass0(String name, byte[] data, int offset, int len) throws ClassFormatError {
    RVMType vmType = RVMClassLoader.defineClassInternal(name, data, offset, len, this);
    Class<?> ans = vmType.getClassForType();
    loadedClasses.put(name, ans);
    return ans;
}
Also used : RVMType(org.jikesrvm.classloader.RVMType)

Example 37 with RVMType

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

the class BootImageWriter method copyMagicArrayToBootImage.

/**
 * Copy a unboxed array type to the boot image
 * @param jdkObject object representation
 * @param rvmArrayType type of array
 * @param allocOnly allocate object don't write to fields
 * @param overwriteAddress addresss to write to if overwriting
 * @param parentObject object containing array
 * @return address of array
 * @throws IllegalAccessException
 */
private static Address copyMagicArrayToBootImage(Object jdkObject, RVMArray rvmArrayType, boolean allocOnly, Address overwriteAddress, Object parentObject) throws IllegalAccessException {
    // 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++;
    RVMType rvmElementType = rvmArrayType.getElementType();
    // allocate space in image
    int arrayCount = Array.getLength(jdkObject);
    Address arrayImageAddress;
    if (overwriteAddress.isMax()) {
        if (rvmElementType.equals(RVMType.CodeType)) {
            arrayImageAddress = bootImage.allocateCode(rvmArrayType, arrayCount);
        } else {
            boolean needsIdentityHash = mapEntry.requiresIdentityHashCode();
            int identityHashValue = mapEntry.getIdentityHashCode();
            arrayImageAddress = bootImage.allocateArray(rvmArrayType, arrayCount, needsIdentityHash, identityHashValue, AlignmentEncoding.ALIGN_CODE_NONE);
        }
    } else {
        arrayImageAddress = overwriteAddress;
    }
    mapEntry.imageAddress = arrayImageAddress;
    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  ", rvmArrayType.toString(), "   length=", String.valueOf(arrayCount), (arraySize >= LARGE_ARRAY_SIZE) ? " large object!!!" : "");
        }
    }
    // copy array elements from host jdk address space into image
    if (rvmElementType.equals(RVMType.CodeType)) {
        if (VM.BuildForIA32) {
            byte[] values = (byte[]) jdkObject;
            for (int i = 0; i < arrayCount; ++i) bootImage.setByte(arrayImageAddress.plus(i), values[i]);
        } else {
            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.AddressType)) {
        Address[] values = (Address[]) jdkObject;
        for (int i = 0; i < arrayCount; i++) {
            Address addr = values[i];
            String msg = "Address array element";
            bootImage.setAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), getWordValue(addr, msg, true), false, false);
        }
    } else if (rvmElementType.equals(RVMType.WordType)) {
        Word[] values = (Word[]) jdkObject;
        for (int i = 0; i < arrayCount; i++) {
            String msg = "Word array element ";
            Word addr = values[i];
            bootImage.setAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), getWordValue(addr, msg, false), false, false);
        }
    } else if (rvmElementType.equals(RVMType.OffsetType)) {
        Offset[] values = (Offset[]) jdkObject;
        for (int i = 0; i < arrayCount; i++) {
            String msg = "Offset array element " + i;
            Offset addr = values[i];
            bootImage.setAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), getWordValue(addr, msg, false), false, false);
        }
    } else if (rvmElementType.equals(RVMType.ExtentType)) {
        Extent[] values = (Extent[]) jdkObject;
        for (int i = 0; i < arrayCount; i++) {
            String msg = "Extent array element ";
            Extent addr = values[i];
            bootImage.setAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), getWordValue(addr, msg, false), false, false);
        }
    } else {
        fail("unexpected magic array type: " + rvmArrayType);
    }
    // copy object's TIB into image, if it's not there already
    if (!allocOnly) {
        copyTIBToBootImage(rvmArrayType, jdkObject, mapEntry.imageAddress);
    }
    if (verbosity.isAtLeast(DETAILED))
        depth--;
    return mapEntry.imageAddress;
}
Also used : Word(org.vmmagic.unboxed.Word) Address(org.vmmagic.unboxed.Address) Extent(org.vmmagic.unboxed.Extent) RVMType(org.jikesrvm.classloader.RVMType) Offset(org.vmmagic.unboxed.Offset)

Example 38 with RVMType

use of org.jikesrvm.classloader.RVMType 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 39 with RVMType

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

the class BootImageWriter method copyKnownInstanceField.

/**
 * If we can't find a field via reflection we may still determine
 * and copy a value because we know the internals of Classpath.
 * @param jdkObject the object containing the field
 * @param rvmFieldName the name of the field
 * @param rvmFieldType the type reference of the field
 * @param rvmFieldAddress the address that the field is being written to
 */
private static boolean copyKnownInstanceField(Object jdkObject, String rvmFieldName, TypeReference rvmFieldType, Address rvmFieldAddress) throws IllegalAccessException {
    // Class library independent objects
    if (jdkObject instanceof java.lang.Class) {
        Object value = null;
        String fieldName = null;
        boolean fieldIsFinal = false;
        if (rvmFieldName.equals("type")) {
            // lets go over the common ones
            if (jdkObject == java.lang.Boolean.TYPE) {
                value = RVMType.BooleanType;
            } else if (jdkObject == java.lang.Byte.TYPE) {
                value = RVMType.ByteType;
            } else if (jdkObject == java.lang.Character.TYPE) {
                value = RVMType.CharType;
            } else if (jdkObject == java.lang.Double.TYPE) {
                value = RVMType.DoubleType;
            } else if (jdkObject == java.lang.Float.TYPE) {
                value = RVMType.FloatType;
            } else if (jdkObject == java.lang.Integer.TYPE) {
                value = RVMType.IntType;
            } else if (jdkObject == java.lang.Long.TYPE) {
                value = RVMType.LongType;
            } else if (jdkObject == java.lang.Short.TYPE) {
                value = RVMType.ShortType;
            } else if (jdkObject == java.lang.Void.TYPE) {
                value = RVMType.VoidType;
            } else {
                value = TypeReference.findOrCreate((Class<?>) jdkObject).peekType();
                if (value == null) {
                    fail("Failed to populate Class.type for " + jdkObject);
                }
            }
            fieldName = "type";
            fieldIsFinal = true;
        }
        if ((fieldName != null) && (value != null)) {
            if (verbosity.isAtLeast(DETAILED))
                traceContext.push(value.getClass().getName(), "java.lang.Class", fieldName);
            Address imageAddress = BootImageMap.findOrCreateEntry(value).imageAddress;
            if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
                // object not part of bootimage: install null reference
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.traceObjectNotInBootImage();
                bootImage.setNullAddressWord(rvmFieldAddress, true, true, false);
            } else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
                imageAddress = copyToBootImage(value, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
                if (verbosity.isAtLeast(ADDRESSES))
                    traceContext.traceObjectFoundThroughKnown();
                bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, !fieldIsFinal);
            } else {
                if (verbosity.isAtLeast(ADDRESSES))
                    traceContext.traceObjectFoundThroughKnown();
                bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, !fieldIsFinal);
            }
            if (verbosity.isAtLeast(DETAILED))
                traceContext.pop();
            return true;
        } else {
            // Unknown Class field or value for type
            return false;
        }
    } else if ((jdkObject instanceof java.lang.String) && (rvmFieldName.equals("count")) && (rvmFieldType.isIntType())) {
        // The fields "count" and "offset" are not guaranteed to be present in
        // the String implementation in the class library (case in point: IcedTea 7).
        // We don't need to do anything for "offset" (the default value of 0 is correct)
        // but we need to ensure that "count" has the correct value.
        bootImage.setFullWord(rvmFieldAddress, ((java.lang.String) jdkObject).length());
        return true;
    }
    // Class library dependent fields
    if (classLibrary == "harmony") {
        if ((jdkObject instanceof java.lang.String) && (rvmFieldName.equals("hashCode")) && (rvmFieldType.isIntType())) {
            // Populate String's hashCode value
            bootImage.setFullWord(rvmFieldAddress, jdkObject.hashCode());
            return true;
        } else if (jdkObject instanceof java.util.Locale) {
            String fieldName;
            Object value;
            if (rvmFieldName.equals("countryCode")) {
                value = ((java.util.Locale) jdkObject).getCountry();
                fieldName = "countryCode";
            } else if (rvmFieldName.equals("languageCode")) {
                value = ((java.util.Locale) jdkObject).getLanguage();
                fieldName = "languageCode";
            } else if (rvmFieldName.equals("variantCode")) {
                value = ((java.util.Locale) jdkObject).getVariant();
                fieldName = "languageCode";
            } else {
                return false;
            }
            if (verbosity.isAtLeast(DETAILED))
                traceContext.push(value.getClass().getName(), "java.util.Locale", fieldName);
            Address imageAddress = BootImageMap.findOrCreateEntry(value).imageAddress;
            if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
                // object not part of bootimage: install null reference
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.traceObjectNotInBootImage();
                throw new Error("Failed to populate " + fieldName + " in Locale");
            } else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
                imageAddress = copyToBootImage(value, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
                if (verbosity.isAtLeast(ADDRESSES))
                    traceContext.traceObjectFoundThroughKnown();
                bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
            } else {
                if (verbosity.isAtLeast(ADDRESSES))
                    traceContext.traceObjectFoundThroughKnown();
                bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
            }
            if (verbosity.isAtLeast(DETAILED))
                traceContext.pop();
            return true;
        } else if ((jdkObject instanceof java.util.WeakHashMap) && (rvmFieldName.equals("referenceQueue"))) {
            Object value = new java.lang.ref.ReferenceQueue();
            if (verbosity.isAtLeast(DETAILED))
                traceContext.push(value.getClass().getName(), "java.util.WeakHashMap", "referenceQueue");
            Address imageAddress = BootImageMap.findOrCreateEntry(value).imageAddress;
            if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
                // object not part of bootimage: install null reference
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.traceObjectNotInBootImage();
                throw new Error("Failed to populate referenceQueue in WeakHashMap");
            } else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
                imageAddress = copyToBootImage(value, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
                if (verbosity.isAtLeast(ADDRESSES))
                    traceContext.traceObjectFoundThroughKnown();
                bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
            } else {
                if (verbosity.isAtLeast(ADDRESSES))
                    traceContext.traceObjectFoundThroughKnown();
                bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
            }
            if (verbosity.isAtLeast(DETAILED))
                traceContext.pop();
            return true;
        } else if (jdkObject instanceof java.lang.ref.ReferenceQueue) {
            if (rvmFieldName.equals("firstReference")) {
                return false;
            } else {
                throw new Error("Unknown field " + rvmFieldName + " in java.lang.ref.ReferenceQueue");
            }
        } else if (jdkObject instanceof java.lang.reflect.Constructor) {
            Constructor<?> cons = (Constructor<?>) jdkObject;
            if (rvmFieldName.equals("vmConstructor")) {
                // fill in this RVMMethod field
                String typeName = "L" + cons.getDeclaringClass().getName().replace('.', '/') + ";";
                RVMType type = TypeReference.findOrCreate(typeName).peekType();
                if (type == null) {
                    throw new Error("Failed to find type for Constructor.constructor: " + cons + " " + typeName);
                }
                final RVMClass klass = type.asClass();
                Class<?>[] consParams = cons.getParameterTypes();
                RVMMethod constructor = null;
                loop_over_all_constructors: for (RVMMethod vmCons : klass.getConstructorMethods()) {
                    TypeReference[] vmConsParams = vmCons.getParameterTypes();
                    if (vmConsParams.length == consParams.length) {
                        for (int j = 0; j < vmConsParams.length; j++) {
                            if (!consParams[j].equals(vmConsParams[j].resolve().getClassForType())) {
                                continue loop_over_all_constructors;
                            }
                        }
                        constructor = vmCons;
                        break;
                    }
                }
                if (constructor == null) {
                    throw new Error("Failed to populate Constructor.cons for " + cons);
                }
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.push("vmConstructor", "java.lang.Constructor", "cons");
                Address imageAddress = BootImageMap.findOrCreateEntry(constructor).imageAddress;
                if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
                    // object not part of bootimage: install null reference
                    if (verbosity.isAtLeast(DETAILED))
                        traceContext.traceObjectNotInBootImage();
                    bootImage.setNullAddressWord(rvmFieldAddress, true, false, false);
                } else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
                    imageAddress = copyToBootImage(constructor, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
                    if (verbosity.isAtLeast(ADDRESSES))
                        traceContext.traceObjectFoundThroughKnown();
                    bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
                } else {
                    if (verbosity.isAtLeast(ADDRESSES))
                        traceContext.traceObjectFoundThroughKnown();
                    bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
                }
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.pop();
                return true;
            } else if (rvmFieldName.equals("isAccessible")) {
                // This field is inherited accesible flag is actually part of
                // AccessibleObject
                bootImage.setByte(rvmFieldAddress, cons.isAccessible() ? 1 : 0);
                return true;
            } else if (rvmFieldName.equals("invoker")) {
                // Bytecode reflection field, can only be installed in running VM
                bootImage.setNullAddressWord(rvmFieldAddress, true, false, false);
                return true;
            } else {
                // Unknown Constructor field
                throw new Error("Unknown field " + rvmFieldName + " in java.lang.reflect.Constructor");
            }
        } else {
            // unknown field
            return false;
        }
    } else if (classLibrary == "classpath") {
        if ((jdkObject instanceof java.lang.String) && (rvmFieldName.equals("cachedHashCode")) && (rvmFieldType.isIntType())) {
            // Populate String's cachedHashCode value
            bootImage.setFullWord(rvmFieldAddress, jdkObject.hashCode());
            return true;
        } else if (jdkObject instanceof java.lang.reflect.Constructor) {
            Constructor<?> cons = (Constructor<?>) jdkObject;
            if (rvmFieldName.equals("cons")) {
                // fill in this RVMMethod field
                String typeName = "L" + cons.getDeclaringClass().getName().replace('.', '/') + ";";
                RVMType type = TypeReference.findOrCreate(typeName).peekType();
                if (type == null) {
                    throw new Error("Failed to find type for Constructor.constructor: " + cons + " " + typeName);
                }
                final RVMClass klass = type.asClass();
                Class<?>[] consParams = cons.getParameterTypes();
                RVMMethod constructor = null;
                loop_over_all_constructors: for (RVMMethod vmCons : klass.getConstructorMethods()) {
                    TypeReference[] vmConsParams = vmCons.getParameterTypes();
                    if (vmConsParams.length == consParams.length) {
                        for (int j = 0; j < vmConsParams.length; j++) {
                            if (!consParams[j].equals(vmConsParams[j].resolve().getClassForType())) {
                                continue loop_over_all_constructors;
                            }
                        }
                        constructor = vmCons;
                        break;
                    }
                }
                if (constructor == null) {
                    throw new Error("Failed to populate Constructor.cons for " + cons);
                }
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.push("VMConstructor", "java.lang.Constructor", "cons");
                Object vmcons = java.lang.reflect.JikesRVMSupport.createVMConstructor(constructor);
                Address imageAddress = BootImageMap.findOrCreateEntry(vmcons).imageAddress;
                if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
                    // object not part of bootimage: install null reference
                    if (verbosity.isAtLeast(DETAILED))
                        traceContext.traceObjectNotInBootImage();
                    bootImage.setNullAddressWord(rvmFieldAddress, true, false, false);
                } else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
                    imageAddress = copyToBootImage(vmcons, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
                    if (verbosity.isAtLeast(ADDRESSES))
                        traceContext.traceObjectFoundThroughKnown();
                    bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
                } else {
                    if (verbosity.isAtLeast(ADDRESSES))
                        traceContext.traceObjectFoundThroughKnown();
                    bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
                }
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.pop();
                return true;
            } else if (rvmFieldName.equals("flag")) {
                // This field is inherited accesible flag is actually part of
                // AccessibleObject
                bootImage.setByte(rvmFieldAddress, cons.isAccessible() ? 1 : 0);
                return true;
            } else {
                // Unknown Constructor field
                return false;
            }
        } else if (jdkObject instanceof java.lang.ref.ReferenceQueue) {
            if (rvmFieldName.equals("lock")) {
                VM.sysWriteln("writing the lock field.");
                Object value = new org.jikesrvm.scheduler.LightMonitor();
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.push(value.getClass().getName(), "java.lang.ref.ReferenceQueue", "lock");
                Address imageAddress = BootImageMap.findOrCreateEntry(value).imageAddress;
                if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
                    if (verbosity.isAtLeast(DETAILED))
                        traceContext.traceObjectNotInBootImage();
                    throw new Error("Failed to populate lock in ReferenceQueue");
                } else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
                    imageAddress = copyToBootImage(value, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
                    if (verbosity.isAtLeast(ADDRESSES))
                        traceContext.traceObjectFoundThroughKnown();
                    bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
                } else {
                    if (verbosity.isAtLeast(ADDRESSES))
                        traceContext.traceObjectFoundThroughKnown();
                    bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
                }
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.pop();
                return true;
            } else if (rvmFieldName.equals("first")) {
                return false;
            } else {
                throw new Error("Unknown field " + rvmFieldName + " in java.lang.ref.ReferenceQueue");
            }
        } else if (jdkObject instanceof java.util.BitSet) {
            BitSet bs = (BitSet) jdkObject;
            if (rvmFieldName.equals("bits")) {
                // highest bit set in set
                int max = 0;
                for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
                    max = i;
                }
                long[] bits = new long[(max + 63) / 64];
                for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
                    bits[i / 64] |= 1L << (i & 63);
                }
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.push("[J", "java.util.BitSet", "bits");
                Address imageAddress = BootImageMap.findOrCreateEntry(bits).imageAddress;
                if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
                    // object not part of bootimage: install null reference
                    if (verbosity.isAtLeast(DETAILED))
                        traceContext.traceObjectNotInBootImage();
                    bootImage.setNullAddressWord(rvmFieldAddress, true, false);
                } else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
                    imageAddress = copyToBootImage(bits, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
                    if (verbosity.isAtLeast(ADDRESSES))
                        traceContext.traceObjectFoundThroughKnown();
                    bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), false, false);
                } else {
                    if (verbosity.isAtLeast(ADDRESSES))
                        traceContext.traceObjectFoundThroughKnown();
                    bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), false, false);
                }
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.pop();
                return true;
            } else {
                // Unknown BitSet field
                return false;
            }
        } else {
            // Unknown field
            return false;
        }
    } else {
        throw new Error("Unknown class library: \"" + classLibrary + "\"");
    }
}
Also used : Address(org.vmmagic.unboxed.Address) RVMType(org.jikesrvm.classloader.RVMType) Constructor(java.lang.reflect.Constructor) BitSet(java.util.BitSet) RVMClass(org.jikesrvm.classloader.RVMClass) RVMMethod(org.jikesrvm.classloader.RVMMethod) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 40 with RVMType

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

Aggregations

RVMType (org.jikesrvm.classloader.RVMType)77 RVMClass (org.jikesrvm.classloader.RVMClass)23 TypeReference (org.jikesrvm.classloader.TypeReference)18 Address (org.vmmagic.unboxed.Address)16 RVMMethod (org.jikesrvm.classloader.RVMMethod)15 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)15 TIB (org.jikesrvm.objectmodel.TIB)13 Entrypoint (org.vmmagic.pragma.Entrypoint)13 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)12 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)12 RVMArray (org.jikesrvm.classloader.RVMArray)11 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)11 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)11 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)10 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)10 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)10 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)10 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)9 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)9 Offset (org.vmmagic.unboxed.Offset)8