From d557cf606f52ae0197050d6066c88f5c9cbc1f4b Mon Sep 17 00:00:00 2001 From: d-kozak Date: Tue, 8 Oct 2024 13:36:55 +0200 Subject: [PATCH] Typeflow.getState() cleanup --- .../graal/pointsto/PointsToAnalysis.java | 12 +++-- .../flow/AbstractSpecialInvokeTypeFlow.java | 6 ++- .../flow/AbstractStaticInvokeTypeFlow.java | 2 +- .../flow/AbstractVirtualInvokeTypeFlow.java | 6 ++- .../flow/ActualParameterTypeFlow.java | 6 +-- .../pointsto/flow/ActualReturnTypeFlow.java | 4 +- .../pointsto/flow/ArrayCopyTypeFlow.java | 2 +- .../pointsto/flow/ArrayElementsTypeFlow.java | 2 +- .../flow/BooleanPrimitiveCheckTypeFlow.java | 10 ++-- .../graal/pointsto/flow/BoxTypeFlow.java | 2 +- .../flow/CallSiteSensitiveMethodTypeFlow.java | 2 +- .../graal/pointsto/flow/CloneTypeFlow.java | 12 ++++- .../graal/pointsto/flow/ConditionalFlow.java | 16 +++--- .../flow/ConstantPrimitiveSourceTypeFlow.java | 2 +- .../graal/pointsto/flow/ConstantTypeFlow.java | 2 +- .../flow/ContextInsensitiveFieldTypeFlow.java | 2 +- .../flow/DynamicNewInstanceTypeFlow.java | 14 ++++- .../graal/pointsto/flow/FieldTypeFlow.java | 2 +- .../pointsto/flow/FormalParamTypeFlow.java | 2 +- .../pointsto/flow/FormalReceiverTypeFlow.java | 2 +- .../pointsto/flow/FormalReturnTypeFlow.java | 2 +- .../pointsto/flow/LoadFieldTypeFlow.java | 4 +- .../graal/pointsto/flow/MergeTypeFlow.java | 2 +- .../graal/pointsto/flow/MethodTypeFlow.java | 6 ++- .../pointsto/flow/MethodTypeFlowBuilder.java | 5 +- .../pointsto/flow/NewInstanceTypeFlow.java | 2 +- .../pointsto/flow/NullCheckTypeFlow.java | 2 +- .../pointsto/flow/OffsetLoadTypeFlow.java | 4 +- .../pointsto/flow/OffsetStoreTypeFlow.java | 4 +- .../flow/PrimitiveFilterTypeFlow.java | 10 ++-- .../graal/pointsto/flow/ProxyTypeFlow.java | 8 ++- .../graal/pointsto/flow/SourceTypeFlow.java | 9 ++-- .../pointsto/flow/StoreFieldTypeFlow.java | 4 +- .../oracle/graal/pointsto/flow/TypeFlow.java | 52 +++++++++++++++++-- .../graal/pointsto/reports/ReportUtils.java | 8 +-- .../pointsto/results/StrengthenGraphs.java | 7 ++- .../pointsto/typestate/PointsToStats.java | 4 +- .../hosted/dashboard/PointsToBreakdown.java | 4 +- 38 files changed, 167 insertions(+), 78 deletions(-) diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java index 938a2d448413..029170707d77 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java @@ -210,7 +210,9 @@ public void forceUnsafeUpdate(AnalysisField field) { * update; an update of the receiver object flow will trigger an updated of the * observers, i.e., of the unsafe load. */ - this.postFlow(unsafeLoad.receiver()); + if (unsafeLoad.receiver().isFlowEnabled()) { + this.postFlow(unsafeLoad.receiver()); + } } // force update of the unsafe stores @@ -223,7 +225,9 @@ public void forceUnsafeUpdate(AnalysisField field) { * update; an update of the receiver object flow will trigger an updated of the * observers, i.e., of the unsafe store. */ - this.postFlow(unsafeStore.receiver()); + if (unsafeStore.receiver().isFlowEnabled()) { + this.postFlow(unsafeStore.receiver()); + } } } @@ -563,6 +567,7 @@ public interface TypeFlowRunnable extends DebugContextRunnable { } public void postFlow(final TypeFlow operation) { + assert operation.isFlowEnabled() : "Only enabled flows should be updated: " + operation; if (operation.inQueue) { return; } @@ -766,7 +771,8 @@ public void addCompleted(DebugContextRunnable r, long nanos) { TypeFlow tf = ((TypeFlowRunnable) r).getTypeFlow(); String source = String.valueOf(tf.getSource()); System.out.format("LONG RUNNING %.2f %s %x %s state %s %x uses %d observers %d%n", (double) nanos / 1_000_000_000, ClassUtil.getUnqualifiedName(tf.getClass()), - System.identityHashCode(tf), source, PointsToStats.asString(tf.getState()), System.identityHashCode(tf.getState()), tf.getUses().size(), tf.getObservers().size()); + System.identityHashCode(tf), source, PointsToStats.asString(tf.getRawState()), System.identityHashCode(tf.getRawState()), tf.getUses().size(), + tf.getObservers().size()); } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AbstractSpecialInvokeTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AbstractSpecialInvokeTypeFlow.java index a482cd97dc34..cf0bc52ddf44 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AbstractSpecialInvokeTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AbstractSpecialInvokeTypeFlow.java @@ -47,7 +47,9 @@ protected AbstractSpecialInvokeTypeFlow(PointsToAnalysis bb, MethodFlowsGraph me @Override protected void onFlowEnabled(PointsToAnalysis bb) { - bb.postTask(() -> onObservedUpdate(bb)); + if (getReceiver().isFlowEnabled()) { + bb.postTask(() -> onObservedUpdate(bb)); + } } @Override @@ -71,7 +73,7 @@ public void onObservedSaturated(PointsToAnalysis bb, TypeFlow observed) { @Override public String toString() { - return "SpecialInvoke<" + targetMethod.format("%h.%n") + ">" + ":" + getState(); + return "SpecialInvoke<" + targetMethod.format("%h.%n") + ">" + ":" + getStateDescription(); } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AbstractStaticInvokeTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AbstractStaticInvokeTypeFlow.java index 0198e99e379e..ef79ececde67 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AbstractStaticInvokeTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AbstractStaticInvokeTypeFlow.java @@ -43,6 +43,6 @@ protected AbstractStaticInvokeTypeFlow(PointsToAnalysis bb, MethodFlowsGraph met @Override public String toString() { - return "StaticInvoke<" + targetMethod.format("%h.%n") + ">" + ":" + getState(); + return "StaticInvoke<" + targetMethod.format("%h.%n") + ">" + ":" + getStateDescription(); } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AbstractVirtualInvokeTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AbstractVirtualInvokeTypeFlow.java index fc2cb080e39f..e91f529efe24 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AbstractVirtualInvokeTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/AbstractVirtualInvokeTypeFlow.java @@ -89,7 +89,9 @@ public final boolean isDirectInvoke() { @Override protected void onFlowEnabled(PointsToAnalysis bb) { - bb.postTask(() -> onObservedUpdate(bb)); + if (getReceiver().isFlowEnabled()) { + bb.postTask(() -> onObservedUpdate(bb)); + } } @Override @@ -129,6 +131,6 @@ public Collection getCalleesForReturnLinking() { @Override public String toString() { - return "VirtualInvoke<" + targetMethod.format("%h.%n") + ">" + ":" + getState(); + return "VirtualInvoke<" + targetMethod.format("%h.%n") + ">" + ":" + getStateDescription(); } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ActualParameterTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ActualParameterTypeFlow.java index 9d82a31907c3..a1588f806e8b 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ActualParameterTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ActualParameterTypeFlow.java @@ -24,10 +24,10 @@ */ package com.oracle.graal.pointsto.flow; -import jdk.graal.compiler.nodes.ValueNode; - import com.oracle.graal.pointsto.meta.AnalysisType; +import jdk.graal.compiler.nodes.ValueNode; + /** * A sink type flow for the context insensitive invoke used to link in parameters in each caller * context. @@ -39,6 +39,6 @@ public ActualParameterTypeFlow(AnalysisType declaredType) { @Override public String toString() { - return "ActualParameter<" + getState() + '>'; + return "ActualParameter<" + getStateDescription() + '>'; } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ActualReturnTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ActualReturnTypeFlow.java index fac14f47f0fc..0598f22fbfb9 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ActualReturnTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ActualReturnTypeFlow.java @@ -53,7 +53,7 @@ public TypeFlow copy(PointsToAnalysis bb, MethodFlowsGraph met @Override public String toString() { - return "ActualReturn<" + getState() + '>'; + return "ActualReturn<" + getStateDescription() + '>'; } public void setInvokeFlow(InvokeTypeFlow invokeFlow) { @@ -68,7 +68,7 @@ public InvokeTypeFlow invokeFlow() { public String format(boolean withState, boolean withSource) { return "Actual return of call to " + invokeFlow.targetMethod.format("%H.%n(%p)") + (withSource ? " at " + formatSource() : "") + - (withState ? " with state <" + getState() + ">" : ""); + (withState ? " with state <" + getStateDescription() + ">" : ""); } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ArrayCopyTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ArrayCopyTypeFlow.java index 59eec8415a9b..082a49c6e9c2 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ArrayCopyTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ArrayCopyTypeFlow.java @@ -141,6 +141,6 @@ public TypeFlow destination() { @Override public String toString() { - return "ArrayCopyTypeFlow<" + getState() + ">"; + return "ArrayCopyTypeFlow<" + getStateDescription() + ">"; } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ArrayElementsTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ArrayElementsTypeFlow.java index 1ab883d65253..3cdfaeb06a21 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ArrayElementsTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ArrayElementsTypeFlow.java @@ -85,7 +85,7 @@ public AnalysisObject object() { @Override public String toString() { - return "MixedElementsFlow<" + source.getName() + "\n" + getState() + ">"; + return "MixedElementsFlow<" + source.getName() + "\n" + getStateDescription() + ">"; } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/BooleanPrimitiveCheckTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/BooleanPrimitiveCheckTypeFlow.java index 92327796d25d..ea2f4bad2a80 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/BooleanPrimitiveCheckTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/BooleanPrimitiveCheckTypeFlow.java @@ -61,7 +61,7 @@ public TypeFlow copy(PointsToAnalysis bb, MethodFlowsGraph met @Override public boolean addState(PointsToAnalysis bb, TypeState add) { - return super.addState(bb, eval()); + return super.addState(bb, eval(bb)); } @Override @@ -70,7 +70,7 @@ protected void onInputSaturated(PointsToAnalysis bb, TypeFlow input) { * If an input saturated, it does not mean that the condition has to always saturate as * well, e.g. Any == {5} will return {5}. */ - super.addState(bb, eval()); + super.addState(bb, eval(bb)); } /** @@ -78,9 +78,9 @@ protected void onInputSaturated(PointsToAnalysis bb, TypeFlow input) { * * @return can be either empty, true, false, or any. */ - public TypeState eval() { - var leftState = left.isSaturated() ? TypeState.anyPrimitiveState() : left.getState(); - var rightState = right.isSaturated() ? TypeState.anyPrimitiveState() : right.getState(); + public TypeState eval(PointsToAnalysis bb) { + var leftState = left.getOutputState(bb); + var rightState = right.getOutputState(bb); if (leftState.isEmpty() || rightState.isEmpty()) { return TypeState.forEmpty(); } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/BoxTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/BoxTypeFlow.java index 872c7ab3f474..6e9d3b0edec9 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/BoxTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/BoxTypeFlow.java @@ -46,7 +46,7 @@ public TypeFlow copy(PointsToAnalysis bb, MethodFlowsGraph met @Override public String toString() { - return "BoxFlow<" + getState() + ">"; + return "BoxFlow<" + getStateDescription() + ">"; } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/CallSiteSensitiveMethodTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/CallSiteSensitiveMethodTypeFlow.java index c016db0c0574..c048ed22751e 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/CallSiteSensitiveMethodTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/CallSiteSensitiveMethodTypeFlow.java @@ -117,7 +117,7 @@ public TypeState foldTypeFlow(PointsToAnalysis bb, TypeFlow originalTypeFlow) } if (originalTypeFlow instanceof FieldTypeFlow || originalTypeFlow instanceof ArrayElementsTypeFlow) { // field and array flows are not call site sensitive and thus not cloneable - return originalTypeFlow.state; + return originalTypeFlow.getState(); } TypeState result = TypeState.forEmpty(); for (MethodFlowsGraph methodFlows : clonedMethodFlows.values()) { diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/CloneTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/CloneTypeFlow.java index 2384a11c7c6c..c653d73e52e4 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/CloneTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/CloneTypeFlow.java @@ -61,8 +61,18 @@ public TypeFlow copy(PointsToAnalysis bb, MethodFlowsGraph met return new CloneTypeFlow(bb, this, methodFlows, allocContext); } + @Override + protected void onFlowEnabled(PointsToAnalysis bb) { + if (input.isFlowEnabled()) { + bb.postTask(() -> onObservedUpdate(bb)); + } + } + @Override public void onObservedUpdate(PointsToAnalysis bb) { + if (!isFlowEnabled()) { + return; + } /* The input state has changed, clone its objects. */ TypeState inputState = input.getState(); @@ -73,7 +83,7 @@ public void onObservedUpdate(PointsToAnalysis bb) { * encapsulate the location of the cloning. From the point of view of the analysis a clone * flow is a source. */ - TypeState resultState = bb.analysisPolicy().cloneState(bb, state, inputState, source, allocationContext); + TypeState resultState = bb.analysisPolicy().cloneState(bb, getState(), inputState, source, allocationContext); /* Update the clone flow state. */ addState(bb, resultState); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ConditionalFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ConditionalFlow.java index 2c541020ccff..0f6f8814396f 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ConditionalFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ConditionalFlow.java @@ -70,22 +70,24 @@ public TypeFlow copy(PointsToAnalysis bb, MethodFlowsGraph met @Override public void onObservedUpdate(PointsToAnalysis bb) { - addState(bb, condition.getState()); + addState(bb, condition.getOutputState(bb)); } @Override public void onObservedSaturated(PointsToAnalysis bb, TypeFlow observed) { /* If the condition is already saturated, merge both inputs. */ - super.addState(bb, TypeState.forUnion(bb, trueValue.getState(), falseValue.getState())); + super.addState(bb, TypeState.forUnion(bb, trueValue.getOutputState(bb), falseValue.getOutputState(bb))); } @Override public boolean addState(PointsToAnalysis bb, TypeState add) { + TypeState trueState = trueValue.getOutputState(bb); + TypeState falseState = falseValue.getOutputState(bb); if (condition.isSaturated()) { /* If the condition is already saturated, merge both inputs. */ - return super.addState(bb, TypeState.forUnion(bb, trueValue.getState(), falseValue.getState())); + return super.addState(bb, TypeState.forUnion(bb, trueState, falseState)); } - var conditionValue = condition.getState(); + var conditionValue = condition.getOutputState(bb); if (conditionValue.isEmpty()) { /* If the condition is empty, do not produce any output yet. */ return false; @@ -94,11 +96,11 @@ public boolean addState(PointsToAnalysis bb, TypeState add) { var canBeTrue = prim.canBeTrue(); var canBeFalse = prim.canBeFalse(); if (canBeTrue && !canBeFalse) { - return super.addState(bb, trueValue.getState()); + return super.addState(bb, trueState); } else if (!canBeTrue && canBeFalse) { - return super.addState(bb, falseValue.getState()); + return super.addState(bb, falseState); } - return super.addState(bb, TypeState.forUnion(bb, trueValue.getState(), falseValue.getState())); + return super.addState(bb, TypeState.forUnion(bb, trueState, falseState)); } throw AnalysisError.shouldNotReachHere("Unexpected non-primitive type state of the condition: " + conditionValue + ", at flow " + this); } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ConstantPrimitiveSourceTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ConstantPrimitiveSourceTypeFlow.java index ddf4024a9f0d..3b547a4e89fc 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ConstantPrimitiveSourceTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ConstantPrimitiveSourceTypeFlow.java @@ -37,7 +37,7 @@ public ConstantPrimitiveSourceTypeFlow(BytecodePosition source, AnalysisType typ } public ConstantPrimitiveSourceTypeFlow(ConstantPrimitiveSourceTypeFlow original, MethodFlowsGraph methodFlows) { - super(original, methodFlows, original.getState()); + super(original, methodFlows, original.getRawState()); } @Override diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ConstantTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ConstantTypeFlow.java index ebdb65a2f16e..b9bcf93d8c40 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ConstantTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ConstantTypeFlow.java @@ -73,6 +73,6 @@ public boolean needsInitialization() { @Override public String toString() { - return "ConstantFlow<" + getState() + ">"; + return "ConstantFlow<" + getStateDescription() + ">"; } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ContextInsensitiveFieldTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ContextInsensitiveFieldTypeFlow.java index 645b51d08edc..c1fae54bf7c1 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ContextInsensitiveFieldTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ContextInsensitiveFieldTypeFlow.java @@ -56,7 +56,7 @@ public boolean addState(PointsToAnalysis bb, TypeState add) { @Override public String toString() { - return "ContextInsensitiveFieldTypeFlow<" + source.format("%h.%n") + System.lineSeparator() + getState() + ">"; + return "ContextInsensitiveFieldTypeFlow<" + source.format("%h.%n") + System.lineSeparator() + getStateDescription() + ">"; } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/DynamicNewInstanceTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/DynamicNewInstanceTypeFlow.java index 63df237c007b..34bc03f8e1de 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/DynamicNewInstanceTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/DynamicNewInstanceTypeFlow.java @@ -77,11 +77,21 @@ public boolean needsInitialization() { return true; } + @Override + protected void onFlowEnabled(PointsToAnalysis bb) { + if (newTypeFlow.isFlowEnabled()) { + bb.postTask(() -> onObservedUpdate(bb)); + } + } + @Override public void onObservedUpdate(PointsToAnalysis bb) { + if (!isFlowEnabled()) { + return; + } /* The state of the new type provider has changed. */ TypeState newTypeState = newTypeFlow.getState(); - TypeState updateState = bb.analysisPolicy().dynamicNewInstanceState(bb, state, newTypeState, source, allocationContext); + TypeState updateState = bb.analysisPolicy().dynamicNewInstanceState(bb, getState(), newTypeState, source, allocationContext); addState(bb, updateState); } @@ -108,6 +118,6 @@ public boolean canSaturate() { @Override public String toString() { - return "DynamicNewInstanceFlow<" + getState() + ">"; + return "DynamicNewInstanceFlow<" + getStateDescription() + ">"; } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FieldTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FieldTypeFlow.java index f56aaa40790a..3724d70c579e 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FieldTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FieldTypeFlow.java @@ -98,7 +98,7 @@ public FieldFilterTypeFlow filterFlow(PointsToAnalysis bb) { @Override public String toString() { - return "FieldFlow<" + source.format("%h.%n") + System.lineSeparator() + getState() + ">"; + return "FieldFlow<" + source.format("%h.%n") + System.lineSeparator() + getStateDescription() + ">"; } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalParamTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalParamTypeFlow.java index 3b9b11d07a04..3a972ccf92a1 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalParamTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalParamTypeFlow.java @@ -69,7 +69,7 @@ public int position() { public String format(boolean withState, boolean withSource) { return "Parameter " + position + " of " + method().format("%H.%n(%p)") + (withSource ? " at " + formatSource() : "") + - (withState ? " with state <" + getState() + ">" : ""); + (withState ? " with state <" + getStateDescription() + ">" : ""); } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalReceiverTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalReceiverTypeFlow.java index 252a841f8f62..fb7eaad20fbc 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalReceiverTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalReceiverTypeFlow.java @@ -90,7 +90,7 @@ public boolean addReceiverState(PointsToAnalysis bb, TypeState add) { public String format(boolean withState, boolean withSource) { return "Formal receiver of " + method().format("%H.%n(%p)") + (withSource ? " at " + formatSource() : "") + - (withState ? " with state <" + getState() + ">" : ""); + (withState ? " with state <" + getStateDescription() + ">" : ""); } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalReturnTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalReturnTypeFlow.java index 88ec0eb06e24..26ce11f7cba7 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalReturnTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalReturnTypeFlow.java @@ -68,6 +68,6 @@ public TypeFlow copy(PointsToAnalysis bb, MethodFlowsGraph met public String format(boolean withState, boolean withSource) { return "Formal return from " + method().format("%H.%n(%p)") + (withSource ? " at " + formatSource() : "") + - (withState ? " with state <" + getState() + ">" : ""); + (withState ? " with state <" + getStateDescription() + ">" : ""); } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/LoadFieldTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/LoadFieldTypeFlow.java index c5dd681f3236..7b45b6bc6afd 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/LoadFieldTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/LoadFieldTypeFlow.java @@ -81,7 +81,7 @@ public boolean needsInitialization() { @Override public String toString() { - return "LoadStaticFieldTypeFlow<" + getState() + ">"; + return "LoadStaticFieldTypeFlow<" + getStateDescription() + ">"; } } @@ -163,7 +163,7 @@ protected void onSaturated() { @Override public String toString() { - return "LoadInstanceFieldTypeFlow<" + getState() + ">"; + return "LoadInstanceFieldTypeFlow<" + getStateDescription() + ">"; } } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MergeTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MergeTypeFlow.java index a735c2818890..5e8e7dd01d3e 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MergeTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MergeTypeFlow.java @@ -46,6 +46,6 @@ public TypeFlow copy(PointsToAnalysis bb, MethodFlowsGraph met @Override public String toString() { - return "MergeTypeFlow<" + getState() + ">"; + return "MergeTypeFlow<" + getStateDescription() + ">"; } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlow.java index 255cf7887e0d..8048d4785852 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlow.java @@ -248,7 +248,11 @@ public boolean isSaturated(@SuppressWarnings("unused") PointsToAnalysis bb, Type * Return the type state of the original flow. */ public TypeState foldTypeFlow(@SuppressWarnings("unused") PointsToAnalysis bb, TypeFlow originalTypeFlow) { - return originalTypeFlow == null ? null : originalTypeFlow.getState(); + if (originalTypeFlow == null) { + return null; + } + assert !originalTypeFlow.isSaturated() : "Saturated flows should not be accessed here: " + originalTypeFlow; + return originalTypeFlow.getState(); } /** diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java index 4b4089a54d53..2dd06112e704 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/MethodTypeFlowBuilder.java @@ -550,6 +550,7 @@ private void insertPlaceholderParamAndReturnFlows() { } else { parameter = new FormalParamTypeFlow(position, paramType, index); } + parameter.enableFlow(bb); flowsGraph.setParameter(index, parameter); } } @@ -562,7 +563,9 @@ private void insertPlaceholderParamAndReturnFlows() { * We want to determine whether void methods can return, so we need to create * FormalReturnTypeFlow for them. */ - flowsGraph.setReturnFlow(new FormalReturnTypeFlow(position, returnType)); + FormalReturnTypeFlow returnFlow = new FormalReturnTypeFlow(position, returnType); + returnFlow.enableFlow(bb); + flowsGraph.setReturnFlow(returnFlow); } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/NewInstanceTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/NewInstanceTypeFlow.java index a62d7eec9336..9d9002e712ab 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/NewInstanceTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/NewInstanceTypeFlow.java @@ -149,6 +149,6 @@ private AnalysisObject createHeapObject(PointsToAnalysis bb, AnalysisContext obj @Override public String toString() { - return "NewInstanceFlow<" + getState() + ">"; + return "NewInstanceFlow<" + getStateDescription() + ">"; } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/NullCheckTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/NullCheckTypeFlow.java index 4651c87d150f..2665c6aaee7b 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/NullCheckTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/NullCheckTypeFlow.java @@ -72,7 +72,7 @@ public TypeState filter(PointsToAnalysis bb, TypeState newState) { @Override public String toString() { - return "NullCheckTypeFlow<" + (getDeclaredType() != null ? getDeclaredType().toJavaName(false) : "null") + " : " + getState() + ">"; + return "NullCheckTypeFlow<" + (getDeclaredType() != null ? getDeclaredType().toJavaName(false) : "null") + " : " + getStateDescription() + ">"; } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/OffsetLoadTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/OffsetLoadTypeFlow.java index ca3c6d4713c6..928e9fd2e257 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/OffsetLoadTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/OffsetLoadTypeFlow.java @@ -144,7 +144,7 @@ public TypeState filter(PointsToAnalysis bb, TypeState newState) { @Override public String toString() { - return "LoadIndexedTypeFlow<" + getState() + ">"; + return "LoadIndexedTypeFlow<" + getStateDescription() + ">"; } } @@ -246,7 +246,7 @@ public void onObservedUpdate(PointsToAnalysis bb) { @Override public String toString() { - return "UnsafeLoadTypeFlow<" + getState() + ">"; + return "UnsafeLoadTypeFlow<" + getStateDescription() + ">"; } } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/OffsetStoreTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/OffsetStoreTypeFlow.java index b01f8da156ec..c83377909d05 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/OffsetStoreTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/OffsetStoreTypeFlow.java @@ -169,7 +169,7 @@ public void onObservedSaturated(PointsToAnalysis bb, TypeFlow observed) { @Override public String toString() { - return "StoreIndexedTypeFlow<" + getState() + ">"; + return "StoreIndexedTypeFlow<" + getStateDescription() + ">"; } } @@ -294,7 +294,7 @@ public void onObservedSaturated(PointsToAnalysis bb, TypeFlow observed) { @Override public String toString() { - return "UnsafeStoreTypeFlow<" + getState() + ">"; + return "UnsafeStoreTypeFlow<" + getStateDescription() + ">"; } } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/PrimitiveFilterTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/PrimitiveFilterTypeFlow.java index 0045fb47e211..956559fc370c 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/PrimitiveFilterTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/PrimitiveFilterTypeFlow.java @@ -65,7 +65,7 @@ public TypeFlow copy(PointsToAnalysis bb, MethodFlowsGraph met @Override public boolean addState(PointsToAnalysis bb, TypeState add) { - return super.addState(bb, eval()); + return super.addState(bb, eval(bb)); } @Override @@ -74,15 +74,15 @@ protected void onInputSaturated(PointsToAnalysis bb, TypeFlow input) { * If an input saturated, it does not mean that the condition has to always saturate as * well, e.g. Any == 5 still returns 5. */ - super.addState(bb, eval()); + super.addState(bb, eval(bb)); } /** * Filters the type state of left using condition and right. */ - private TypeState eval() { - var leftState = left.isSaturated() ? TypeState.anyPrimitiveState() : left.getState(); - var rightState = right.isSaturated() ? TypeState.anyPrimitiveState() : right.getState(); + private TypeState eval(PointsToAnalysis bb) { + var leftState = left.getOutputState(bb); + var rightState = right.getOutputState(bb); assert leftState.isPrimitive() || leftState.isEmpty() : left; assert rightState.isPrimitive() || rightState.isEmpty() : right; return TypeState.filter(leftState, comparison, rightState); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ProxyTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ProxyTypeFlow.java index 2b558c4b404c..cd9c1ab15ee4 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ProxyTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ProxyTypeFlow.java @@ -24,6 +24,7 @@ */ package com.oracle.graal.pointsto.flow; +import com.oracle.graal.pointsto.BigBang; import com.oracle.graal.pointsto.PointsToAnalysis; import com.oracle.graal.pointsto.typestate.TypeState; import com.oracle.graal.pointsto.util.AnalysisError; @@ -69,7 +70,12 @@ public void update(PointsToAnalysis bb) { } @Override - public TypeState getState() { + public TypeState getOutputState(BigBang bb) { + throw AnalysisError.shouldNotReachHere("should not be reached during analysis"); + } + + @Override + public TypeState getRawState() { throw AnalysisError.shouldNotReachHere("should not be reached during analysis"); } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/SourceTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/SourceTypeFlow.java index 8a20c867cd8b..28222a4d8846 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/SourceTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/SourceTypeFlow.java @@ -24,14 +24,13 @@ */ package com.oracle.graal.pointsto.flow; -import jdk.graal.compiler.nodes.extended.BytecodeExceptionNode; -import jdk.graal.compiler.nodes.extended.JavaReadNode; - import com.oracle.graal.pointsto.PointsToAnalysis; import com.oracle.graal.pointsto.meta.AnalysisType; import com.oracle.graal.pointsto.typestate.TypeState; import com.oracle.graal.pointsto.util.AnalysisError; +import jdk.graal.compiler.nodes.extended.BytecodeExceptionNode; +import jdk.graal.compiler.nodes.extended.JavaReadNode; import jdk.vm.ci.code.BytecodePosition; /** @@ -59,7 +58,7 @@ public SourceTypeFlow(BytecodePosition position, AnalysisType type, boolean canB } public SourceTypeFlow(SourceTypeFlow original, MethodFlowsGraph methodFlows) { - super(original, methodFlows, original.getState().canBeNull() ? TypeState.forNull() : TypeState.forEmpty()); + super(original, methodFlows, original.getRawState().canBeNull() ? TypeState.forNull() : TypeState.forEmpty()); } @Override @@ -100,6 +99,6 @@ public boolean canSaturate() { @Override public String toString() { - return "SourceFlow<" + getState() + ">"; + return "SourceFlow<" + getStateDescription() + ">"; } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/StoreFieldTypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/StoreFieldTypeFlow.java index ed4a895517e6..a309cbe6740f 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/StoreFieldTypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/StoreFieldTypeFlow.java @@ -92,7 +92,7 @@ public boolean needsInitialization() { @Override public String toString() { - return "StoreStaticFieldTypeFlow<" + getState() + ">"; + return "StoreStaticFieldTypeFlow<" + getStateDescription() + ">"; } } @@ -199,7 +199,7 @@ public void onObservedSaturated(PointsToAnalysis bb, TypeFlow observed) { @Override public String toString() { - return "StoreInstanceFieldTypeFlow<" + getState() + ">"; + return "StoreInstanceFieldTypeFlow<" + getStateDescription() + ">"; } } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/TypeFlow.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/TypeFlow.java index 41981c8bcee8..5ad6ae5d1052 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/TypeFlow.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/TypeFlow.java @@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import com.oracle.graal.pointsto.BigBang; import com.oracle.graal.pointsto.PointsToAnalysis; import com.oracle.graal.pointsto.api.PointstoOptions; import com.oracle.graal.pointsto.meta.AnalysisMethod; @@ -107,7 +108,7 @@ public abstract class TypeFlow { */ protected final AnalysisType declaredType; - protected volatile TypeState state; + private volatile TypeState state; /** Nonzero iff this flow was enabled by its predicate. */ @SuppressWarnings("unused") private volatile int isEnabled; @@ -412,15 +413,43 @@ public boolean isContextInsensitive() { return false; } - public AnalysisType getDeclaredType() { - return declaredType; + /** + * Returns the type state that is currently propagated along the use edges out of this flow. For + * disabled flows, this value is always empty. For saturated flows, this value will be + * AllInstantiated/AnyPrimitive. This is a helper method that should be used when the user is + * not sure what is the state of this flow. If it is known from the context that this flow is + * already enabled, use {@link TypeFlow#getState} + */ + public TypeState getOutputState(BigBang bb) { + if (!isFlowEnabled()) { + return TypeState.forEmpty(); + } else if (isSaturated() && declaredType != null) { + return declaredType.getTypeFlow(bb, true).state; + } + return state; } + /** + * Returns the type state of the flow. Should be used most of the time, but only for flows that + * are already enabled. + */ public TypeState getState() { - /* GR-58690 - We should not query the type state of disabled flows. */ + assert isFlowEnabled() : "This method should be used only for enabled flows: " + this; + return state; + } + + /** + * Returns the raw type state of this flow regardless of its disabled/enabled/saturation status. + * Use this only when you know what you are doing, e.g. for logging. + */ + public TypeState getRawState() { return state; } + public AnalysisType getDeclaredType() { + return declaredType; + } + public boolean isAllInstantiated() { return this instanceof AllInstantiatedTypeFlow; } @@ -1035,7 +1064,20 @@ public String formatSource() { } public String format(boolean withState, boolean withSource) { - return ClassUtil.getUnqualifiedName(getClass()) + (withSource ? " at " + formatSource() : "") + (withState ? " with state <" + getState() + '>' : ""); + return ClassUtil.getUnqualifiedName(getClass()) + (withSource ? " at " + formatSource() : "") + (withState ? " with state <" + getStateDescription() + '>' : ""); + } + + /** + * Returns the string representation of the state of this flow, including + * disabled/enabled/saturation status. Meant mainly for logging and debugging. + */ + protected final String getStateDescription() { + if (!isFlowEnabled()) { + return "DISABLED: " + state; + } else if (isSaturated()) { + return "SATURATED: " + state; + } + return state.toString(); } @Override diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/ReportUtils.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/ReportUtils.java index 280e10433dad..21e38e9e6751 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/ReportUtils.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/ReportUtils.java @@ -298,22 +298,22 @@ public static String typePropagationTrace(PointsToAnalysis bb, TypeFlow flow, public static String typePropagationTrace(PointsToAnalysis bb, TypeFlow flow, AnalysisType type, String indent) { if (bb.trackTypeFlowInputs()) { StringBuilder msg = new StringBuilder(String.format("Propagation trace through type flows for type %s: %n", type.toJavaName())); - followInput(flow, type, indent, new HashSet<>(), msg); + followInput(bb, flow, type, indent, new HashSet<>(), msg); return msg.toString(); } else { return String.format("To print the propagation trace through type flows for type %s set the -H:+TrackInputFlows option. %n", type.toJavaName()); } } - private static void followInput(TypeFlow flow, AnalysisType type, String indent, HashSet> seen, StringBuilder msg) { + private static void followInput(PointsToAnalysis bb, TypeFlow flow, AnalysisType type, String indent, HashSet> seen, StringBuilder msg) { seen.add(flow); if (flow instanceof AllInstantiatedTypeFlow) { msg.append(String.format("AllInstantiated(%s)%n", flow.getDeclaredType().toJavaName(true))); } else { msg.append(String.format("%sat %s: %s%n", indent, flow.formatSource(), flow.format(false, false))); for (TypeFlow input : flow.getInputs()) { - if (!seen.contains(input) && input.getState().containsType(type)) { - followInput(input, type, indent, seen, msg); + if (!seen.contains(input) && input.getOutputState(bb).containsType(type)) { + followInput(bb, input, type, indent, seen, msg); break; } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java index 8fa695ec560a..7418ba9c607c 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java @@ -803,6 +803,9 @@ private void devirtualizeInvoke(AnalysisMethod singleCallee, Invoke invoke) { private boolean isUnreachable(Node branch) { TypeFlow branchFlow = getNodeFlow(branch); if (branchFlow != null && !methodFlow.isSaturated(((PointsToAnalysis) bb), branchFlow)) { + if (!branchFlow.isFlowEnabled()) { + return true; + } TypeState typeState = methodFlow.foldTypeFlow((PointsToAnalysis) bb, branchFlow); if (branchFlow.isPrimitiveFlow()) { /* @@ -811,7 +814,7 @@ private boolean isUnreachable(Node branch) { */ assert branchFlow instanceof PrimitiveFilterTypeFlow : "Unexpected type of primitive flow encountered as branch predicate: " + branchFlow; } - return !branchFlow.isFlowEnabled() || typeState.isEmpty(); + return typeState.isEmpty(); } return false; } @@ -893,7 +896,7 @@ private Object strengthenStampFromTypeFlow(ValueNode node, TypeFlow nodeFlow, */ boolean hasUsages = node.usages().filter(n -> !(n instanceof FrameState)).isNotEmpty(); - TypeState nodeTypeState = methodFlow.foldTypeFlow((PointsToAnalysis) bb, nodeFlow); + TypeState nodeTypeState = nodeFlow.isFlowEnabled() ? methodFlow.foldTypeFlow((PointsToAnalysis) bb, nodeFlow) : TypeState.forEmpty(); if (hasUsages && allowConstantFolding && !nodeTypeState.canBeNull()) { JavaConstant constantValue = nodeTypeState.asConstant(); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/PointsToStats.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/PointsToStats.java index 13fc569cdea7..cb4c1427581c 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/PointsToStats.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/typestate/PointsToStats.java @@ -296,8 +296,8 @@ private static void reportTypeFlowStats(BufferedWriter out) { TypeFlowStats stats = e.getValue(); doWrite(out, String.format("%-35s\t%-10d\t%-10d\t%-10b\t%-10b\t%-10d\t%-10d\t%-10d\t%-10s\t%-10d\t%10d\t%10d\t%10s%n", - asString(flow), stateToId.get(flow.getState()), objectsCount(flow.getState()), - flow.getState().canBeNull(), flow.isClone(), + asString(flow), stateToId.get(flow.getRawState()), objectsCount(flow.getRawState()), + flow.getRawState().canBeNull(), flow.isClone(), flow.getUses().size(), flow.getObservers().size(), flow.getUses().size() + flow.getObservers().size(), retainReson.getOrDefault(flow, ""), stats.queuedUpdatesCount(), stats.successfulUpdatesCount(), stats.allUpdatesCount(), diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/PointsToBreakdown.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/PointsToBreakdown.java index f70fae0fcaaf..66770332b009 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/PointsToBreakdown.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/dashboard/PointsToBreakdown.java @@ -587,12 +587,12 @@ private void serializeTypeFlow(BigBang bb, TypeFlow flow) { flowWrapper.calleeNames.add(callee.getQualifiedName()); } } else if (flow instanceof NewInstanceTypeFlow || flow instanceof DynamicNewInstanceTypeFlow) { - flowWrapper.types = serializeTypeState(bb, flow.getState()); + flowWrapper.types = serializeTypeState(bb, flow.getRawState()); } else if (flow instanceof LoadFieldTypeFlow.LoadInstanceFieldTypeFlow || flow instanceof LoadFieldTypeFlow.LoadStaticFieldTypeFlow) { LoadFieldTypeFlow loadFlow = (LoadFieldTypeFlow) flow; flowWrapper.qualifiedName = fieldName(loadFlow.field()); } else if (flow instanceof StoreFieldTypeFlow.StoreInstanceFieldTypeFlow || flow instanceof StoreFieldTypeFlow.StoreStaticFieldTypeFlow) { - TypeState typeState = flow.getState(); + TypeState typeState = flow.getRawState(); flowWrapper.types = serializeTypeState(bb, typeState); StoreFieldTypeFlow storeFlow = (StoreFieldTypeFlow) flow; flowWrapper.qualifiedName = fieldName(storeFlow.field());