use of com.oracle.svm.hosted.meta.HostedArrayClass 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();
}
}
use of com.oracle.svm.hosted.meta.HostedArrayClass 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;
}
}
Aggregations