Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -118,27 +118,27 @@ public void scanEmbeddedRoot(JavaConstant root, BytecodePosition position) {
public void onFieldRead(AnalysisField field) {
assert field.isRead();
/* Check if the value is available before accessing it. */
if (isValueAvailable(field)) {
FieldScan reason = new FieldScan(field);
AnalysisType declaringClass = field.getDeclaringClass();
if (field.isStatic()) {
FieldScan reason = new FieldScan(field);
AnalysisType declaringClass = field.getDeclaringClass();
if (field.isStatic()) {
if (isValueAvailable(field)) {
JavaConstant fieldValue = declaringClass.getOrComputeData().readFieldValue(field);
markReachable(fieldValue, reason);
notifyAnalysis(field, null, fieldValue, reason);
} else {
/* Trigger field scanning for the already processed objects. */
postTask(() -> onInstanceFieldRead(field, declaringClass, reason));
} else if (field.canBeNull()) {
notifyAnalysis(field, null, JavaConstant.NULL_POINTER, reason);
}
} else {
/* Trigger field scanning for the already processed objects. */
postTask(() -> onInstanceFieldRead(field, declaringClass, reason));
}
}

private void onInstanceFieldRead(AnalysisField field, AnalysisType type, FieldScan reason) {
for (AnalysisType subtype : type.getSubTypes()) {
for (ImageHeapConstant imageHeapConstant : imageHeap.getReachableObjects(subtype)) {
ImageHeapInstance imageHeapInstance = (ImageHeapInstance) imageHeapConstant;
JavaConstant fieldValue = imageHeapInstance.readFieldValue(field);
markReachable(fieldValue, reason);
notifyAnalysis(field, imageHeapInstance, fieldValue, reason);
updateInstanceField(field, imageHeapInstance, reason, null);
}
/* Subtypes include this type itself. */
if (!subtype.equals(type)) {
Expand Down Expand Up @@ -468,17 +468,25 @@ protected void onObjectReachable(ImageHeapConstant imageHeapConstant, ScanReason
} else if (imageHeapConstant instanceof ImageHeapInstance imageHeapInstance) {
for (ResolvedJavaField javaField : objectType.getInstanceFields(true)) {
AnalysisField field = (AnalysisField) javaField;
if (field.isRead() && isValueAvailable(field)) {
JavaConstant fieldValue = imageHeapInstance.readFieldValue(field);
markReachable(fieldValue, reason, onAnalysisModified);
notifyAnalysis(field, imageHeapInstance, fieldValue, reason, onAnalysisModified);
if (field.isRead()) {
updateInstanceField(field, imageHeapInstance, reason, onAnalysisModified);
}
}
}
}

public boolean isValueAvailable(@SuppressWarnings("unused") AnalysisField field) {
return true;
private void updateInstanceField(AnalysisField field, ImageHeapInstance imageHeapInstance, ScanReason reason, Consumer<ScanReason> onAnalysisModified) {
if (isValueAvailable(field)) {
JavaConstant fieldValue = imageHeapInstance.readFieldValue(field);
markReachable(fieldValue, reason, onAnalysisModified);
notifyAnalysis(field, imageHeapInstance, fieldValue, reason, onAnalysisModified);
} else if (field.canBeNull()) {
notifyAnalysis(field, imageHeapInstance, JavaConstant.NULL_POINTER, reason, onAnalysisModified);
}
}

public boolean isValueAvailable(AnalysisField field) {
return field.isValueAvailable();
}

protected String formatReason(String message, ScanReason reason) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,29 @@ public final class ImageHeapInfo {
/** Indicates no chunk with {@link #initialize} chunk offset parameters. */
public static final long NO_CHUNK = -1;

@UnknownObjectField(availability = AfterHeapLayout.class) public Object firstReadOnlyPrimitiveObject;
@UnknownObjectField(availability = AfterHeapLayout.class) public Object lastReadOnlyPrimitiveObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object firstReadOnlyPrimitiveObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object lastReadOnlyPrimitiveObject;

@UnknownObjectField(availability = AfterHeapLayout.class) public Object firstReadOnlyReferenceObject;
@UnknownObjectField(availability = AfterHeapLayout.class) public Object lastReadOnlyReferenceObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object firstReadOnlyReferenceObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object lastReadOnlyReferenceObject;

@UnknownObjectField(availability = AfterHeapLayout.class) public Object firstReadOnlyRelocatableObject;
@UnknownObjectField(availability = AfterHeapLayout.class) public Object lastReadOnlyRelocatableObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object firstReadOnlyRelocatableObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object lastReadOnlyRelocatableObject;

@UnknownObjectField(availability = AfterHeapLayout.class) public Object firstWritablePrimitiveObject;
@UnknownObjectField(availability = AfterHeapLayout.class) public Object lastWritablePrimitiveObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object firstWritablePrimitiveObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object lastWritablePrimitiveObject;

@UnknownObjectField(availability = AfterHeapLayout.class) public Object firstWritableReferenceObject;
@UnknownObjectField(availability = AfterHeapLayout.class) public Object lastWritableReferenceObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object firstWritableReferenceObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object lastWritableReferenceObject;

@UnknownObjectField(availability = AfterHeapLayout.class) public Object firstWritableHugeObject;
@UnknownObjectField(availability = AfterHeapLayout.class) public Object lastWritableHugeObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object firstWritableHugeObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object lastWritableHugeObject;

@UnknownObjectField(availability = AfterHeapLayout.class) public Object firstReadOnlyHugeObject;
@UnknownObjectField(availability = AfterHeapLayout.class) public Object lastReadOnlyHugeObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object firstReadOnlyHugeObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object lastReadOnlyHugeObject;

@UnknownObjectField(availability = AfterHeapLayout.class) public Object firstObject;
@UnknownObjectField(availability = AfterHeapLayout.class) public Object lastObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object firstObject;
@UnknownObjectField(availability = AfterHeapLayout.class, canBeNull = true) public Object lastObject;

// All offsets are relative to the heap base.
@UnknownPrimitiveField(availability = AfterHeapLayout.class) public long offsetOfFirstWritableAlignedChunk;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordFactory;

import com.oracle.svm.core.BuildPhaseProvider.AfterCompilation;
import com.oracle.svm.core.NeverInline;
import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.code.CodeInfo;
Expand Down Expand Up @@ -64,7 +65,7 @@
*/
public class HeapDumpUtils {

@UnknownObjectField private byte[] fieldsMap;
@UnknownObjectField(availability = AfterCompilation.class) private byte[] fieldsMap;

/** Extra methods for testing. */
private final TestingBackDoor testingBackDoor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ public final class DynamicHub implements AnnotatedElement, java.lang.reflect.Typ
* Back link to the SubstrateType used by the substrate meta access. Only used for the subset of
* types for which a SubstrateType exists.
*/
@UnknownObjectField(fullyQualifiedTypes = "com.oracle.svm.graal.meta.SubstrateType")//
private SharedType metaType;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import static org.graalvm.word.LocationIdentity.ANY_LOCATION;

import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -73,6 +72,7 @@
import org.graalvm.word.Pointer;
import org.graalvm.word.WordFactory;

import com.oracle.graal.pointsto.meta.AnalysisUniverse;
import com.oracle.svm.core.c.CGlobalData;
import com.oracle.svm.core.c.CGlobalDataFactory;
import com.oracle.svm.core.config.ConfigurationValues;
Expand All @@ -86,7 +86,6 @@
import com.oracle.svm.core.util.ImageHeapMap;
import com.oracle.svm.graal.meta.SubstrateMethod;
import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl;
import com.oracle.svm.util.ReflectionUtil;

/**
* Holds data that is pre-computed during native image generation and accessed at run time during a
Expand Down Expand Up @@ -129,11 +128,6 @@ public class GraalSupport {
protected final DiagnosticsOutputDirectory outputDirectory = new DiagnosticsOutputDirectory(RuntimeOptionValues.singleton());
protected final Map<ExceptionAction, Integer> compilationProblemsPerAction = new EnumMap<>(ExceptionAction.class);

private static final Field graphEncodingField = ReflectionUtil.lookupField(GraalSupport.class, "graphEncoding");
private static final Field graphObjectsField = ReflectionUtil.lookupField(GraalSupport.class, "graphObjects");
private static final Field graphNodeTypesField = ReflectionUtil.lookupField(GraalSupport.class, "graphNodeTypes");
private static final Field methodsToCompileField = ReflectionUtil.lookupField(GraalSupport.class, "methodsToCompile");

private static final CGlobalData<Pointer> nextIsolateId = CGlobalDataFactory.createWord((Pointer) WordFactory.unsigned(1L));

private volatile long isolateId = 0;
Expand Down Expand Up @@ -234,7 +228,7 @@ public static boolean setMethodsToCompile(DuringAnalysisAccessImpl config, Subst
GraalSupport support = get();
if (!Arrays.equals(support.methodsToCompile, methodsToCompile)) {
support.methodsToCompile = methodsToCompile;
GraalSupport.rescan(config, support, methodsToCompileField);
GraalSupport.rescan(config, methodsToCompile);
result = true;
}
return result;
Expand Down Expand Up @@ -274,28 +268,38 @@ public static boolean setGraphEncoding(FeatureAccess a, byte[] graphEncoding, Ob
boolean result = false;
if (!Arrays.equals(support.graphEncoding, graphEncoding)) {
support.graphEncoding = graphEncoding;
GraalSupport.rescan(a, support, graphEncodingField);
result = true;
}
if (!Arrays.deepEquals(support.graphObjects, graphObjects)) {
support.graphObjects = graphObjects;
GraalSupport.rescan(a, support, graphObjectsField);
GraalSupport.rescan(a, graphObjects);
result = true;
}
if (!Arrays.equals(support.graphNodeTypes, graphNodeTypes)) {
support.graphNodeTypes = graphNodeTypes;
GraalSupport.rescan(a, support, graphNodeTypesField);
GraalSupport.rescan(a, graphNodeTypes);
result = true;
}
return result;
}

private static void rescan(FeatureAccess a, GraalSupport support, Field field) {
if (a instanceof DuringAnalysisAccessImpl) {
((DuringAnalysisAccessImpl) a).rescanField(support, field);
private static void rescan(FeatureAccess a, Object object) {
if (a instanceof DuringAnalysisAccessImpl access) {
rescan(access.getUniverse(), object);
}
}

/**
* Rescan Graal objects during analysis. The fields that point to these objects are annotated
* with {@link UnknownObjectField} so their value is not processed during analysis, only their
* declared type is injected in the type flow graphs. Their eventual value becomes available
* after analysis. Later when the field is read the lazy value supplier scans the final value
* and patches the shadow heap.
*/
public static void rescan(AnalysisUniverse universe, Object object) {
universe.getHeapScanner().rescanObject(object);
}

@Platforms(Platform.HOSTED_ONLY.class)
public static void registerImmutableObjects(CompilationAccess access) {
access.registerAsImmutable(get().graphEncoding);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
*/
package com.oracle.svm.graal.hosted;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
Expand Down Expand Up @@ -56,6 +55,7 @@
import com.oracle.svm.core.util.HostedStringDeduplication;
import com.oracle.svm.core.util.ObservableImageHeapMapProvider;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.graal.GraalSupport;
import com.oracle.svm.graal.SubstrateGraalRuntime;
import com.oracle.svm.graal.meta.SubstrateField;
import com.oracle.svm.graal.meta.SubstrateMethod;
Expand Down Expand Up @@ -107,11 +107,6 @@ public class GraalGraphObjectReplacer implements Function<Object, Object> {

private final HostedStringDeduplication stringTable;

private final Field substrateFieldTypeField;
private final Field substrateFieldDeclaringClassField;
private final Field dynamicHubMetaTypeField;
private final Field substrateTypeRawAllInstanceFieldsField;

private final Class<?> jvmciCleanerClass = ReflectionUtil.lookupClass(false, "jdk.vm.ci.hotspot.Cleaner");

/**
Expand All @@ -125,10 +120,6 @@ public GraalGraphObjectReplacer(AnalysisUniverse aUniverse, SubstrateProviders s
this.sProviders = sProviders;
this.universeFactory = universeFactory;
this.stringTable = HostedStringDeduplication.singleton();
substrateFieldTypeField = ReflectionUtil.lookupField(SubstrateField.class, "type");
substrateFieldDeclaringClassField = ReflectionUtil.lookupField(SubstrateField.class, "declaringClass");
dynamicHubMetaTypeField = ReflectionUtil.lookupField(DynamicHub.class, "metaType");
substrateTypeRawAllInstanceFieldsField = ReflectionUtil.lookupField(SubstrateType.class, "rawAllInstanceFields");
}

public void setGraalRuntime(SubstrateGraalRuntime sGraalRuntime) {
Expand Down Expand Up @@ -289,8 +280,8 @@ public synchronized SubstrateField createField(ResolvedJavaField original) {
sField = newField;

sField.setLinks(createType(aField.getType()), createType(aField.getDeclaringClass()));
aUniverse.getHeapScanner().rescanField(sField, substrateFieldTypeField);
aUniverse.getHeapScanner().rescanField(sField, substrateFieldDeclaringClassField);
GraalSupport.rescan(aUniverse, sField.getType());
GraalSupport.rescan(aUniverse, sField.getDeclaringClass());
}
}
return sField;
Expand Down Expand Up @@ -338,10 +329,10 @@ public synchronized SubstrateType createType(JavaType original) {
if (sType == null) {
sType = newType;
hub.setMetaType(sType);
aUniverse.getHeapScanner().rescanField(hub, dynamicHubMetaTypeField);
GraalSupport.rescan(aUniverse, hub.getMetaType());

sType.setRawAllInstanceFields(createAllInstanceFields(aType));
aUniverse.getHeapScanner().rescanField(sType, substrateTypeRawAllInstanceFieldsField);
GraalSupport.rescan(aUniverse, sType.getRawAllInstanceFields());
createType(aType.getSuperclass());
createType(aType.getComponentType());
for (AnalysisType aInterface : aType.getInterfaces()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ public class SubstrateField implements SharedField {

protected static final SubstrateField[] EMPTY_ARRAY = new SubstrateField[0];

SubstrateType type;
SubstrateType declaringClass;
@UnknownObjectField SubstrateType type;
@UnknownObjectField SubstrateType declaringClass;
private final String name;
private final int modifiers;
private int hashCode;
Expand Down
Loading