Skip to content

Commit f4676a7

Browse files
committed
[GR-57552] Allow registerOpaqueMethodReturn/ReturnsAllInstantiatedTypes for methods returning primitives
PullRequest: graal/18646
2 parents 5d2033e + 8484b87 commit f4676a7

File tree

8 files changed

+35
-39
lines changed

8 files changed

+35
-39
lines changed

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,10 @@ public MethodFlowsGraphInfo addContext(PointsToAnalysis bb, AnalysisContext call
7373
newFlows.cloneOriginalFlows(bb);
7474
newFlows.linkCloneFlows(bb);
7575
/*
76-
* If this method returns all instantiated types, then it will not be linked to
77-
* any internal flows. Instead, it needs to be linked to its declared type's
78-
* flow.
76+
* If this method has opaque return, then it will not be linked to any internal
77+
* flows. Instead, it needs to be linked to its declared type's flow.
7978
*/
80-
if (flowsGraph.method.getReturnsAllInstantiatedTypes()) {
79+
if (flowsGraph.method.hasOpaqueReturn()) {
8180
var newReturnFlow = newFlows.getReturnFlow();
8281
newReturnFlow.getDeclaredType().getTypeFlow(bb, true).addUse(bb, newReturnFlow);
8382
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ private synchronized void createFlowsGraph(PointsToAnalysis bb, InvokeTypeFlow r
171171
}
172172
bb.numParsedGraphs.incrementAndGet();
173173

174-
boolean computeIndex = !method.getReturnsAllInstantiatedTypes() && bb.getHostVM().getMultiMethodAnalysisPolicy().canComputeReturnedParameterIndex(method.getMultiMethodKey());
174+
boolean computeIndex = !method.hasOpaqueReturn() && bb.getHostVM().getMultiMethodAnalysisPolicy().canComputeReturnedParameterIndex(method.getMultiMethodKey());
175175
returnedParameterIndex = computeIndex ? computeReturnedParameterIndex(builder.graph) : -1;
176176

177177
/* Set the flows graph after fully built. */

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

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -468,11 +468,14 @@ private boolean handleNodeIntrinsic() {
468468
return false;
469469
}
470470

471-
private void insertAllInstantiatedTypesReturn() {
471+
/**
472+
* If a method has opaque return, we model it conservatively by returning a) all instantiated
473+
* subtypes of its return type for an object type or b) any primitive value for a primitive.
474+
*/
475+
private void handleOpaqueReturn() {
472476
AnalysisError.guarantee(flowsGraph.getReturnFlow() == null, "Expected null return flow");
473477

474478
AnalysisType returnType = TypeFlow.filterUncheckedInterface(method.getSignature().getReturnType());
475-
AnalysisError.guarantee(returnType.getJavaKind().isObject(), "Unexpected return type: %s", returnType);
476479

477480
BytecodePosition position = AbstractAnalysisEngine.syntheticSourcePosition(null, method);
478481
var returnFlow = new FormalReturnTypeFlow(position, returnType);
@@ -626,9 +629,9 @@ protected void apply(boolean forceReparse, Object reason) {
626629
*/
627630
AnalysisType returnType = method.getSignature().getReturnType();
628631
if (returnType.getJavaKind().isObject()) {
629-
// GR-52421: the return type state should not be all-instantiated, it should be the
632+
// GR-52421: the return should not be opaque, it should be the
630633
// persisted result of the open-world analysis
631-
insertAllInstantiatedTypesReturn();
634+
handleOpaqueReturn();
632635
}
633636
// GR-52421: verify that tracked parameter state is subset of persisted state
634637
insertPlaceholderParamAndReturnFlows();
@@ -637,12 +640,12 @@ protected void apply(boolean forceReparse, Object reason) {
637640

638641
// assert method.getAnnotation(Fold.class) == null : method;
639642
if (handleNodeIntrinsic()) {
640-
assert !method.getReturnsAllInstantiatedTypes() : method;
643+
assert !method.hasOpaqueReturn() : method;
641644
return;
642645
}
643646

644-
if (method.getReturnsAllInstantiatedTypes()) {
645-
insertAllInstantiatedTypesReturn();
647+
if (method.hasOpaqueReturn()) {
648+
handleOpaqueReturn();
646649
}
647650

648651
boolean insertPlaceholderFlows = bb.getHostVM().getMultiMethodAnalysisPolicy().insertPlaceholderParamAndReturnFlows(method.getMultiMethodKey());
@@ -954,10 +957,10 @@ protected void node(FixedNode n) {
954957

955958
} else if (n instanceof ReturnNode) {
956959
/*
957-
* Return type flows within the graph do not need to be linked when all instantiated
958-
* types are returned.
960+
* Return type flows within the graph do not need to be linked if the method has
961+
* opaque return.
959962
*/
960-
if (!method.getReturnsAllInstantiatedTypes()) {
963+
if (!method.hasOpaqueReturn()) {
961964
ReturnNode node = (ReturnNode) n;
962965
if (node.result() != null && bb.isSupportedJavaKind(node.result().getStackKind())) {
963966
TypeFlowBuilder<?> returnFlowBuilder = uniqueReturnFlowBuilder(node);

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisMethod.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,13 @@ public record Signature(String name, AnalysisType[] parameterTypes) {
182182
@SuppressWarnings("unused") private volatile Object allImplementations;
183183

184184
/**
185-
* Indicates that this method returns all instantiated types. This is necessary when there are
186-
* control flows present which cannot be tracked by analysis, which happens for continuation
187-
* support.
185+
* Indicates that this method has opaque return. This is necessary when there are control flows
186+
* present which cannot be tracked by analysis, which happens for continuation support.
188187
*
189188
* This should only be set via calling
190189
* {@code FeatureImpl.BeforeAnalysisAccessImpl#registerOpaqueMethodReturn}.
191190
*/
192-
private boolean returnsAllInstantiatedTypes;
191+
private boolean hasOpaqueReturn;
193192

194193
@SuppressWarnings({"this-escape", "unchecked"})
195194
protected AnalysisMethod(AnalysisUniverse universe, ResolvedJavaMethod wrapped, MultiMethodKey multiMethodKey, Map<MultiMethodKey, MultiMethod> multiMethodMap) {
@@ -288,7 +287,7 @@ protected AnalysisMethod(AnalysisMethod original, MultiMethodKey multiMethodKey)
288287
this.multiMethodKey = multiMethodKey;
289288
assert original.multiMethodMap != null;
290289
multiMethodMap = original.multiMethodMap;
291-
returnsAllInstantiatedTypes = original.returnsAllInstantiatedTypes;
290+
hasOpaqueReturn = original.hasOpaqueReturn;
292291

293292
if (PointstoOptions.TrackAccessChain.getValue(declaringClass.universe.hostVM().options())) {
294293
startTrackInvocations();
@@ -1138,12 +1137,12 @@ public AnalysisMethod getOrCreateMultiMethod(MultiMethodKey key, Consumer<Analys
11381137
* This should only be set via calling
11391138
* {@code FeatureImpl.BeforeAnalysisAccessImpl#registerOpaqueMethodReturn}.
11401139
*/
1141-
public void setReturnsAllInstantiatedTypes() {
1142-
returnsAllInstantiatedTypes = true;
1140+
public void setOpaqueReturn() {
1141+
hasOpaqueReturn = true;
11431142
}
11441143

1145-
public boolean getReturnsAllInstantiatedTypes() {
1146-
return returnsAllInstantiatedTypes;
1144+
public boolean hasOpaqueReturn() {
1145+
return hasOpaqueReturn;
11471146
}
11481147

11491148
protected abstract AnalysisMethod createMultiMethod(AnalysisMethod analysisMethod, MultiMethodKey newMultiMethodKey);

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,8 @@ private void mergeConstantObjects(PointsToAnalysis bb) {
488488
public AllInstantiatedTypeFlow instantiatedTypesNonNull;
489489

490490
/*
491-
* Returns a type flow containing all types that are assignable from this type and are also
492-
* instantiated.
491+
* Returns a generic type flow containing a) all types that are assignable from this type and
492+
* are also instantiated for objects or b) any primitive value for primitives.
493493
*/
494494
public TypeFlow<?> getTypeFlow(@SuppressWarnings("unused") BigBang bb, boolean includeNull) {
495495
if (isPrimitive() || isWordType()) {

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/PointsToAnalysisMethod.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ public void cleanupAfterAnalysis() {
244244
}
245245

246246
@Override
247-
public void setReturnsAllInstantiatedTypes() {
248-
super.setReturnsAllInstantiatedTypes();
249-
assert !getTypeFlow().flowsGraphCreated() : "must call setReturnsAllInstantiatedTypes before typeflow is created";
247+
public void setOpaqueReturn() {
248+
super.setOpaqueReturn();
249+
assert !getTypeFlow().flowsGraphCreated() : "must call setOpaqueReturn before typeflow is created";
250250
}
251251
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/FeatureImpl.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -492,16 +492,11 @@ public void registerFieldValueTransformer(Field field, FieldValueTransformer tra
492492
/**
493493
* Registers a method as having an analysis-opaque return value. This designation limits the
494494
* type-flow analysis performed on the method's return value.
495-
*
496-
* Currently we expect only methods with the Object return type to be registered via this
497-
* method; however, the underlying analysis support can handle other object types (including
498-
* untrusted interfaces).
499495
*/
500496
public void registerOpaqueMethodReturn(Method method) {
501497
AnalysisMethod aMethod = bb.getMetaAccess().lookupJavaMethod(method);
502498
VMError.guarantee(aMethod.getAllMultiMethods().size() == 1, "Opaque method return called for method with >1 multimethods: %s ", method);
503-
VMError.guarantee(method.getReturnType().equals(Object.class), "Called registerOpaqueMethodReturn for a method with a non-Object return type: %s", method);
504-
aMethod.setReturnsAllInstantiatedTypes();
499+
aMethod.setOpaqueReturn();
505500
}
506501
}
507502

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/InlineBeforeAnalysisPolicyUtils.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,11 @@ public static boolean inliningAllowed(SVMHost hostVM, GraphBuilderContext b, Ana
235235
if (!Uninterruptible.Utils.inliningAllowed(caller, callee)) {
236236
return false;
237237
}
238-
if (callee.getReturnsAllInstantiatedTypes()) {
238+
if (callee.hasOpaqueReturn()) {
239239
/*
240-
* When a callee returns all instantiated types then it cannot be inlined. Inlining the
241-
* method would expose the method's return values instead of treating it as an
242-
* AllInstantiatedTypeFlow.
240+
* When a callee has opaque return then it cannot be inlined. Inlining the method would
241+
* expose the method's return values, which might change e.g. due to later
242+
* intrinsification of the invoke.
243243
*/
244244
return false;
245245
}

0 commit comments

Comments
 (0)