public static ValueNode create(ValueNode forValue, ConstantReflectionProvider constantReflection) { if (forValue instanceof NewArrayNode) { NewArrayNode newArray = (NewArrayNode) forValue; return newArray.length(); } ValueNode length = readArrayLength(forValue, constantReflection); if (length != null) { return length; } return new ArrayLengthNode(forValue); }
protected ValueNode genArrayLength(ValueNode x) { return ArrayLengthNode.create(x, constantReflection); }
protected void lowerArrayLengthNode(ArrayLengthNode arrayLengthNode, LoweringTool tool) { arrayLengthNode.replaceAtUsages(createReadArrayLength(arrayLengthNode.array(), arrayLengthNode, tool)); StructuredGraph graph = arrayLengthNode.graph(); graph.removeFixed(arrayLengthNode); }
@Override public boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode[] args) { ValueNode arg0 = args[0]; org.graalvm.compiler.nodes.java.ArrayLengthNode node = new org.graalvm.compiler.nodes.java.ArrayLengthNode(arg0); b.addPush(JavaKind.Int, node); return true; } @Override
@Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { ValueNode length = readArrayLength(forValue, tool.getConstantReflection()); if (length != null) { return length; } return this; }
@MethodSubstitution public static int getLength(Object array) { if (!array.getClass().isArray()) { DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } return ArrayLengthNode.arrayLength(array); }
private boolean processArrayLength(ArrayLengthNode length, PEReadEliminationBlockState state, GraphEffectList effects) { return processLoad(length, length.array(), ARRAY_LENGTH_LOCATION, -1, JavaKind.Int, state, effects); }
} else if (node instanceof ArrayLengthNode) { ArrayLengthNode arrayLengthNode = (ArrayLengthNode) node; return arrayLengthNode.canonical(canonicalizerTool); } else if (node instanceof IntegerSwitchNode && ((IntegerSwitchNode) node).value().isConstant()) { IntegerSwitchNode switchNode = (IntegerSwitchNode) node;
@Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode array) { b.addPush(JavaKind.Int, new ArrayLengthNode(array)); return true; } });
private ValueNode readOrCreateArrayLength(AccessIndexedNode n, ValueNode array, LoweringTool tool, StructuredGraph graph) { ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection()); if (arrayLength == null) { arrayLength = createReadArrayLength(array, n, tool); } else { arrayLength = arrayLength.isAlive() ? arrayLength : graph.addOrUniqueWithInputs(arrayLength); } return arrayLength; }
private static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length, Counters counters) { if (probability(SLOW_PATH_PROBABILITY, srcPos < 0) || probability(SLOW_PATH_PROBABILITY, destPos < 0) || probability(SLOW_PATH_PROBABILITY, length < 0) || probability(SLOW_PATH_PROBABILITY, srcPos > ArrayLengthNode.arrayLength(src) - length) || probability(SLOW_PATH_PROBABILITY, destPos > ArrayLengthNode.arrayLength(dest) - length)) { counters.checkAIOOBECounter.inc(); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } counters.checkSuccessCounter.inc(); }
@Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode original, ValueNode newLength) { if (analysis) { b.addPush(JavaKind.Object, new AnalysisArraysCopyOfNode(b.getInvokeReturnStamp(b.getAssumptions()).getTrustedStamp(), original, newLength)); } else { /* Get the class from the original node. */ GetClassNode originalArrayType = b.add(new GetClassNode(original.stamp(NodeView.DEFAULT), b.nullCheckedValue(original))); ValueNode originalLength = b.add(ArrayLengthNode.create(original, b.getConstantReflection())); Stamp stamp = b.getInvokeReturnStamp(b.getAssumptions()).getTrustedStamp().join(original.stamp(NodeView.DEFAULT)); b.addPush(JavaKind.Object, new SubstrateArraysCopyOfNode(stamp, original, originalLength, newLength, originalArrayType)); } return true; } });
ValueNode arrayLength = kit.append(new ArrayLengthNode(loadField)); kit.startIf(graph.unique(new IntegerEqualsNode(arrayLength, ConstantNode.forInt(0, graph))), BranchProbabilityNode.NOT_LIKELY_PROBABILITY); kit.elsePart();
@Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode original, ValueNode newLength, ValueNode newArrayType) { if (analysis) { /* * If the new array type comes from a GetClassNode or is a constant we can infer * the concrete type of the new array, otherwise we conservatively assume that * the new array can have any of the instantiated array types. */ b.addPush(JavaKind.Object, new AnalysisArraysCopyOfNode(b.getInvokeReturnStamp(b.getAssumptions()).getTrustedStamp(), original, newLength, newArrayType)); } else { Stamp stamp; if (newArrayType.isConstant()) { ResolvedJavaType newType = b.getConstantReflection().asJavaType(newArrayType.asConstant()); stamp = StampFactory.objectNonNull(TypeReference.createExactTrusted(newType)); } else { stamp = b.getInvokeReturnStamp(b.getAssumptions()).getTrustedStamp(); } ValueNode originalLength = b.add(ArrayLengthNode.create(original, b.getConstantReflection())); b.addPush(JavaKind.Object, new SubstrateArraysCopyOfNode(stamp, original, originalLength, newLength, newArrayType)); } return true; } });
@Override public void simplify(SimplifierTool tool) { if (tool.allUsagesAvailable() && hasNoUsages()) { NodeView view = NodeView.from(tool); ValueNode arrayLength = ArrayLengthNode.create(array, tool.getConstantReflection()); LogicNode boundsCheck = CompareNode.createCompareNode(CanonicalCondition.BT, index, arrayLength, tool.getConstantReflection(), view); if (boundsCheck.isTautology()) { return; } if (graph().getGuardsStage().allowsGuardInsertion()) { if (!arrayLength.isAlive()) { arrayLength = graph().addOrUniqueWithInputs(arrayLength); if (arrayLength instanceof FixedWithNextNode) { FixedWithNextNode fixedArrayLength = (FixedWithNextNode) arrayLength; graph().addBeforeFixed(this, fixedArrayLength); } } boundsCheck = graph().addOrUniqueWithInputs(boundsCheck); FixedGuardNode fixedGuard = new FixedGuardNode(boundsCheck, DeoptimizationReason.BoundsCheckException, DeoptimizationAction.InvalidateReprofile, false, getNodeSourcePosition()); graph().replaceFixedWithFixed(this, graph().add(fixedGuard)); } } }