openj9
openj9 copied to clipboard
JDK8 OpenJ9's (Deterministic) Result is Different from That of HotSpot and ART
Java version
openjdk version "1.8.0_342-internal"
OpenJDK Runtime Environment (build 1.8.0_342-internal-_2022_06_10_15_18-b00)
Eclipse OpenJ9 VM (build master-3d06b2f9c, JRE 1.8.0 Linux amd64-64-Bit Compressed References 20220610_000000 (JIT enabled, AOT enabled)
OpenJ9 - 3d06b2f9c
OMR - cf8ddbd1a
JCL - 2bb179375a based on jdk8u342-b05)
Javac version
javac 1.8.0_342-internal
Summary of problem
The following Test.java makes OpenJ9 (with above version) to produce different result from HotSpot and the Android Runtime (ART). This should also be a JIT compiler's bug since -Xint gives the same result as HotSpot/ART.
Note, this issue is different from #15306 that the OpenJ9 result of the following Test.java is always deterministic, though different from that of HotSpot and Android Runtime.
class Test {
static int N = 256;
static double[] dArrFld = new double[N];
long vMeth_check_sum;
long bMeth_check_sum;
void vMeth(short s, int i) {
if (ax$0) {
int ax$2 = 100033;
int ax$1 = 0xFFFF0001;
int ax$3;
for (ax$3 = ax$1; ax$3 <= ax$2; ax$3++) bMeth_check_sum++;
return;
}
int i22 = 0, i25, i27, i28 = 4, i29;
for (i25 = 2; i25 < 101; i25++)
for (i27 = 1; i27 < 6; ++i27) {
i29 = 1;
i28 += i29;
dArrFld[i27] -= i22;
}
vMeth_check_sum += i28;
}
void mainTest(String[] strArr1) {
short s3 = 32558;
int i30 = 43239;
try {
ax$0 = true;
for (int ax$6 = 0; ax$6 < 5180; ax$6 += 1) vMeth((short) 1157649817, 1798632008);
} finally {
ax$0 = false;
}
vMeth(s3, i30);
System.out.println(vMeth_check_sum);
}
public static void main(String[] strArr) {
Test _instance = new Test();
_instance.mainTest(strArr);
}
Boolean ax$0;
}
Results of OpenJ9:
$ ./OpenJ9/jdk8/bin/java Test
103
Results of HotSpot (JDK8/11/17) and the Android Runtime (ART):
$ ./HotSpot/jdk8u/bin/java Test
499
$ ./HotSpot/jdk11u/bin/java Test
499
$ ./HotSpot/jdk17u/bin/java Test
499
$ ./Android/host-art/host/linux-x86/bin/art --no-compile --64 -- -cp test.jar Test
499
To avoid smashing you issuetracker, I put another similar but different test directly in here. OpenJ9 also produces different result from HotSpot and ART.
This one is different from the above one that this is related to floating-point calculation (i.e., the double dFld). We cannot be sure if they are the same bug or different ones.
import java.util.Vector;
class Test {
int N = 256;
double dFld;
volatile float fFld;
int iFld1;
void mainTest(String[] strArr1) {
int i25, i29 = 58047;
long[] lArr3 = new long[N];
init(lArr3, 28L);
for (long l2 : lArr3) {
for (i25 = 1; i25 < 20; i25++) dFld -= iFld1;
iFld1 = (int) l2;
fFld = i29;
}
for (int ax$268 = 1695; ax$268 < 5424; ax$268 += 1) {
Vector ax$263 = new Vector();
String[][] ax$264 = new String[672][2];
}
System.out.println(dFld);
}
public static void main(String[] strArr) {
Test _instance = new Test();
for (int i = 0; i < 10; i++) _instance.mainTest(strArr);
}
public static void init(long[] a, long seed) {
for (int j = 0; j < a.length; j++) {
a[j] = (j % 2 == 0) ? seed + j : seed - j;
}
}
}
Results of OpenJ9:
$ ./OpenJ9/jdk8/bin/java Test
-138073.0
-271833.0
-405593.0
-539353.0
564775.0
1668903.0
2773031.0
3877159.0
4981287.0
6085415.0
Results of HotSpot (JDK8/11/17) and the Android Runtime (ART):
$ ./HotSpot/jdk8u/bin/java Test
-138073.0
-271833.0
-405593.0
-539353.0
-673113.0
-806873.0
-940633.0
-1074393.0
-1208153.0
-1341913.0
$ ./HotSpot/jdk11u/bin/java Test
-138073.0
-271833.0
-405593.0
-539353.0
-673113.0
-806873.0
-940633.0
-1074393.0
-1208153.0
-1341913.0
$ ./HotSpot/jdk17u/bin/java Test
-138073.0
-271833.0
-405593.0
-539353.0
-673113.0
-806873.0
-940633.0
-1074393.0
-1208153.0
-1341913.0
$ ./Android/host-art/host/linux-x86/bin/art --no-compile --64 -- -cp test.jar Test
-138073.0
-271833.0
-405593.0
-539353.0
-673113.0
-806873.0
-940633.0
-1074393.0
-1208153.0
-1341913.0
I can't duplicate the first test case.
The second test case gives me different results than shown, but still different from Hotspot. It's also interesting that Hotspot runs the test case much faster. This is not fixed by https://github.com/eclipse-openj9/openj9/pull/15344
@0xdaryl fyi
How about openj9-bug-72.tar.gz? The first test case is reduced from the Test.java in this link.
Actually with -Xshareclasses:none I can duplicate the first case.
Awesome @pshipton
The first test only fails at scorching and passes with -Xjit:disableSequenceSimplification. This may also be a duplicate of #15306.
The second test will fail at hot and (expectedly) -Xjit:disableSequenceSimplification has no effect. It is a separate issue.
I evaluated as far back as 0.29 and both fail, hence these are not regressions in 0.33.
@0xdaryl then do I need to open a new issue thread for the second?
@0xdaryl then do I need to open a new issue thread for the second?
Let's hold off for now. If the first issue is indeed a duplicate of 15306 then we can simply re-purpose this issue for the second problem.
There is also a second test in #15306, please help check that when you are available. But, just take your time :-).
@nbhuiyan : please add this to your list of issues to investigate.
I have narrowed down the optimization that causes the incorrect result running the JIT-ed code: jProfilingRecompLoopTest. This optimization modifies the IL and sets up a counting mechanism for loop iterations in order to trigger recompilation of the method containing the loop if the number of iterations are high enough. These checks are inserted right after asynccheck nodes. For Test.vMeth method in comment above, there are 4 places where this optimization transforms the CFG and inserts the checks. I have not yet found anything in the resulting trees that suggests they are set up incorrectly, and I am currently trying to understand if something may be going wrong at runtime.
The underlying issue causing this incorrect result may have existed for a while since this particular optimization's code hardly saw any activity over the past few years.
This issue is not a regression and won't be resolved in time for 0.33. This should be moved out of the 0.33 release. @pshipton
This won't be fixed for 0.35. Moving to 0.36.
Moving to 0.38.
No change in status on this one. Moving to 0.40.