Search in sources :

Example 1 with HostedInstanceClass

use of com.oracle.svm.hosted.meta.HostedInstanceClass 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 2 with HostedInstanceClass

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

the class NativeImageHeap method choosePartition.

/**
 * Choose a partition of the native image heap for the given object.
 */
private HeapPartition choosePartition(final Object candidate, final boolean immutableArg) {
    final HostedType type = getMetaAccess().lookupJavaType(candidate.getClass());
    assert type.getWrapped().isInstantiated() : type;
    boolean written = false;
    boolean references = false;
    boolean immutable = immutableArg;
    if (type.isInstanceClass()) {
        final HostedInstanceClass clazz = (HostedInstanceClass) type;
        if (HybridLayout.isHybrid(clazz)) {
            final HybridLayout<?> hybridLayout = new HybridLayout<>(clazz, layout);
            final HostedField arrayField = hybridLayout.getArrayField();
            written |= arrayField.isWritten();
            final JavaKind arrayKind = hybridLayout.getArrayElementKind();
            references |= arrayKind.isObject();
        }
        // Aggregate over all the fields of the instance.
        for (HostedField field : clazz.getInstanceFields(true)) {
            /*
                 * Any field that is written says the instance is written. Except that if the field
                 * is final, it will only be written during initialization during native image
                 * construction, but will not be written in the running image.
                 */
            written |= field.isWritten() && !field.isFinal();
            references |= field.getType().getStorageKind().isObject();
        }
        // If the type has a monitor field, it has a reference field that is written.
        if (clazz.getMonitorFieldOffset() != 0) {
            written = true;
            references = true;
            immutable = false;
        }
    } else if (type.isArray()) {
        HostedArrayClass clazz = (HostedArrayClass) type;
        // TODO: How to know if any of the array elements are written?
        written = true;
        JavaKind kind = clazz.getComponentType().getJavaKind();
        references = kind.isObject();
    } else {
        throw shouldNotReachHere();
    }
    if (SubstrateOptions.UseOnlyWritableBootImageHeap.getValue()) {
        assert !spawnIsolates();
        // Emergency use only! Alarms will sound!
        return writableReference;
    }
    if (!written || immutable) {
        return references ? readOnlyReference : readOnlyPrimitive;
    } else {
        return references ? writableReference : writablePrimitive;
    }
}
Also used : HostedType(com.oracle.svm.hosted.meta.HostedType) HostedArrayClass(com.oracle.svm.hosted.meta.HostedArrayClass) HostedField(com.oracle.svm.hosted.meta.HostedField) HybridLayout(com.oracle.svm.hosted.config.HybridLayout) HostedInstanceClass(com.oracle.svm.hosted.meta.HostedInstanceClass) JavaKind(jdk.vm.ci.meta.JavaKind)

Aggregations

HostedArrayClass (com.oracle.svm.hosted.meta.HostedArrayClass)2 HostedField (com.oracle.svm.hosted.meta.HostedField)2 HostedInstanceClass (com.oracle.svm.hosted.meta.HostedInstanceClass)2 HostedType (com.oracle.svm.hosted.meta.HostedType)2 JavaKind (jdk.vm.ci.meta.JavaKind)2 HybridLayout (com.oracle.svm.hosted.config.HybridLayout)1 BitSet (java.util.BitSet)1 JavaConstant (jdk.vm.ci.meta.JavaConstant)1