JDK-8282555 : Missing memory edge when spilling MoveF2I, MoveD2L etc
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 11,17,18,19
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2022-03-02
  • Updated: 2022-07-12
  • Resolved: 2022-05-05
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 11 JDK 17 JDK 19
11.0.17-oracleFixed 17.0.5-oracleFixed 19 b22Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Description
Original Bug Name:
"java.lang.RuntimeException in HeapByteBufferTest.java with -XX:+OptoScheduling"

These flags lead to intermittent unexpected behavior:
-XX:+UnlockDiagnosticVMOptions -XX:-TieredCompilation -XX:+OptoScheduling

On this test:
test/hotspot/jtreg/compiler/intrinsics/unsafe/HeapByteBufferTest.java

I was able to reproduce stably it with the help of -XX:+StressGCM.
With -XX:AbortVMOnException=java.lang.RuntimeException I can let the java exception crash the VM, and I can go find the StressSeed value.
The hit rate is maybe around 10-20%.
The runtime exception happens in this function:
void ck(double x, double y) 
Occasionally, the test runs into an endless recursion/stack-overflow in:
void ck(double x, double y)
-> not sure why this test was implemented this way, but it essentially seems to lead to a stack-overflow if the value is not identical/expected.

Note, that the values are only half off. I have found these cases:
java.lang.RuntimeException:  x = 39cb23bc2be7f15d, y = 2be7f15d
java.lang.RuntimeException:  x = ae05b6495318f496, y = ae45b6495318f496
java.lang.RuntimeException:  x = 1e96db4e3fda1b95, y = 4c71f0d03fda1b95
java.lang.RuntimeException:  x = 8854ecf2c6878eb1, y = e1c006e6c6878eb1
java.lang.RuntimeException: x = 21a12358cfa01320, y = 32418ea0cfa01320
It is evident that the lower 4 byte of the long is identical, and the upper 4 bytes are diverging.

I have found these seeds / java stack traces:

-XX:StressSeed=123
java.lang.RuntimeException:  x = 39cb23bc2be7f15d, y = 2be7f15d
	at MyByteBuffer.ck(ByteBufferTest.java:214)
	at MyByteBuffer.getLong(ByteBufferTest.java:256)
	at ByteBufferTest.stepUsingViews(ByteBufferTest.java:406)
	at ByteBufferTest.step(ByteBufferTest.java:315)
	at ByteBufferTest.run(ByteBufferTest.java:743)
	at HeapByteBufferTest.main(HeapByteBufferTest.java:51)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:577)
	at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:125)
	at java.base/java.lang.Thread.run(Thread.java:828)

-XX:StressSeed=289413885
java.lang.RuntimeException:  x = ae05b6495318f496, y = ae45b6495318f496
	at MyByteBuffer.ck(ByteBufferTest.java:214)
	at MyByteBuffer.getLong(ByteBufferTest.java:256)
	at ByteBufferTest.stepUsingViews(ByteBufferTest.java:406)
	at ByteBufferTest.step(ByteBufferTest.java:315)
	at ByteBufferTest.run(ByteBufferTest.java:743)
	at HeapByteBufferTest.main(HeapByteBufferTest.java:51)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:577)
	at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:125)
	at java.base/java.lang.Thread.run(Thread.java:828)

-XX:StressSeed=284669752
java.lang.RuntimeException:  x = 21a12358cfa01320, y = 32418ea0cfa01320
	at MyByteBuffer.ck(ByteBufferTest.java:214)
	at MyByteBuffer.getLong(ByteBufferTest.java:256)
	at ByteBufferTest.stepUsingViews(ByteBufferTest.java:406)
	at ByteBufferTest.step(ByteBufferTest.java:315)
	at ByteBufferTest.run(ByteBufferTest.java:743)
	at HeapByteBufferTest.main(HeapByteBufferTest.java:51)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:577)
	at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:125)
	at java.base/java.lang.Thread.run(Thread.java:828)
Comments
compiler/intrinsics/unsafe/HeapByteBufferTest.java test passed in JDK 19 ATR.
12-07-2022

Fix request [11u] I backport this for parity with 11.0.17-oracle. A C2 fix we should take. I had to fix a C++11 construct (nullptr). Test passes with but also without the fix. SAP nightly testing passed.
27-06-2022

A pull request was submitted for review. URL: https://git.openjdk.org/jdk11u-dev/pull/1185 Date: 2022-06-24 11:50:35 +0000
24-06-2022

Fix request [17u] I backport this for parity with 17.0.5-oracle. A C2 fix we should take. Clean backport. Test passes and fails without the fix. SAP niglty testing passed.
24-06-2022

A pull request was submitted for review. URL: https://git.openjdk.org/jdk17u-dev/pull/485 Date: 2022-06-21 14:39:23 +0000
21-06-2022

A pull request was submitted for review. URL: https://git.openjdk.org/jdk18u/pull/158 Date: 2022-06-21 07:26:50 +0000
21-06-2022

Changeset: 4a5e7a1a Author: Emanuel Peter <emanuel.peter@oracle.com> Committer: Tobias Hartmann <thartmann@openjdk.org> Date: 2022-05-05 08:15:53 +0000 URL: https://git.openjdk.java.net/jdk/commit/4a5e7a1ada611cfdefdc3b9a6fada05494e07390
05-05-2022

A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk/pull/7889 Date: 2022-03-21 11:02:35 +0000
02-05-2022

ILW = Wrong execution of C2 compiled code, rare, no good workaround = HLH = P2
28-03-2022

I also see that the failure is NOT OptoScheduling specifig. StressGCM helps to reproduce it, as it can invert the scheduling, and since we are missing the dependency edge, this can lead to bad scheduling with wrong results. But I have seen it reproduce without any of these flags also, you just have to be (un)lucky.
28-03-2022

Update for after JDK-8282573: As far as I see the already reported seeds still reproduce the bug. Seed 297274261 also triggers the long case. Using seed 293843391, I can trigger the new RuntimeException for the double case. Some examples: java.lang.RuntimeException: x = 0.0, y = -4.0479973512229064E-20 (x = 0, y = bbe7e52920000000) java.lang.RuntimeException: x = 0.0, y = -195326.078125 (x = 0, y = c107d7f0a0000000) java.lang.RuntimeException: x = 0.0, y = -6.72353284159044E-10 (x = 0, y = be071a1500000000) java.lang.RuntimeException: x = 5.075650423287514E35, y = 3.456374075838653E-12 (x = 47587038e0000000, y = 3d8e671000000000) The lower bytes are mostly the same it seems. Not sure if it is the full 4 bytes. It is almost 4 bytes in this representation. Maybe it is actually 4 bytes, but there were representation changes during the reporting. one with a java stacktrace: java.lang.RuntimeException: x = 0.0, y = 1.08140945408E11 (x = 0, y = 42392db3e0000000) at MyByteBuffer.ck(ByteBufferTest.java:222) at MyByteBuffer.getFloat(ByteBufferTest.java:247) at ByteBufferTest.stepUsingAccessors(ByteBufferTest.java:345) at ByteBufferTest.step(ByteBufferTest.java:316) at ByteBufferTest.run(ByteBufferTest.java:745) at HeapByteBufferTest.main(HeapByteBufferTest.java:51) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) at java.base/java.lang.reflect.Method.invoke(Method.java:577) at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:125) at java.base/java.lang.Thread.run(Thread.java:828)
03-03-2022