JDK-8157189 : 'iload_w' in shared class is not interpreted correctly
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2016-05-17
  • Updated: 2016-06-23
  • Resolved: 2016-06-03
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 9
9 b124Fixed
Related Reports
Relates :  
Description
When CDS archives classes, it converts all 'iload' bytcodes to 'nofast_iload' without checking if it's wide instruction. 'nofast_iload' does not work with 'wide' instruction. That results incorrect behavior at runtime when the original byte code is 'iload_w'.
Comments
Here is proposed fix. diff --git a/src/share/vm/memory/metaspaceShared.cpp b/src/share/vm/memory/metaspaceShared.cpp --- a/src/share/vm/memory/metaspaceShared.cpp +++ b/src/share/vm/memory/metaspaceShared.cpp @@ -191,7 +191,12 @@ case Bytecodes::_getfield: *bcs.bcp() = Bytecodes::_nofast_getfield; break; case Bytecodes::_putfield: *bcs.bcp() = Bytecodes::_nofast_putfield; break; case Bytecodes::_aload_0: *bcs.bcp() = Bytecodes::_nofast_aload_0; break; - case Bytecodes::_iload: *bcs.bcp() = Bytecodes::_nofast_iload; break; + case Bytecodes::_iload: { + if (!bcs.is_wide()) { + *bcs.bcp() = Bytecodes::_nofast_iload; + } + break; + } default: break; } } rewrite_nofast_bytecode() also rewrites getfield, putfield, aload_0 in shared classes. Those bytecodes do not work with 'wide' instruction. So they don't have the same issue.
01-06-2016

The same issue also affects the lang/STMT/stmt005/stmt00591m6/ test.
01-06-2016

After I fixed rewrite_nofast_bytecode() to not replace 'iload_w', both jck tests passed.
01-06-2016

Ok, I found the root cause. The 'iload' instruction in the jasm code is 'iload_w'. rewrite_nofast_bytecode() (metaspaceShared.cpp) replaces all 'iload' bytecodes to 'nofast_iload', regardless if it is 'wide' or not. The 'nofast_iload' bytecode is interpreted by TemplateTable::iload_internal() without patching, which does not handle the 'wide' version however. rewrite_nofast_bytecode() should check if 'iload' is wide and only replace the byte code when it's not. The VM does not patch the 'iload_w' byte code, there is not 'write' to the shared method in that case.
01-06-2016

Looked into the javasoft.sqe.tests.vm.instr.iinc_w.iinc_w004.iinc_w00410m1t.iinc_w00410m1t failure. The first failure occurs in the javasoft.sqe.tests.vm.instr.iinc_w.iinc_w004.iinc_w00410m1t.iinc_w00410m1t1p.run() method, which is invoked by iinc_w00410m1t.runPositive() through reflection. The runtime executed bytecode instructions for javasoft.sqe.tests.vm.instr.iinc_w.iinc_w004.iinc_w00410m1t.iinc_w00410m1t1p.run() are slightly different when the javasoft.sqe.tests.vm.instr.iinc_w.iinc_w004.iinc_w00410m1t.iinc_w00410m1t1p is shared. bytecode trace with -Xshare:on [21781] static jint javasoft.sqe.tests.vm.instr.iinc_w.iinc_w004.iinc_w00410m1t.iinc_w00410m1t1p.run(jobject, jobject) [21781] 1328730 0 iconst_0 [21781] 1328731 1 wide[21781] 1328732 1 istore #300 [21781] 1328733 5 wide[21781] 1328734 5 iinc #300 1 [21781] 1328735 11 nofast_iload #21 [21781] 1328736 13 aconst_null [21781] 1328737 14 aload_2 [21781] 1328738 15 ldc 1 [21781] 1328739 17 if_icmpeq 22 [21781] 1328740 20 iconst_2 [21781] 1328741 21 ireturn bytcode trace with -Xshare:off [26262] static jint javasoft.sqe.tests.vm.instr.iinc_w.iinc_w004.iinc_w00410m1t.iinc_w00410m1t1p.run(jobject, jobject) [26262] 9086631 0 iconst_0 [26262] 9086632 1 wide[26262] 9086633 1 istore #300 [26262] 9086634 5 wide[26262] 9086635 5 iinc #300 1 [26262] 9086636 11 wide[26262] 9086637 11 iload #300 [26262] 9086638 15 ldc 1 [26262] 9086639 17 if_icmpeq 22 [26262] 9086640 22 iconst_0 [26262] 9086641 23 ireturn jasm code: iconst_0; istore_w 300; iinc_w 300,1; iload_w 300; ldc int 1; The difference is the '_nofast_iload' in shared case.
27-05-2016

Some logs from test run: [0.712s][info][classload] jdk.internal.misc.JavaNetAccess source: jrt:/java.base [0.713s][info][classload] java.net.SocketPermission source: shared objects file [0.713s][info][classload] java.net.URLClassLoader$7 source: jrt:/java.base [0.714s][info][classload] javasoft.sqe.tests.vm.instr.iload_w.iload_w001.iload_w00101m1t.iload_w00101m1t source: shared objects file [0.715s][info][classload] com.sun.jck.lib.ExecJCKTestSameJVMCmd$SimpleTest source: file:/data/tools/jck/9/b33/JCK-runtime-9/lib/jtjck.jar [0.717s][info][classload] com.sun.jck.lib.ExecJCKTestSameJVMCmd$StandardTest source: file:/data/tools/jck/9/b33/JCK-runtime-9/lib/jtjck.jar [0.717s][info][classload] com.sun.jck.lib.ExecJCKTestSameJVMCmd$Version2Test source: file:/data/tools/jck/9/b33/JCK-runtime-9/lib/jtjck.jar [0.718s][info][classload] javasoft.sqe.javatest.Test source: shared objects file [0.718s][info][classload] com.sun.jck.lib.Deprecated source: file:/data/tools/jck/9/b33/JCK-runtime-9/lib/jtjck.jar [0.719s][info][classload] jdk.internal.reflect.DelegatingMethodAccessorImpl source: jrt:/java.base java version "9-ea" Java(TM) SE Runtime Environment (build 9-ea+116) Java HotSpot(TM) 64-Bit Server VM (build 9-ea+116, mixed mode, sharing) STATUS:Failed. [0.720s][info][classload] java.lang.Shutdown source: jrt:/java.base [0.720s][info][classload] java.lang.Shutdown$Lock source: jrt:/java.base
17-05-2016

ILW: MHM -> P3 I: M, test failure, not a crash L: H - always reproducible W: M, if not using AppCDS
17-05-2016