Skip to content

Commit 977ba5d

Browse files
committed
[GR-47662] [GR-47506] Fix race on getAllCallees and typeflow creation.
PullRequest: graal/15142
2 parents 5d60297 + ccf95d5 commit 977ba5d

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ public Collection<AnalysisMethod> getAllCallees() {
117117
return ConcurrentLightHashSet.getElements(this, CALLEES_UPDATER);
118118
}
119119

120+
@Override
121+
public final Collection<AnalysisMethod> getAllComputedCallees() {
122+
return getAllCallees();
123+
}
124+
120125
@Override
121126
public String toString() {
122127
return "VirtualInvoke<" + targetMethod.format("%h.%n") + ">" + ":" + getState();

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,24 @@ public final boolean isDirectInvoke() {
7474

7575
@Override
7676
public final Collection<AnalysisMethod> getAllCallees() {
77-
if (targetMethod.isImplementationInvoked()) {
77+
return getAllCalleesHelper(false);
78+
}
79+
80+
@Override
81+
public final Collection<AnalysisMethod> getAllComputedCallees() {
82+
return getAllCalleesHelper(true);
83+
}
84+
85+
private Collection<AnalysisMethod> getAllCalleesHelper(boolean allComputed) {
86+
if (allComputed || targetMethod.isImplementationInvoked()) {
7887
/*
7988
* When type states are filtered (e.g. due to context sensitivity), it is possible for a
8089
* callee to be set, but for it not to be linked.
8190
*/
8291
Collection<AnalysisMethod> result = LightImmutableCollection.toCollection(this, CALLEES_ACCESSOR);
83-
assert result.stream().filter(m -> m.isOriginalMethod()).allMatch(AnalysisMethod::isImplementationInvoked);
92+
if (!allComputed) {
93+
assert result.stream().filter(m -> m.isOriginalMethod()).allMatch(AnalysisMethod::isImplementationInvoked);
94+
}
8495
return result;
8596
}
8697
return Collections.emptyList();

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public abstract class InvokeTypeFlow extends TypeFlow<BytecodePosition> implemen
5050
/**
5151
* Result type flow returned by the callee.
5252
*/
53-
protected ActualReturnTypeFlow actualReturn;
53+
protected volatile ActualReturnTypeFlow actualReturn;
5454

5555
protected final InvokeTypeFlow originalInvoke;
5656

@@ -270,6 +270,10 @@ protected void linkCallee(PointsToAnalysis bb, boolean isStatic, MethodFlowsGrap
270270
}
271271

272272
public void linkReturn(PointsToAnalysis bb, boolean isStatic, MethodFlowsGraphInfo calleeFlows) {
273+
/*
274+
* If actualReturn is null, then there is no linking necessary. Later, if a typeflow is
275+
* created for the return, then {@code setActualReturn} will perform all necessary linking.
276+
*/
273277
if (actualReturn != null && bb.getHostVM().getMultiMethodAnalysisPolicy().performReturnLinking(callerMultiMethodKey, calleeFlows.getMethod().getMultiMethodKey())) {
274278
if (bb.optimizeReturnedParameter()) {
275279
int paramNodeIndex = calleeFlows.getMethod().getTypeFlow().getReturnedParameterIndex();
@@ -339,6 +343,12 @@ public Collection<AnalysisMethod> getOriginalCallees() {
339343
@Override
340344
public abstract Collection<AnalysisMethod> getAllCallees();
341345

346+
/**
347+
* Returns all callees which have been computed for this method. It is possible that these
348+
* callees have yet to have their typeflow created and also they may not be fully linked.
349+
*/
350+
public abstract Collection<AnalysisMethod> getAllComputedCallees();
351+
342352
@Override
343353
public BytecodePosition getPosition() {
344354
return getSource();

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/DefaultAnalysisPolicy.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,14 @@ public boolean addOriginalObserver(PointsToAnalysis bb, TypeFlow<?> flow, TypeFl
233233

234234
@Override
235235
public void linkActualReturn(PointsToAnalysis bb, boolean isStatic, InvokeTypeFlow invoke) {
236-
/* Link the actual return with the formal return of already linked callees. */
237-
for (AnalysisMethod callee : invoke.getAllCallees()) {
238-
invoke.linkReturn(bb, isStatic, ((PointsToAnalysisMethod) callee).getTypeFlow().getMethodFlowsGraphInfo());
236+
/*
237+
* Link the actual return with the formal return of already linked callees. Note the callees
238+
* may not be fully linked if they have been {@code DirectInvokeTypeFlow#initializeCallees}
239+
* but not yet processed.
240+
*/
241+
for (AnalysisMethod callee : invoke.getAllComputedCallees()) {
242+
MethodFlowsGraphInfo calleeFlows = ((PointsToAnalysisMethod) callee).getTypeFlow().getOrCreateMethodFlowsGraphInfo(bb, invoke);
243+
invoke.linkReturn(bb, isStatic, calleeFlows);
239244
}
240245
if (invoke.isSaturated()) {
241246
InvokeTypeFlow contextInsensitiveInvoke = invoke.getTargetMethod().getContextInsensitiveVirtualInvoke(invoke.getCallerMultiMethodKey());

0 commit comments

Comments
 (0)