Skip to content

Commit a9aade0

Browse files
committed
Simplify root fields registration.
1 parent 54b86b3 commit a9aade0

File tree

6 files changed

+63
-115
lines changed

6 files changed

+63
-115
lines changed

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,53 @@ public void onTypeInstantiated(AnalysisType type) {
655655
});
656656
}
657657

658+
/**
659+
* Inject custom types in the analysis field type state. This utility is used for:
660+
* <ul>
661+
* <li>root fields - whose state is forced to be that of the declared type</li>
662+
* <li>unsafe accessed fields - whose state is conservatively also the declared type</li>
663+
* <li>lazily computed fields - for which writes are not visible during analysis</li>
664+
* <ul/>
665+
*/
666+
@Override
667+
public void injectFieldTypes(AnalysisField aField, List<AnalysisType> customTypes, boolean canBeNull) {
668+
assert aField.getStorageKind().isObject();
669+
var ptaField = (PointsToAnalysisField) aField;
670+
671+
/* Link the field with all declared types. */
672+
for (AnalysisType type : customTypes) {
673+
if (type.isPrimitive() || type.isWordType()) {
674+
continue;
675+
}
676+
type.getTypeFlow(this, canBeNull).addUse(this, ptaField.getInitialFlow());
677+
678+
if (type.isArray()) {
679+
AnalysisType fieldComponentType = type.getComponentType();
680+
ptaField.getInitialFlow().addUse(this, ptaField.getSinkFlow());
681+
if (!(fieldComponentType.isPrimitive() || fieldComponentType.isWordType())) {
682+
/*
683+
* Write the component type abstract object into the field array elements type
684+
* flow, i.e., the array elements type flow of the abstract object of the field
685+
* declared type.
686+
*
687+
* This is required so that the index loads from this array return all the
688+
* possible objects that can be stored in the array.
689+
*/
690+
TypeFlow<?> elementsFlow = type.getContextInsensitiveAnalysisObject().getArrayElementsFlow(this, true);
691+
fieldComponentType.getTypeFlow(this, false).addUse(this, elementsFlow);
692+
693+
/*
694+
* In the current implementation it is not necessary to do it recursively for
695+
* multidimensional arrays since we don't model individual array elements, so
696+
* from the point of view of the static analysis the field's array elements
697+
* value is non-null (in the case of an n-dimensional array that value is
698+
* another array, n-1 dimensional).
699+
*/
700+
}
701+
}
702+
}
703+
}
704+
658705
public static class ConstantObjectsProfiler {
659706

660707
static final ConcurrentHashMap<AnalysisType, MyInteger> constantTypes = new ConcurrentHashMap<>(ESTIMATED_NUMBER_OF_TYPES);

substratevm/src/com.oracle.graal.reachability/src/com/oracle/graal/reachability/ReachabilityAnalysisEngine.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.Collections;
3030
import java.util.Deque;
3131
import java.util.HashSet;
32+
import java.util.List;
3233
import java.util.Set;
3334

3435
import com.oracle.graal.pointsto.AbstractAnalysisEngine;
@@ -154,6 +155,15 @@ public AnalysisType addRootField(AnalysisField analysisField) {
154155
return analysisField.getType();
155156
}
156157

158+
@Override
159+
public void injectFieldTypes(AnalysisField aField, List<AnalysisType> customTypes, boolean canBeNull) {
160+
assert aField.getStorageKind().isObject();
161+
aField.registerAsAccessed("@UnknownObjectField annotated field.");
162+
for (AnalysisType declaredType : customTypes) {
163+
declaredType.registerAsReachable("injected field types for unknown annotated field " + aField.format("%H.%n"));
164+
}
165+
}
166+
157167
@Override
158168
public AnalysisMethod addRootMethod(AnalysisMethod m, boolean invokeSpecial, Object reason, MultiMethod.MultiMethodKey... otherRoots) {
159169
assert otherRoots.length == 0 : otherRoots;

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ameta/CustomTypeFieldHandler.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
import com.oracle.graal.pointsto.meta.PointsToAnalysisField;
3939
import com.oracle.svm.hosted.analysis.FieldValueComputer;
4040

41-
public abstract class CustomTypeFieldHandler {
42-
protected final BigBang bb;
41+
public final class CustomTypeFieldHandler {
42+
private final BigBang bb;
4343
private final AnalysisMetaAccess metaAccess;
4444
private final FieldValueInterceptionSupport fieldValueInterceptionSupport = FieldValueInterceptionSupport.singleton();
4545
private Set<AnalysisField> processedFields = ConcurrentHashMap.newKeySet();
@@ -60,7 +60,7 @@ public void handleField(AnalysisField field) {
6060
assert field.isAccessed();
6161
if (fieldValueInterceptionSupport.hasFieldValueTransformer(field)) {
6262
if (field.getStorageKind().isObject() && !fieldValueInterceptionSupport.isValueAvailable(field, null, !field.isStatic())) {
63-
injectFieldTypes(field, List.of(field.getType()), true);
63+
bb.injectFieldTypes(field, List.of(field.getType()), true);
6464
} else if (bb.trackPrimitiveValues() && field.getStorageKind().isPrimitive() && field instanceof PointsToAnalysisField ptaField) {
6565
ptaField.saturatePrimitiveField();
6666
}
@@ -71,15 +71,13 @@ public void handleField(AnalysisField field) {
7171
assert !type.isPrimitive() : type + " for " + field;
7272
type.registerAsInstantiated("Is declared as the type of an unknown object field.");
7373
}
74-
injectFieldTypes(field, types, fieldValueComputer.canBeNull());
74+
bb.injectFieldTypes(field, types, fieldValueComputer.canBeNull());
7575
} else if (bb.trackPrimitiveValues() && field.getStorageKind().isPrimitive() && field instanceof PointsToAnalysisField ptaField) {
7676
ptaField.saturatePrimitiveField();
7777
}
7878
}
7979
}
8080

81-
public abstract void injectFieldTypes(AnalysisField aField, List<AnalysisType> customTypes, boolean canBeNull);
82-
8381
private List<AnalysisType> transformTypes(AnalysisField field, List<Class<?>> types) {
8482
List<AnalysisType> customTypes = new ArrayList<>();
8583
AnalysisType declaredType = field.getType();

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/NativeImagePointsToAnalysis.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import java.lang.reflect.Executable;
2828
import java.lang.reflect.Method;
2929
import java.lang.reflect.Modifier;
30-
import java.util.List;
3130
import java.util.concurrent.ConcurrentHashMap;
3231

3332
import com.oracle.graal.pointsto.ClassInclusionPolicy;
@@ -87,7 +86,7 @@ public NativeImagePointsToAnalysis(OptionValues options, AnalysisUniverse univer
8786
this.annotationSubstitutionProcessor = annotationSubstitutionProcessor;
8887

8988
dynamicHubInitializer = new DynamicHubInitializer(this);
90-
customTypeFieldHandler = new PointsToCustomTypeFieldHandler(this, metaAccess);
89+
customTypeFieldHandler = new CustomTypeFieldHandler(this, metaAccess);
9190
callChecker = new CallChecker();
9291
}
9392

@@ -128,11 +127,6 @@ public void onFieldAccessed(AnalysisField field) {
128127
postTask(() -> customTypeFieldHandler.handleField(field));
129128
}
130129

131-
@Override
132-
public void injectFieldTypes(AnalysisField aField, List<AnalysisType> customTypes, boolean canBeNull) {
133-
customTypeFieldHandler.injectFieldTypes(aField, customTypes, canBeNull);
134-
}
135-
136130
@Override
137131
public void onTypeReachable(AnalysisType type) {
138132
postTask(_ -> {

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/NativeImageReachabilityAnalysisEngine.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
*/
2525
package com.oracle.svm.hosted.analysis;
2626

27-
import java.util.List;
28-
2927
import com.oracle.graal.pointsto.ClassInclusionPolicy;
3028
import com.oracle.graal.pointsto.meta.AnalysisField;
3129
import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;
@@ -58,16 +56,7 @@ public NativeImageReachabilityAnalysisEngine(OptionValues options, AnalysisUnive
5856
reachabilityMethodProcessingHandler, classInclusionPolicy);
5957
this.annotationSubstitutionProcessor = annotationSubstitutionProcessor;
6058
this.dynamicHubInitializer = new DynamicHubInitializer(this);
61-
this.unknownFieldHandler = new CustomTypeFieldHandler(this, metaAccess) {
62-
@Override
63-
public void injectFieldTypes(AnalysisField aField, List<AnalysisType> declaredTypes, boolean canBeNull) {
64-
assert aField.getStorageKind().isObject();
65-
aField.registerAsAccessed("@UnknownObjectField annotated field.");
66-
for (AnalysisType declaredType : declaredTypes) {
67-
declaredType.registerAsReachable("injected field types for unknown annotated field " + aField.format("%H.%n"));
68-
}
69-
}
70-
};
59+
this.unknownFieldHandler = new CustomTypeFieldHandler(this, metaAccess);
7160
}
7261

7362
@Override

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/PointsToCustomTypeFieldHandler.java

Lines changed: 0 additions & 90 deletions
This file was deleted.

0 commit comments

Comments
 (0)