Search in sources :

Example 1 with HostedField

use of com.oracle.svm.hosted.meta.HostedField in project graal by oracle.

the class NativeImageHeap method writeObject.

private void writeObject(ObjectInfo info, final RelocatableBuffer roBuffer, final RelocatableBuffer rwBuffer) {
    /*
         * Write a reference from the object to its hub. This lives at layout.getHubOffset() from
         * the object base.
         */
    final RelocatableBuffer buffer = bufferForPartition(info, roBuffer, rwBuffer);
    final int indexInSection = info.getIntIndexInSection(layout.getHubOffset());
    assert layout.isReferenceAligned(info.getOffsetInPartition());
    assert layout.isReferenceAligned(indexInSection);
    final HostedClass clazz = info.getClazz();
    final DynamicHub hub = clazz.getHub();
    final long objectHeaderBits = Heap.getHeap().getObjectHeader().setBootImageOnLong(0L);
    writeDynamicHub(buffer, indexInSection, hub, objectHeaderBits);
    if (clazz.isInstanceClass()) {
        JavaConstant con = SubstrateObjectConstant.forObject(info.getObject());
        HybridLayout<?> hybridLayout = hybridLayouts.get(clazz);
        HostedField hybridArrayField = null;
        HostedField hybridBitsetField = null;
        int maxBitIndex = -1;
        Object hybridArray = null;
        if (hybridLayout != null) {
            hybridArrayField = hybridLayout.getArrayField();
            hybridArray = SubstrateObjectConstant.asObject(hybridArrayField.readStorageValue(con));
            hybridBitsetField = hybridLayout.getBitsetField();
            if (hybridBitsetField != null) {
                BitSet bitSet = (BitSet) SubstrateObjectConstant.asObject(hybridBitsetField.readStorageValue(con));
                if (bitSet != null) {
                    /*
                         * Write the bits of the hybrid bit field. The bits are located between the
                         * array length and the instance fields.
                         */
                    int bitsPerByte = Byte.SIZE;
                    for (int bit = bitSet.nextSetBit(0); bit >= 0; bit = bitSet.nextSetBit(bit + 1)) {
                        final int index = info.getIntIndexInSection(hybridLayout.getBitFieldOffset()) + bit / bitsPerByte;
                        if (index > maxBitIndex) {
                            maxBitIndex = index;
                        }
                        int mask = 1 << (bit % bitsPerByte);
                        assert mask < (1 << bitsPerByte);
                        buffer.putByte(index, (byte) (buffer.getByte(index) | mask));
                    }
                }
            }
        }
        /*
             * Write the regular instance fields.
             */
        for (HostedField field : clazz.getInstanceFields(true)) {
            if (!field.equals(hybridArrayField) && !field.equals(hybridBitsetField) && field.isAccessed()) {
                assert field.getLocation() >= 0;
                assert info.getIntIndexInSection(field.getLocation()) > maxBitIndex;
                writeField(buffer, info, field, con, info);
            }
        }
        if (hub.getHashCodeOffset() != 0) {
            buffer.putInt(info.getIntIndexInSection(hub.getHashCodeOffset()), info.getIdentityHashCode());
        }
        if (hybridArray != null) {
            /*
                 * Write the hybrid array length and the array elements.
                 */
            int length = Array.getLength(hybridArray);
            buffer.putInt(info.getIntIndexInSection(layout.getArrayLengthOffset()), length);
            for (int i = 0; i < length; i++) {
                final int elementIndex = info.getIntIndexInSection(hybridLayout.getArrayElementOffset(i));
                final JavaKind elementKind = hybridLayout.getArrayElementKind();
                final Object array = Array.get(hybridArray, i);
                writeConstant(buffer, elementIndex, elementKind, array, info);
            }
        }
    } else if (clazz.isArray()) {
        JavaKind kind = clazz.getComponentType().getJavaKind();
        Object array = info.getObject();
        int length = Array.getLength(array);
        buffer.putInt(info.getIntIndexInSection(layout.getArrayLengthOffset()), length);
        buffer.putInt(info.getIntIndexInSection(layout.getArrayHashCodeOffset()), info.getIdentityHashCode());
        if (array instanceof Object[]) {
            Object[] oarray = (Object[]) array;
            assert oarray.length == length;
            for (int i = 0; i < length; i++) {
                final int elementIndex = info.getIntIndexInSection(layout.getArrayElementOffset(kind, i));
                final Object element = aUniverse.replaceObject(oarray[i]);
                writeConstant(buffer, elementIndex, kind, element, info);
            }
        } else {
            for (int i = 0; i < length; i++) {
                final int elementIndex = info.getIntIndexInSection(layout.getArrayElementOffset(kind, i));
                final Object element = Array.get(array, i);
                writeConstant(buffer, elementIndex, kind, element, info);
            }
        }
    } else {
        throw shouldNotReachHere();
    }
}
Also used : HostedField(com.oracle.svm.hosted.meta.HostedField) DynamicHub(com.oracle.svm.core.hub.DynamicHub) BitSet(java.util.BitSet) JavaConstant(jdk.vm.ci.meta.JavaConstant) HostedClass(com.oracle.svm.hosted.meta.HostedClass) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 2 with HostedField

use of com.oracle.svm.hosted.meta.HostedField in project graal by oracle.

the class NativeImageHeap method addObjectToBootImageHeap.

/**
 * It has been determined that an object should be added to the model of the native image heap.
 * This is the mechanics of recursively adding the object and all its fields and array elements
 * to the model of the native image heap.
 */
private void addObjectToBootImageHeap(final Object original, final Object canonicalObj, final boolean canonicalizable, boolean immutableFromParent, final int identityHashCode, final Object reason) {
    final Optional<HostedType> optionalType = getMetaAccess().optionalLookupJavaType(canonicalObj.getClass());
    if (!optionalType.isPresent() || !optionalType.get().isInstantiated()) {
        throw UserError.abort("Image heap writing found an object whose class was not seen as instantiated during static analysis. " + "Did a static field or an object referenced from a static field changed during native image generation? " + "For example, a lazily initialized cache could have been initialized during image generation, " + "in which case you need to force eager initialization of the cache before static analysis or reset the cache using a field value recomputation.\n" + "  object: " + original + "  of class: " + original.getClass().getTypeName() + "\n" + "  reachable through:\n" + fillReasonStack(new StringBuilder(), reason));
    }
    final HostedType type = optionalType.get();
    if (type.isInstanceClass()) {
        final HostedInstanceClass clazz = (HostedInstanceClass) type;
        final JavaConstant con = SubstrateObjectConstant.forObject(canonicalObj);
        final Object hybridArray;
        final long size;
        if (HybridLayout.isHybrid(clazz)) {
            HybridLayout<?> hybridLayout = hybridLayouts.get(clazz);
            if (hybridLayout == null) {
                hybridLayout = new HybridLayout<>(clazz, layout);
                hybridLayouts.put(clazz, hybridLayout);
            }
            /*
                 * The hybrid array and bit set are written within the hybrid object. So they may
                 * not be written as separate objects. We use the blacklist to check that.
                 */
            HostedField bitsetField = hybridLayout.getBitsetField();
            if (bitsetField != null) {
                BitSet bitSet = (BitSet) SubstrateObjectConstant.asObject(bitsetField.readStorageValue(con));
                if (bitSet != null) {
                    blacklist.put(bitSet, Boolean.TRUE);
                }
            }
            hybridArray = SubstrateObjectConstant.asObject(hybridLayout.getArrayField().readStorageValue(con));
            blacklist.put(hybridArray, Boolean.TRUE);
            size = hybridLayout.getTotalSize(Array.getLength(hybridArray));
        } else {
            hybridArray = null;
            size = LayoutEncoding.getInstanceSize(clazz.getHub().getLayoutEncoding()).rawValue();
        }
        // All canonicalizable objects are immutable,
        // as are instances of known immutable classes.
        final ObjectInfo info = addToHeapPartition(original, canonicalObj, clazz, size, identityHashCode, canonicalizable, immutableFromParent, reason);
        recursiveAddObject(clazz.getHub(), canonicalizable, false, info);
        // Recursively add all the fields of the object.
        // Even if the parent is not canonicalizable, the fields may be canonicalizable.
        final boolean fieldsAreImmutable = canonicalObj instanceof String;
        for (HostedField field : clazz.getInstanceFields(true)) {
            if (field.getType().getStorageKind() == JavaKind.Object && !HybridLayout.isHybridField(field) && field.isAccessed()) {
                assert field.getLocation() >= 0;
                recursiveAddObject(SubstrateObjectConstant.asObject(field.readStorageValue(con)), canonicalizable, fieldsAreImmutable, info);
            }
        }
        if (hybridArray instanceof Object[]) {
            addArrayElements((Object[]) hybridArray, canonicalizable, info);
        }
    } else if (type.isArray()) {
        HostedArrayClass clazz = (HostedArrayClass) type;
        int length = Array.getLength(canonicalObj);
        JavaKind kind = type.getComponentType().getJavaKind();
        final long size = layout.getArraySize(kind, length);
        final ObjectInfo info = addToHeapPartition(original, canonicalObj, clazz, size, identityHashCode, canonicalizable, immutableFromParent, reason);
        recursiveAddObject(clazz.getHub(), canonicalizable, false, info);
        if (kind == JavaKind.Object) {
            addArrayElements((Object[]) canonicalObj, canonicalizable, info);
        }
    } else {
        throw shouldNotReachHere();
    }
}
Also used : HostedField(com.oracle.svm.hosted.meta.HostedField) BitSet(java.util.BitSet) JavaConstant(jdk.vm.ci.meta.JavaConstant) HostedInstanceClass(com.oracle.svm.hosted.meta.HostedInstanceClass) HostedType(com.oracle.svm.hosted.meta.HostedType) HostedArrayClass(com.oracle.svm.hosted.meta.HostedArrayClass) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 3 with HostedField

use of com.oracle.svm.hosted.meta.HostedField in project graal by oracle.

the class NativeImageHeap method addStaticFields.

private void addStaticFields(DebugContext debug) {
    addObject(debug, StaticFieldsSupport.getStaticObjectFields(), false, false, "staticObjectFields");
    addObject(debug, StaticFieldsSupport.getStaticPrimitiveFields(), false, false, "staticPrimitiveFields");
    /*
         * We only have empty holder arrays for the static fields, so we need to add static object
         * fields manually.
         */
    for (HostedField field : getUniverse().getFields()) {
        if (Modifier.isStatic(field.getModifiers()) && field.wrapped.isWritten() && field.wrapped.isAccessed() && field.getType().getStorageKind() == JavaKind.Object) {
            addObject(debug, SubstrateObjectConstant.asObject(field.readStorageValue(null)), false, false, field);
        }
    }
}
Also used : HostedField(com.oracle.svm.hosted.meta.HostedField)

Example 4 with HostedField

use of com.oracle.svm.hosted.meta.HostedField in project graal by oracle.

the class NativeImageHeap method patchBootImageInfoField.

private void patchBootImageInfoField(ObjectInfo info, String fieldName, RelocatableBuffer roBuffer, RelocatableBuffer rwBuffer) {
    try {
        ObjectInfo staticFieldsInfo = objects.get(StaticFieldsSupport.getStaticObjectFields());
        final HostedField field = getMetaAccess().lookupJavaField(NativeImageInfo.class.getDeclaredField(fieldName));
        final int index = staticFieldsInfo.getIntIndexInSection(field.getLocation());
        // Overwrite the previously written null-value with the actual object location.
        final RelocatableBuffer buffer = bufferForPartition(staticFieldsInfo, roBuffer, rwBuffer);
        writeReference(buffer, index, info.getObject(), staticFieldsInfo);
    } catch (NoSuchFieldException ex) {
        throw shouldNotReachHere(ex);
    }
}
Also used : HostedField(com.oracle.svm.hosted.meta.HostedField) NativeImageInfo(com.oracle.svm.core.heap.NativeImageInfo)

Example 5 with HostedField

use of com.oracle.svm.hosted.meta.HostedField in project graal by oracle.

the class NativeImageHeap method writeStaticFields.

private void writeStaticFields(RelocatableBuffer buffer) {
    /*
         * Write the values of static fields. The arrays for primitive and object fields are empty
         * and just placeholders. This ensures we get the latest version, since there can be
         * Features registered that change the value of static fields late in the native image
         * generation process.
         */
    ObjectInfo primitiveFields = objects.get(StaticFieldsSupport.getStaticPrimitiveFields());
    ObjectInfo objectFields = objects.get(StaticFieldsSupport.getStaticObjectFields());
    for (HostedField field : getUniverse().getFields()) {
        if (Modifier.isStatic(field.getModifiers()) && field.wrapped.isWritten() && field.wrapped.isAccessed()) {
            ObjectInfo fields = (field.getStorageKind() == JavaKind.Object) ? objectFields : primitiveFields;
            writeField(buffer, fields, field, null, null);
        }
    }
}
Also used : HostedField(com.oracle.svm.hosted.meta.HostedField)

Aggregations

HostedField (com.oracle.svm.hosted.meta.HostedField)13 HostedType (com.oracle.svm.hosted.meta.HostedType)4 AnalysisField (com.oracle.graal.pointsto.meta.AnalysisField)3 JavaKind (jdk.vm.ci.meta.JavaKind)3 DynamicHub (com.oracle.svm.core.hub.DynamicHub)2 SubstrateField (com.oracle.svm.graal.meta.SubstrateField)2 HostedArrayClass (com.oracle.svm.hosted.meta.HostedArrayClass)2 HostedInstanceClass (com.oracle.svm.hosted.meta.HostedInstanceClass)2 Field (java.lang.reflect.Field)2 BitSet (java.util.BitSet)2 JavaConstant (jdk.vm.ci.meta.JavaConstant)2 AnalysisType (com.oracle.graal.pointsto.meta.AnalysisType)1 AnalysisUniverse (com.oracle.graal.pointsto.meta.AnalysisUniverse)1 NativeImageInfo (com.oracle.svm.core.heap.NativeImageInfo)1 StringInternSupport (com.oracle.svm.core.jdk.StringInternSupport)1 ReadableJavaField (com.oracle.svm.core.meta.ReadableJavaField)1 SubstrateType (com.oracle.svm.graal.meta.SubstrateType)1 HybridLayout (com.oracle.svm.hosted.config.HybridLayout)1 HostedClass (com.oracle.svm.hosted.meta.HostedClass)1 HostedInterface (com.oracle.svm.hosted.meta.HostedInterface)1