RFR (S) 8150534: C1 compilation fails with "Constant field loads are folded during parsing"
Vladimir Ivanov
vladimir.x.ivanov at oracle.com
Wed Feb 24 18:17:54 UTC 2016
The failures are caused by ScavengeRootsInCode < 2. In such case,
compilers don't constant fold object-producing loads, because they can
lead to embedded oops. But it's fine to constant fold an array length,
since it produces an int.
I suggest the following adjustments [1]:
(1) add the following assert:
if (field->is_constant() && field->is_static()) {
+ assert(PatchALot || ScavengeRootsInCode < 2, "Constant field
loads are folded during parsing");
(2) replace the guarantee with an assert (hidden in as_array());
verifier should guarantee the arrayref points to an array:
if (!c->is_null_object()) {
- guarantee(c->is_array(), "Arraylength should reference the array");
- set_constant(((ciArray*) c)->length());
+ set_constant(c->as_array()->length());
}
(3) add 2 new test modes to the test:
+ * @run main/othervm ... -XX:ScavengeRootsInCode=0
+ * @run main/othervm ... -XX:ScavengeRootsInCode=1
Best regards,
Vladimir Ivanov
[1] diff --git a/src/share/vm/c1/c1_Canonicalizer.cpp
b/src/share/vm/c1/c1_Canonicalizer.cpp
--- a/src/share/vm/c1/c1_Canonicalizer.cpp
+++ b/src/share/vm/c1/c1_Canonicalizer.cpp
@@ -248,10 +248,10 @@
} else if ((lf = x->array()->as_LoadField()) != NULL) {
ciField* field = lf->field();
if (field->is_constant() && field->is_static()) {
+ assert(PatchALot || ScavengeRootsInCode < 2, "Constant field
loads are folded during parsing");
ciObject* c = field->constant_value().as_object();
if (!c->is_null_object()) {
- guarantee(c->is_array(), "Arraylength should reference the array");
- set_constant(((ciArray*) c)->length());
+ set_constant(c->as_array()->length());
}
}
}
diff --git a/test/compiler/c1/CanonicalizeArrayLength.java
b/test/compiler/c1/CanonicalizeArrayLength.java
--- a/test/compiler/c1/CanonicalizeArrayLength.java
+++ b/test/compiler/c1/CanonicalizeArrayLength.java
@@ -27,6 +27,8 @@
* @summary C1 crashes in Canonicalizer::do_ArrayLength() after fix
for JDK-8150102
* @run main/othervm -XX:CompileThreshold=100 -XX:+TieredCompilation
-XX:TieredStopAtLevel=1 -XX:-BackgroundCompilation
CanonicalizeArrayLength
* @run main/othervm -XX:CompileThreshold=100 -XX:+TieredCompilation
-XX:TieredStopAtLevel=1 -XX:-BackgroundCompilation -XX:+PatchALot
CanonicalizeArrayLength
+ * @run main/othervm -XX:CompileThreshold=100 -XX:+TieredCompilation
-XX:TieredStopAtLevel=1 -XX:-BackgroundCompilation
-XX:ScavengeRootsInCode=0 CanonicalizeArrayLength
+ * @run main/othervm -XX:CompileThreshold=100 -XX:+TieredCompilation
-XX:TieredStopAtLevel=1 -XX:-BackgroundCompilation
-XX:ScavengeRootsInCode=1 CanonicalizeArrayLength
*
*/
On 2/24/16 8:25 PM, Aleksey Shipilev wrote:
> Hi,
>
> In JDK-8150102, we assumed that all suitable constants are exposed as
> Constants after parsing, and added the assert to test that invariant is
> true. And of course, it asserts in some corner cases which we cannot
> reliably reproduce.
>
> With no clear way to fix the underlying issue, we would like to
> re-introduce the deleted branch in Canonicalizer:
> https://bugs.openjdk.java.net/browse/JDK-8150534
> http://cr.openjdk.java.net/~shade/8150534/webrev.01/
>
> Note that it fixes the case when -XX:+PatchALot is used, which
> definitely asserts. Some tests unreliably assert even with
> out-of-the-box config. I forked the investigation about the Constant
> field loads to:
> https://bugs.openjdk.java.net/browse/JDK-8150547
>
> Testing: regression tests; JPRT (in progress)
>
> Thanks,
> -Aleksey
>
More information about the hotspot-compiler-dev
mailing list