Skip to content

Commit eea2a66

Browse files
committed
Propagate assignable types eagerly.
1 parent bcb541a commit eea2a66

23 files changed

+302
-349
lines changed

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

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,13 @@ public void forNonNullFieldValue(JavaConstant receiver, AnalysisField field, Jav
6161
AnalysisType fieldType = bb.getMetaAccess().lookupJavaType(bb.getSnippetReflectionProvider().asObject(Object.class, fieldValue).getClass());
6262
assert fieldType.isInstantiated() : fieldType;
6363

64-
/*
65-
* *ALL* constants are scanned after each analysis iteration, thus the fieldType will
66-
* eventually be added to the AllInstantiatedTypeFlow and the field type flow will
67-
* eventually be updated.
68-
*/
69-
70-
if (bb.getAllInstantiatedTypeFlow().getState().containsType(fieldType)) {
71-
/* Add the constant value object to the field's type flow. */
72-
FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(field, receiver);
73-
AnalysisObject constantObject = bb.analysisPolicy().createConstantObject(bb, fieldValue, fieldType);
74-
if (!fieldTypeFlow.getState().containsObject(constantObject)) {
75-
/* Add the new constant to the field's flow state. */
76-
TypeState constantTypeState = TypeState.forNonNullObject(bb, constantObject);
77-
fieldTypeFlow.addState(bb, constantTypeState);
78-
}
64+
/* Add the constant value object to the field's type flow. */
65+
FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(field, receiver);
66+
AnalysisObject constantObject = bb.analysisPolicy().createConstantObject(bb, fieldValue, fieldType);
67+
if (!fieldTypeFlow.getState().containsObject(constantObject)) {
68+
/* Add the new constant to the field's flow state. */
69+
TypeState constantTypeState = TypeState.forNonNullObject(bb, constantObject);
70+
fieldTypeFlow.addState(bb, constantTypeState);
7971
}
8072
}
8173

@@ -107,19 +99,13 @@ public void forNullArrayElement(JavaConstant array, AnalysisType arrayType, int
10799

108100
@Override
109101
public void forNonNullArrayElement(JavaConstant array, AnalysisType arrayType, JavaConstant elementConstant, AnalysisType elementType, int elementIndex) {
110-
/*
111-
* *ALL* constants are scanned after each analysis iteration, thus the elementType will
112-
* eventually be added to the AllInstantiatedTypeFlow and the array elements flow will
113-
* eventually be updated.
114-
*/
115-
if (bb.getAllInstantiatedTypeFlow().getState().containsType(elementType)) {
116-
ArrayElementsTypeFlow arrayObjElementsFlow = getArrayElementsFlow(array, arrayType);
117-
AnalysisObject constantObject = bb.analysisPolicy().createConstantObject(bb, elementConstant, elementType);
118-
if (!arrayObjElementsFlow.getState().containsObject(constantObject)) {
119-
/* Add the constant element to the constant's array type flow. */
120-
TypeState elementTypeState = TypeState.forNonNullObject(bb, constantObject);
121-
arrayObjElementsFlow.addState(bb, elementTypeState);
122-
}
102+
assert elementType.isInstantiated() : elementType;
103+
ArrayElementsTypeFlow arrayObjElementsFlow = getArrayElementsFlow(array, arrayType);
104+
AnalysisObject constantObject = bb.analysisPolicy().createConstantObject(bb, elementConstant, elementType);
105+
if (!arrayObjElementsFlow.getState().containsObject(constantObject)) {
106+
/* Add the constant element to the constant's array type flow. */
107+
TypeState elementTypeState = TypeState.forNonNullObject(bb, constantObject);
108+
arrayObjElementsFlow.addState(bb, elementTypeState);
123109
}
124110
}
125111

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ public abstract class BigBang {
108108

109109
protected final boolean trackTypeFlowInputs;
110110
protected final boolean reportAnalysisStatistics;
111+
protected final boolean extendedAsserts;
111112

112113
/**
113114
* Processing queue.
@@ -160,6 +161,7 @@ public BigBang(OptionValues options, AnalysisUniverse universe, HostedProviders
160161
if (reportAnalysisStatistics) {
161162
PointsToStats.init(this);
162163
}
164+
extendedAsserts = PointstoOptions.ExtendedAsserts.getValue(options);
163165

164166
unsafeLoads = new ConcurrentHashMap<>();
165167
unsafeStores = new ConcurrentHashMap<>();
@@ -194,6 +196,10 @@ public boolean reportAnalysisStatistics() {
194196
return reportAnalysisStatistics;
195197
}
196198

199+
public boolean extendedAsserts() {
200+
return extendedAsserts;
201+
}
202+
197203
public OptionValues getOptions() {
198204
return options;
199205
}
@@ -358,6 +364,10 @@ public TypeFlow<?> getAllInstantiatedTypeFlow() {
358364
return objectType.getTypeFlow(this, true);
359365
}
360366

367+
public TypeState getAllInstantiatedTypes() {
368+
return getAllInstantiatedTypeFlow().getState();
369+
}
370+
361371
public TypeFlow<?> getAllSynchronizedTypeFlow() {
362372
return allSynchronizedTypeFlow;
363373
}
@@ -369,7 +379,7 @@ public TypeState getAllSynchronizedTypeState() {
369379
* monitors.
370380
*/
371381
if (allSynchronizedTypeFlow.isSaturated()) {
372-
return getAllInstantiatedTypeFlow().getState();
382+
return getAllInstantiatedTypes();
373383
}
374384
return allSynchronizedTypeFlow.getState();
375385
}
@@ -627,7 +637,6 @@ private void checkObjectGraph() throws InterruptedException {
627637
} else {
628638
objectScanner.scanBootImageHeapRoots(null, null);
629639
}
630-
AnalysisType.updateAssignableTypes(this);
631640
}
632641

633642
public HeapScanningPolicy scanningPolicy() {
@@ -821,7 +830,7 @@ public void printHeader() {
821830

822831
@Override
823832
public void print() {
824-
System.out.format("%5d %5d %5d |", numParsedGraphs.get(), getAllInstantiatedTypeFlow().getState().typesCount(), universe.getNextTypeId());
833+
System.out.format("%5d %5d %5d |", numParsedGraphs.get(), getAllInstantiatedTypes().typesCount(), universe.getNextTypeId());
825834
super.print();
826835
System.out.println();
827836
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ public final void scanConstant(JavaConstant value, ScanReason reason, WorklistEn
246246
return;
247247
}
248248
if (!bb.scanningPolicy().scanConstant(bb, value)) {
249+
analysisType(bb, valueObj).registerAsInHeap();
249250
return;
250251
}
251252
if (scannedObjects.putAndAcquire(valueObj) == null) {

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AccessFieldTypeFlow.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public final boolean addState(BigBang bb, TypeState add) {
6666
*/
6767
protected TypeState filterObjectState(BigBang bb, TypeState objectState) {
6868
if (bb.analysisPolicy().relaxTypeFlowConstraints()) {
69-
return TypeState.forIntersection(bb, objectState, field.getDeclaringClass().getTypeFlow(bb, true).getState());
69+
return TypeState.forIntersection(bb, objectState, field.getDeclaringClass().getAssignableTypes(true));
7070
}
7171
return objectState;
7272
}

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AllInstantiatedTypeFlow.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030

3131
public final class AllInstantiatedTypeFlow extends TypeFlow<AnalysisType> {
3232

33-
public AllInstantiatedTypeFlow(AnalysisType declaredType) {
34-
super(declaredType, declaredType);
33+
public AllInstantiatedTypeFlow(AnalysisType declaredType, boolean canBeNull) {
34+
super(declaredType, declaredType, canBeNull);
3535
}
3636

3737
public AllInstantiatedTypeFlow(AnalysisType declaredType, TypeState state) {

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ArrayElementsTypeFlow.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public boolean canSaturate() {
6161
@Override
6262
protected void onInputSaturated(BigBang bb, TypeFlow<?> input) {
6363
/*
64-
* When an array store is saturated conservativelly assume that the array can contain any
64+
* When an array store is saturated conservatively assume that the array can contain any
6565
* subtype of its declared type.
6666
*/
6767
getDeclaredType().getTypeFlow(bb, true).addUse(bb, this);
@@ -79,7 +79,7 @@ public TypeState filter(BigBang bb, TypeState update) {
7979
* conversion. At runtime that will throw an ArrayStoreException but during the analysis
8080
* we can detect such cases and filter out the incompatible types.
8181
*/
82-
return TypeState.forIntersection(bb, update, declaredType.getTypeFlow(bb, true).getState());
82+
return TypeState.forIntersection(bb, update, declaredType.getAssignableTypes(true));
8383
}
8484
}
8585

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FieldFilterTypeFlow.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public TypeState filter(BigBang bb, TypeState update) {
5151
return update;
5252
} else {
5353
/* Filter the incoming state with the field type. */
54-
return TypeState.forIntersection(bb, update, declaredType.getTypeFlow(bb, true).getState());
54+
return TypeState.forIntersection(bb, update, declaredType.getAssignableTypes(true));
5555
}
5656
}
5757

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FieldTypeFlow.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,13 @@ public boolean canSaturate() {
8787
@Override
8888
protected void onInputSaturated(BigBang bb, TypeFlow<?> input) {
8989
/*
90-
* When a field store is saturated conservativelly assume that the field state can contain
90+
* When a field store is saturated conservatively assume that the field state can contain
9191
* any subtype of its declared type.
9292
*/
9393
getDeclaredType().getTypeFlow(bb, true).addUse(bb, this);
9494
}
9595

96-
/** The filter flow is used for unsafe writes and initialiazed on demand. */
96+
/** The filter flow is used for unsafe writes and initialized on demand. */
9797
public FieldFilterTypeFlow filterFlow(BigBang bb) {
9898
assert source.isUnsafeAccessed() : "Filter flow requested for non unsafe accessed field.";
9999

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FilterTypeFlow.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ public TypeState filter(BigBang bb, TypeState update) {
9191
* instantiated sub-types).
9292
*/
9393
if (isAssignable) {
94-
result = TypeState.forIntersection(bb, update, declaredType.getTypeFlow(bb, includeNull).getState());
94+
result = TypeState.forIntersection(bb, update, declaredType.getAssignableTypes(includeNull));
9595
} else {
96-
result = TypeState.forSubtraction(bb, update, declaredType.getTypeFlow(bb, !includeNull).getState());
96+
result = TypeState.forSubtraction(bb, update, declaredType.getAssignableTypes(!includeNull));
9797
}
9898
}
9999
return result;
@@ -111,7 +111,7 @@ protected void onInputSaturated(BigBang bb, TypeFlow<?> input) {
111111
* swap-out will have no effect on those. However, if this flow is already marked as
112112
* saturated when the use or observer *lands*, even if that happens while/after
113113
* swapping-out, then the corresponding use or observer will be notified of its input
114-
* saturation. Otherwise it may neighter get the saturation signal OR get swapped-out.
114+
* saturation. Otherwise it may neither get the saturation signal OR get swapped-out.
115115
*
116116
* The downside in the later case is that the input/observer will lose the more precise
117117
* type information that swapping-out would have provided and will just use the more

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalReceiverTypeFlow.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,20 +58,20 @@ public TypeState filter(BigBang bb, TypeState newState) {
5858
return declaredTypeFilter(bb, newState).forNonNull(bb);
5959
}
6060

61+
/**
62+
* The formal receiver type flow, i.e., the type flow of the 'this' parameter, is linked with
63+
* the actual receiver type flow through a non-state-transfer link, i.e., a link that exists
64+
* only for a proper iteration of type flow graphs. This happens because the formal receiver ,
65+
* i.e., 'this' parameter, state must ONLY reflect those objects of the actual receiver that
66+
* generated the context for the method clone which it belongs to. A direct link would instead
67+
* transfer all the objects of compatible type from the actual receiver to the formal receiver.
68+
* The formal receiver state for the non-initial parameters is updated through the
69+
* FormalReceiverTypeFlow.addReceiverState method invoked directly from
70+
* VirtualInvokeTypeFlow.update, SpecialInvokeTypeFlow.update or from
71+
* InitialReceiverTypeFlow.update.
72+
*/
6173
@Override
6274
public boolean addState(BigBang bb, TypeState add) {
63-
/*
64-
* The formal receiver type flow, i.e., the type flow of the 'this' parameter is linked with
65-
* the actual receiver type flow through a non-state-transfer link, i.e., a link that exists
66-
* only for a proper iteration of type flow graphs. This happens because the formal receiver
67-
* , i.e., 'this' parameter, state must ONLY reflect those objects of the actual receiver
68-
* that generated the context for the method clone which it belongs to. A direct link would
69-
* instead transfer all the objects of compatible type from the actual receiver to the
70-
* formal receiver. The formal receiver state for the non-initial parameters is updated
71-
* through the FormalReceiverTypeFlow.addReceiverState method invoked directly from
72-
* VirtualInvokeTypeFlow.update, SpecialInvokeTypeFlow.update or from
73-
* InitialReceiverTypeFlow.update.
74-
*/
7575
return false;
7676
}
7777

0 commit comments

Comments
 (0)