@@ -742,38 +742,53 @@ public static ValueNode arrayLength(ValueNode value, FindLengthMode mode, Consta
742742 return arrayLength (value , mode , constantReflection , null );
743743 }
744744
745+ /**
746+ * Filters out non-constant results when requested.
747+ */
748+ private static ValueNode filterArrayLengthResult (ValueNode result , boolean allowOnlyConstantResult ) {
749+ return result == null || !allowOnlyConstantResult || result .isConstant () ? result : null ;
750+ }
751+
745752 private static ValueNode arrayLength (ValueNode value , FindLengthMode mode , ConstantReflectionProvider constantReflection , EconomicMap <ValueNode , ValueNode > visitedPhiInputs ) {
746753 Objects .requireNonNull (mode );
747754
748755 EconomicMap <ValueNode , ValueNode > visitedPhiInputMap = visitedPhiInputs ;
749756 ValueNode current = value ;
750757 StructuredGraph graph = value .graph ();
758+ boolean allowOnlyConstantResult = false ;
751759 do {
752760 CompilationAlarm .checkProgress (graph );
753761 /*
754762 * PiArrayNode implements ArrayLengthProvider and ValueProxy. We want to treat it as an
755763 * ArrayLengthProvider, therefore we check this case first.
756764 */
757- if (current instanceof ArrayLengthProvider ) {
758- return (( ArrayLengthProvider ) current ) .findLength (mode , constantReflection );
765+ if (current instanceof ArrayLengthProvider provider ) {
766+ return filterArrayLengthResult ( provider .findLength (mode , constantReflection ), allowOnlyConstantResult );
759767
760- } else if (current instanceof ValuePhiNode ) {
768+ } else if (current instanceof ValuePhiNode phi ) {
761769 if (visitedPhiInputMap == null ) {
762770 visitedPhiInputMap = EconomicMap .create ();
763771 }
764- return phiArrayLength (( ValuePhiNode ) current , mode , constantReflection , visitedPhiInputMap );
772+ return filterArrayLengthResult ( phiArrayLength (phi , mode , constantReflection , visitedPhiInputMap ), allowOnlyConstantResult );
765773
766- } else if (current instanceof ValueProxyNode ) {
767- ValueProxyNode proxy = (ValueProxyNode ) current ;
774+ } else if (current instanceof ValueProxyNode proxy ) {
768775 ValueNode length = arrayLength (proxy .getOriginalNode (), mode , constantReflection );
769776 if (mode == ArrayLengthProvider .FindLengthMode .CANONICALIZE_READ && length != null && !length .isConstant ()) {
770777 length = new ValueProxyNode (length , proxy .proxyPoint ());
771778 }
772- return length ;
779+ return filterArrayLengthResult ( length , allowOnlyConstantResult ) ;
773780
774- } else if (current instanceof ValueProxy ) {
775- /* Written as a loop instead of a recursive call to reduce recursion depth. */
776- current = ((ValueProxy ) current ).getOriginalNode ();
781+ } else if (current instanceof LimitedValueProxy valueProxy ) {
782+ /*
783+ * Note is it usually recommended to check for ValueProxy, not LimitedValueProxy.
784+ * However, in this case we are intentionally unproxifying all LimitedValueProxies,
785+ * as we want constant lengths to be found across DeoptProxyNodes. When the result
786+ * is not a ValueProxy we limit the returned result to constant values.
787+ */
788+ if (!(valueProxy instanceof ValueProxy )) {
789+ allowOnlyConstantResult = true ;
790+ }
791+ current = valueProxy .getOriginalNode ();
777792 } else {
778793 return null ;
779794 }
0 commit comments