Skip to content

Commit d5ec6c8

Browse files
committed
[GR-31289] Avoid unnecessary VM call and exception when canonicalizing array length read.
PullRequest: graal/8918
2 parents 09612a1 + 9c523b0 commit d5ec6c8

File tree

2 files changed

+12
-10
lines changed

2 files changed

+12
-10
lines changed

compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -114,7 +114,15 @@ public static ValueNode canonicalizeRead(ValueNode read, AddressNode address, Lo
114114
if (tool.canonicalizeReads() && address instanceof OffsetAddressNode) {
115115
OffsetAddressNode objAddress = (OffsetAddressNode) address;
116116
ValueNode object = objAddress.getBase();
117-
if (metaAccess != null && object.isConstant() && !object.isNullConstant() && objAddress.getOffset().isConstant()) {
117+
// Note: readConstant cannot be used to read the array length, so in order to avoid an
118+
// unnecessary CompilerToVM.readFieldValue call ending in an IllegalArgumentException,
119+
// check if we are reading the array length location first.
120+
if (locationIdentity.equals(ARRAY_LENGTH_LOCATION)) {
121+
ValueNode length = GraphUtil.arrayLength(object, ArrayLengthProvider.FindLengthMode.CANONICALIZE_READ, tool.getConstantReflection());
122+
if (length != null) {
123+
return length;
124+
}
125+
} else if (metaAccess != null && object.isConstant() && !object.isNullConstant() && objAddress.getOffset().isConstant()) {
118126
long displacement = objAddress.getOffset().asJavaConstant().asLong();
119127
int stableDimension = ((ConstantNode) object).getStableDimension();
120128
if (locationIdentity.isImmutable() || stableDimension > 0) {
@@ -125,12 +133,6 @@ public static ValueNode canonicalizeRead(ValueNode read, AddressNode address, Lo
125133
}
126134
}
127135
}
128-
if (locationIdentity.equals(ARRAY_LENGTH_LOCATION)) {
129-
ValueNode length = GraphUtil.arrayLength(object, ArrayLengthProvider.FindLengthMode.CANONICALIZE_READ, tool.getConstantReflection());
130-
if (length != null) {
131-
return length;
132-
}
133-
}
134136
if (locationIdentity instanceof CanonicalizableLocation) {
135137
CanonicalizableLocation canonicalize = (CanonicalizableLocation) locationIdentity;
136138
ValueNode result = canonicalize.canonicalizeRead(read, address, object, tool);

compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/ArrayLengthProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,7 @@ enum FindLengthMode {
4444
*
4545
* Values that are defined inside a loop and flow out the loop need to be proxied by
4646
* {@link ValueProxyNode}. When this mode is used, new necessary proxy nodes are created
47-
* base on the proxies that were found while traversing the path to the length node. In
47+
* based on the proxies that were found while traversing the path to the length node. In
4848
* addition, new {@link ValuePhiNode phi nodes} can be created. The caller is responsible
4949
* for adding these nodes to the graph, i.e., the return value can be a node that is not yet
5050
* added to the graph.

0 commit comments

Comments
 (0)