JDK-8181833 : [Graal] UnsafeGetStableArrayElement.java fails with "assertNotEquals: expected 1 to not equal 1"
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 10
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • Submitted: 2017-06-09
  • Updated: 2020-07-09
  • Resolved: 2020-07-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 15
15Resolved
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
compiler/unsafe/UnsafeGetStableArrayElement.java fails with

java.lang.RuntimeException: assertNotEquals: expected 1 to not equal 1
        at jdk.test.lib.Asserts.fail(Asserts.java:594)
        at jdk.test.lib.Asserts.assertNotEquals(Asserts.java:394)
        at jdk.test.lib.Asserts.assertNotEquals(Asserts.java:378)
        at jdk.test.lib.Asserts.assertNE(Asserts.java:355)
        at compiler.unsafe.UnsafeGetStableArrayElement.run(UnsafeGetStableArrayElement.java:214)
        at compiler.unsafe.UnsafeGetStableArrayElement.testMismatched(UnsafeGetStableArrayElement.java:225)
        at compiler.unsafe.UnsafeGetStableArrayElement.testUnsafeAccess(UnsafeGetStableArrayElement.java:232)
        at compiler.unsafe.UnsafeGetStableArrayElement.main(UnsafeGetStableArrayElement.java:338)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:563)
        at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:115)
        at java.base/java.lang.Thread.run(Thread.java:844)

when running with Graal.
Comments
The test is listed in ProblemList-graal.txt and we expect it to work with libgraal. So closing this bug as duplicate of 8207267
09-07-2020

> It looks like JVMCI compiler mode doesn't respect -Xbatch It doesn't always respect batch: https://github.com/openjdk/jdk/blob/master/src/hotspot/share/compiler/compileBroker.cpp#L1527 The background for this is JDK-8148507. This is another thing that is solved by libgraal.
13-11-2019

I don't see any relevant compilations (Test::test*) happening in compiler log before the failure. The test fails because the check happens before generated code is installed. It looks like JVMCI compiler mode doesn't respect -Xbatch and performs compilation in background thus defeating test warmup. (Or maybe compilation is delayed for some reason.) The test passes if I increase # of warmup iterations to 1M and I see relevant test methods in compilation log.
13-11-2019

I was working on compiler/unsafe/UnsafeGetStableArrayElement.java to make it work with Graal. I patched the test so mismatched accesses are not checked in case of Graal VM is used, please see updated version of the test attached. However, the test started to fail recently with latest jdk14 bits. The failure is now in testMatched check: java.lang.RuntimeException: assertEquals: expected true to equal false at jdk.test.lib.Asserts.fail(Asserts.java:594) at jdk.test.lib.Asserts.assertEquals(Asserts.java:205) at jdk.test.lib.Asserts.assertEquals(Asserts.java:189) at jdk.test.lib.Asserts.assertEQ(Asserts.java:166) at compiler.unsafe.UnsafeGetStableArrayElement.run(UnsafeGetStableArrayElement.java:227) at compiler.unsafe.UnsafeGetStableArrayElement.testMatched(UnsafeGetStableArrayElement.java:241) at compiler.unsafe.UnsafeGetStableArrayElement.testUnsafeAccess(UnsafeGetStableArrayElement.java:252) at compiler.unsafe.UnsafeGetStableArrayElement.main(UnsafeGetStableArrayElement.java:364) It seems the failure was introduced by latest update Graal changes (JDK-8233273). Vladimir [~vlivanov], could you please have a look and let me know if this is one more expected incompatibility between c2 and graal or this is Graal regression. Thanks.
04-11-2019

How does this relate to Unsafe accesses to @Stable arrays? I don't see any use of Unsafe in String, StringLatin1 or StringUTF16 in JDK 9. What are you suggesting by "perhaps Graal can get away with special-casing java.lang.String"? That we should only prevent constant folding mismatched accesses to String.value via Unsafe?
07-09-2017

Checking the VC history of the failing test reveals the context. Some performance of packed strings might depend on mismatched access, also with constant folding, to a string's base array. The behavior is triggered for the Hotspot JITs by the @Stable annotation. I am not aware of any other use of @Stable with mismatched access, so perhaps Graal can get away with special-casing java.lang.String. Also, the zero-sensitivity of @Stable doesn't lend well to vectorizing (larger access to smaller elements) or field extraction (smaller access to larger elements) since the zeros must be tested for in the array elements, not the access units. A quick survey of C2 changes suggests that the best thing to do is bail out of the @Stable optimization on all mismatches. In the case of String.charAt, the character being loaded is only constant foldable if *both* array bytes are non-zero, which is an awkward test to get right, and also is liable to fail in practice. What String needs is a new "frozen" marker on its data arrays, which would allow constant folding regardless of value (i.e., whether individual bytes are zero or not). @Stable is in this case just a short-term approximation to frozen. (In some cases it is not, since it also supports memoization of lazy evaluation.)
07-09-2017

The test should be modified to support Graal semantics (i.e. it supports constant folding an Unsafe access to an array where the type of the access and the type of the array elements don't match). Either the assertion should be removed or modified to take into account whether the JIT is Graal or C2.
06-09-2017

[~vlivanov], can you say anything more about the reasoning behind the C2 implementation decision? An important question on this and other cases where Graal differs from C2 is how many real world apps or frameworks might be impacted by an incompatibility. While a comprehensive answer is impossible, known dependencies are important to take into account. In the absence of such dependencies, I'm inclined to leave Graal behavior as is.
04-09-2017

Yes, mismatched accesses aren't constant folded by C2 and UnsafeGetStableArrayElement checks that. It was an implementation decision, so I don't think Graal behavior is required to be aligned with C2. So, either fixing the test or changing Graal should work.
22-08-2017

Looking into this test case, the behavior on stable array is that 1. unsafe read with the same type can be constant folded 2. unsafe read with a different type cannot be constant folded If that is correct, I will synchronize the graal behavior.
22-08-2017

Hi Rahul, yes, that's correct. Thanks for re-adding the testbug label. Tobias
18-08-2017

Hi [~thartmann], [~epavlova], If understood correctly Tobias comment mentioned only the UnsafeOffHeapBooleanTest failure is a graal bug and same as JDK-8186134. But the original 8181833 assert failure reported here for UnsafeGetStableArrayElement is different and still seems to be testbug! So I am re-applying testbug label. Please edit if I am wrong. Thanks.
17-08-2017

[~epavlova], looking at the UnsafeOffHeapBooleanTest failures again, I think they are not test bugs but "real" Graal problems (see JDK-8186134).
15-08-2017

I agree with your analysis. It is expected the test is run only with C2: @requires vm.flavor == "server" & !vm.emulatedClient * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions * -Xbatch -XX:-TieredCompilation
09-06-2017

[~vlivanov], you added the test with JDK-8150186, could you please verify?
09-06-2017

ILW = Test fails with Graal, 3 tests, no workaround = LLH = P5
09-06-2017

These tests rely on being executed with C2 and fail because Graal does not optimize the code as expected. I think theses tests should not be executed with Graal. Marking as testbug.
09-06-2017

1 more test: compiler/unsafe/UnsafeGetConstantField.java
09-06-2017

2 more test failures which might be related: TEST: compiler/unsafe/UnsafeOffHeapBooleanTest.java #section:main ----------messages:(5/412)---------- command: main -XX:+TieredCompilation -XX:TieredStopAtLevel=3 -Xbatch UnsafeOffHeapBooleanTest 20000 reason: User specified action: run main/othervm -XX:+TieredCompilation -XX:TieredStopAtLevel=3 -Xbatch UnsafeOffHeapBooleanTest 20000 Mode: othervm [/othervm specified] Additional options from @modules: --add-modules java.base --add-exports java.base/jdk.internal.misc=ALL-UNNAMED elapsed time (seconds): 8.175 ----------configuration:(4/111)---------- Boot Layer add modules: java.base add exports: java.base/jdk.internal.misc ALL-UNNAMED ----------System.out:(6/143)---------- ### Test started Some of the results below are wrong bool0 is: true bool1 is: true bool0 & bool1 is: false =================================== ----------System.err:(14/924)---------- Java HotSpot(TM) 64-Bit Server VM warning: forcing TieredStopAtLevel to full optimization because JVMCI is enabled java.lang.RuntimeException: ### Test failed at UnsafeOffHeapBooleanTest.main(UnsafeOffHeapBooleanTest.java:76) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:563) at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:115) at java.base/java.lang.Thread.run(Thread.java:844) TEST: compiler/unsafe/UnsafeOnHeapBooleanTest.java command: main -XX:-UseOnStackReplacement -XX:-TieredCompilation -Xbatch UnsafeOnHeapBooleanTest 20000 reason: User specified action: run main/othervm -XX:-UseOnStackReplacement -XX:-TieredCompilation -Xbatch UnsafeOnHeapBooleanTest 20000 Mode: othervm [/othervm specified] Additional options from @modules: --add-modules java.base --add-exports java.base/jdk.internal.misc=ALL-UNNAMED elapsed time (seconds): 27.218 ----------configuration:(4/111)---------- Boot Layer add modules: java.base add exports: java.base/jdk.internal.misc ALL-UNNAMED ----------System.out:(6/143)---------- ### Test started Some of the results below are wrong bool0 is: true bool1 is: true bool0 & bool1 is: false =================================== ----------System.err:(13/807)---------- java.lang.RuntimeException: ### Test failed at UnsafeOnHeapBooleanTest.main(UnsafeOnHeapBooleanTest.java:81) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:563) at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:115) at java.base/java.lang.Thread.run(Thread.java:844)
09-06-2017

Steps to reproduce: > jtreg -vt -k:\!ignore -javaoptions:"-XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+TieredCompilation -XX:+UseJVMCICompiler -Djvmci.compiler=graal" -jdk:HS10_fastdebug -dir:hotspot/test compiler/unsafe/UnsafeGetStableArrayElement.java
09-06-2017