Skip to content

Commit 4a03c97

Browse files
committed
[GR-38096] Initialize the parameters of root methods with the declared type.
PullRequest: graal/11605
2 parents 15c747c + 542f39c commit 4a03c97

File tree

22 files changed

+71
-282
lines changed

22 files changed

+71
-282
lines changed

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

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,17 @@
6060
import com.oracle.graal.pointsto.constraints.UnsupportedFeatures;
6161
import com.oracle.graal.pointsto.flow.AllSynchronizedTypeFlow;
6262
import com.oracle.graal.pointsto.flow.FieldTypeFlow;
63+
import com.oracle.graal.pointsto.flow.FormalParamTypeFlow;
64+
import com.oracle.graal.pointsto.flow.InvokeTypeFlow;
65+
import com.oracle.graal.pointsto.flow.MethodFlowsGraph;
6366
import com.oracle.graal.pointsto.flow.MethodTypeFlow;
6467
import com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder;
6568
import com.oracle.graal.pointsto.flow.OffsetLoadTypeFlow.AbstractUnsafeLoadTypeFlow;
6669
import com.oracle.graal.pointsto.flow.OffsetStoreTypeFlow.AbstractUnsafeStoreTypeFlow;
6770
import com.oracle.graal.pointsto.flow.TypeFlow;
6871
import com.oracle.graal.pointsto.flow.context.AnalysisContext;
6972
import com.oracle.graal.pointsto.flow.context.AnalysisContextPolicy;
73+
import com.oracle.graal.pointsto.infrastructure.WrappedSignature;
7074
import com.oracle.graal.pointsto.meta.AnalysisField;
7175
import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;
7276
import com.oracle.graal.pointsto.meta.AnalysisMethod;
@@ -443,46 +447,29 @@ public AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecia
443447

444448
AnalysisType declaringClass = aMethod.getDeclaringClass();
445449
boolean isStatic = aMethod.isStatic();
446-
int paramCount = aMethod.getSignature().getParameterCount(!isStatic);
450+
WrappedSignature signature = aMethod.getSignature();
451+
int paramCount = signature.getParameterCount(!isStatic);
447452
PointsToAnalysisMethod pointsToMethod = assertPointsToAnalysisMethod(aMethod);
448-
final MethodTypeFlow methodFlow = pointsToMethod.getTypeFlow();
449-
450-
/*
451-
* Add the initial parameter flows as uses to the type flow of their respective types.
452-
* The initial parameter flows will be linked to the concrete parameter flows after the
453-
* method is parsed and the method type flow is linked. This code is shared between
454-
* static and non-static methods and the differentiation is made below when the methods
455-
* are linked.
456-
*
457-
* The parameter iteration skips the primitive parameters, as these are not modeled, and
458-
* the receiver for virtual invokes which will be linked below.
459-
*
460-
* Note: the Signature doesn't count the receiver of a virtual invoke as a parameter
461-
* whereas the MethodTypeFlow does, hence when accessing the parameter type below we use
462-
* idx-offset but when setting the initial parameter flow we simply use idx.
463-
*/
464-
int offset = 0;
465-
if (!isStatic) {
466-
methodFlow.setInitialReceiverFlow(this, aMethod.getDeclaringClass());
467-
offset = 1;
468-
}
469-
for (int idx = offset; idx < paramCount; idx++) {
470-
AnalysisType declaredParamType = (AnalysisType) aMethod.getSignature().getParameterType(idx - offset, declaringClass);
471-
if (declaredParamType.getJavaKind() == JavaKind.Object) {
472-
methodFlow.setInitialParameterFlow(this, declaredParamType, idx);
473-
}
474-
}
475453

476454
if (isStatic) {
477455
/*
478456
* For static methods trigger analysis in the empty context. This will trigger
479-
* parsing and will add the actual parameter flows as uses to the initial parameter
480-
* flows initialized above.
457+
* parsing and return the method flows graph. Then the method parameter type flows
458+
* are initialized with the corresponding parameter declared type.
481459
*/
482460
postTask(() -> {
483461
pointsToMethod.registerAsDirectRootMethod();
484462
pointsToMethod.registerAsImplementationInvoked(null);
485-
methodFlow.addContext(PointsToAnalysis.this, PointsToAnalysis.this.contextPolicy().emptyContext());
463+
MethodTypeFlow methodFlow = pointsToMethod.getTypeFlow();
464+
MethodFlowsGraph methodFlowsGraph = methodFlow.addContext(PointsToAnalysis.this, PointsToAnalysis.this.contextPolicy().emptyContext());
465+
for (int idx = 0; idx < paramCount; idx++) {
466+
AnalysisType declaredParamType = (AnalysisType) signature.getParameterType(idx, declaringClass);
467+
FormalParamTypeFlow parameter = methodFlowsGraph.getParameter(idx);
468+
if (declaredParamType.getJavaKind() == JavaKind.Object && parameter != null) {
469+
TypeFlow<?> initialParameterFlow = declaredParamType.getTypeFlow(this, true);
470+
initialParameterFlow.addUse(this, parameter);
471+
}
472+
}
486473
});
487474
} else {
488475
if (invokeSpecial && pointsToMethod.isAbstract()) {
@@ -498,10 +485,10 @@ public AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecia
498485
* state it will get notified for any future reachable subtypes and will resolve the
499486
* method in each subtype.
500487
*
501-
* In both cases when a callee is resolved the method is parsed and the
502-
* corresponding actual parameter flows are added as uses to the initial parameter
503-
* flows initialized above. Then the callee is linked and registered as
504-
* implementation-invoked.
488+
* In both cases the context-insensitive invoke parameters are initialized with the
489+
* corresponding declared type state. When a callee is resolved the method is parsed
490+
* and the actual parameter type state is propagated to the formal parameters. Then
491+
* the callee is linked and registered as implementation-invoked.
505492
*/
506493
postTask(() -> {
507494
BytecodePosition location = new BytecodePosition(null, pointsToMethod, 0);
@@ -510,7 +497,30 @@ public AnalysisMethod addRootMethod(AnalysisMethod aMethod, boolean invokeSpecia
510497
} else {
511498
pointsToMethod.registerAsVirtualRootMethod();
512499
}
513-
pointsToMethod.initAndGetContextInsensitiveInvoke(PointsToAnalysis.this, location, invokeSpecial);
500+
InvokeTypeFlow invoke = pointsToMethod.initAndGetContextInsensitiveInvoke(PointsToAnalysis.this, location, invokeSpecial);
501+
/*
502+
* Initialize the type flow of the invoke's actual parameters with the
503+
* corresponding parameter declared type. Thus, when the invoke links callees it
504+
* will propagate the parameter types too.
505+
*
506+
* The parameter iteration skips the primitive parameters, as these are not
507+
* modeled. The type flow of the receiver is set to the receiver type already
508+
* when the invoke is created.
509+
*/
510+
for (int idx = 1; idx < paramCount; idx++) {
511+
/*
512+
* Note: the Signature doesn't count the receiver of a virtual invoke as a
513+
* parameter whereas the MethodTypeFlow does, hence when accessing the
514+
* parameter type below we use idx-1 but when accessing the actual parameter
515+
* flow we simply use idx.
516+
*/
517+
AnalysisType declaredParamType = (AnalysisType) signature.getParameterType(idx - 1, declaringClass);
518+
TypeFlow<?> actualParameterFlow = invoke.getActualParameter(idx);
519+
if (declaredParamType.getJavaKind() == JavaKind.Object && actualParameterFlow != null) {
520+
TypeFlow<?> initialParameterFlow = declaredParamType.getTypeFlow(this, true);
521+
initialParameterFlow.addUse(this, actualParameterFlow);
522+
}
523+
}
514524
});
515525
}
516526
}

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,8 @@ public TypeState filter(PointsToAnalysis bb, TypeState newState) {
6565
* i.e., 'this' parameter, state must ONLY reflect those objects of the actual receiver that
6666
* generated the context for the method clone which it belongs to. A direct link would instead
6767
* 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.
68+
* The formal receiver state is updated through the FormalReceiverTypeFlow.addReceiverState
69+
* method invoked directly from VirtualInvokeTypeFlow.update or SpecialInvokeTypeFlow.update.
7270
*/
7371
@Override
7472
public boolean addState(PointsToAnalysis bb, TypeState add) {

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

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

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

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

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

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ public class MethodFlowsGraph {
5858
// parameters, sources and field loads are the possible data entry
5959
// points in the method
6060
private FormalParamTypeFlow[] parameters;
61-
private InitialParamTypeFlow[] initialParameterFlows;
6261
private List<TypeFlow<?>> miscEntryFlows;
6362
private EconomicMap<EncodedNodeReference, TypeFlow<?>> nodeFlows;
6463
/*
@@ -98,9 +97,6 @@ public MethodFlowsGraph(PointsToAnalysisMethod analysisMethod) {
9897
method.getSignature().getParameterType(i - offset, method.getDeclaringClass());
9998
}
10099

101-
// initial parameter flows
102-
initialParameterFlows = new InitialParamTypeFlow[parameterCount];
103-
104100
// lookup the return type so that it is added to the universe even if the method is
105101
// never linked and parsed
106102
method.getSignature().getReturnType(method.getDeclaringClass());
@@ -134,8 +130,6 @@ public void cloneOriginalFlows(PointsToAnalysis bb) {
134130
}
135131
}
136132

137-
initialParameterFlows = new InitialParamTypeFlow[originalMethodFlowsGraph.initialParameterFlows.length];
138-
139133
nodeFlows = lookupClonesOf(bb, originalMethodFlowsGraph.nodeFlows);
140134
returnFlow = originalMethodFlowsGraph.getReturnFlow() != null ? lookupCloneOf(bb, originalMethodFlowsGraph.getReturnFlow()) : null;
141135
instanceOfFlows = lookupClonesOf(bb, originalMethodFlowsGraph.instanceOfFlows);
@@ -212,15 +206,6 @@ public void linkClones(final PointsToAnalysis bb) {
212206

213207
MethodFlowsGraph originalMethodFlowsGraph = method.getTypeFlow().originalMethodFlows;
214208

215-
/* Link the initial parameter flows to the parameters. */
216-
for (int i = 0; i < originalMethodFlowsGraph.initialParameterFlows.length; i++) {
217-
InitialParamTypeFlow initialParameterFlow = originalMethodFlowsGraph.getInitialParameterFlow(i);
218-
if (initialParameterFlow != null && parameters[i] != null) {
219-
initialParameterFlow.addUse(bb, parameters[i]);
220-
initialParameterFlows[i] = initialParameterFlow;
221-
}
222-
}
223-
224209
for (TypeFlow<?> original : originalMethodFlowsGraph.linearizedGraph) {
225210
TypeFlow<?> clone = lookupCloneOf(bb, original);
226211

@@ -387,20 +372,6 @@ public TypeFlow<?>[] getParameters() {
387372
return parameters;
388373
}
389374

390-
public void setInitialParameterFlow(InitialParamTypeFlow initialParameterFlow, int i) {
391-
assert i >= 0 && i < this.initialParameterFlows.length;
392-
initialParameterFlows[i] = initialParameterFlow;
393-
}
394-
395-
public InitialParamTypeFlow getInitialParameterFlow(int i) {
396-
assert i >= 0 && i < this.initialParameterFlows.length;
397-
return initialParameterFlows[i];
398-
}
399-
400-
public TypeFlow<?>[] getInitialParameterFlows() {
401-
return initialParameterFlows;
402-
}
403-
404375
public void addNodeFlow(EncodedNodeReference key, TypeFlow<?> flow) {
405376
assert flow != null && !(flow instanceof AllInstantiatedTypeFlow);
406377
if (nodeFlows == null) {

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

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
import com.oracle.graal.pointsto.constraints.UnsupportedFeatureException;
4949
import com.oracle.graal.pointsto.flow.context.AnalysisContext;
5050
import com.oracle.graal.pointsto.meta.AnalysisMethod;
51-
import com.oracle.graal.pointsto.meta.AnalysisType;
5251
import com.oracle.graal.pointsto.meta.PointsToAnalysisMethod;
5352
import com.oracle.graal.pointsto.typestate.TypeState;
5453
import com.oracle.graal.pointsto.util.AnalysisError;
@@ -158,20 +157,6 @@ public void setParameter(int index, FormalParamTypeFlow parameter) {
158157
originalMethodFlows.setParameter(index, parameter);
159158
}
160159

161-
public void setInitialReceiverFlow(PointsToAnalysis bb, AnalysisType declaringType) {
162-
TypeFlow<?> declaringTypeFlow = declaringType.getTypeFlow(bb, false);
163-
InitialReceiverTypeFlow initialReceiverFlow = new InitialReceiverTypeFlow(method, declaringType);
164-
declaringTypeFlow.addUse(bb, initialReceiverFlow);
165-
originalMethodFlows.setInitialParameterFlow(initialReceiverFlow, 0);
166-
}
167-
168-
public void setInitialParameterFlow(PointsToAnalysis bb, AnalysisType declaredType, int i) {
169-
TypeFlow<?> declaredTypeFlow = declaredType.getTypeFlow(bb, true);
170-
InitialParamTypeFlow initialParameterFlow = new InitialParamTypeFlow(method, declaredType, i);
171-
declaredTypeFlow.addUse(bb, initialParameterFlow);
172-
originalMethodFlows.setInitialParameterFlow(initialParameterFlow, i);
173-
}
174-
175160
protected void addInstanceOf(Object key, InstanceOfTypeFlow instanceOf) {
176161
originalMethodFlows.addInstanceOf(key, instanceOf);
177162
}

0 commit comments

Comments
 (0)