Summary: | Program exhibits differing behavior depending on two statements which are always true while the program is running | ||||||
---|---|---|---|---|---|---|---|
Product: | [Eclipse Project] JDT | Reporter: | Dennis Meng <dennismeng90> | ||||
Component: | Core | Assignee: | Stephan Herrmann <stephan.herrmann> | ||||
Status: | VERIFIED NOT_ECLIPSE | QA Contact: | |||||
Severity: | normal | ||||||
Priority: | P3 | CC: | eclipse, Olivier_Thomann, remy.suen, stephan.herrmann | ||||
Version: | 3.8 | ||||||
Target Milestone: | 3.8 M1 | ||||||
Hardware: | PC | ||||||
OS: | Windows Vista | ||||||
Whiteboard: | |||||||
Attachments: |
|
Description
Dennis Meng
2011-08-03 21:37:00 EDT
Created attachment 200870 [details]
Source code of program that exhibits the problem
See description...
Oops. The for loop in question is the outermost loop in the program. I can reproduce using any version of the compiler (tried 3.2.2, 3.6.0 and
3.7.0).
> However, if I change the statement to be something that will always be true, no
> matter what happens at run time, the program does not appear to terminate
> within any reasonable stretch of time.
What line where you changing?
Never mind, I found that changing for (int i = 1; i <= Integer.MAX_VALUE; i++) { to for (int i = 1; i <= Integer.MAX_VALUE-1; i++) { fixes the program. Next I inserted System.out.print(i); as the last statement of the outermost loop => program correctly prints and terminates. However, when comparing the byte code of these two versions I couldn't see any significant change other than a changed constant (plus the added statement of course). Next I ran the "buggy" .class files on different JVMs: java version "1.6.0_22" OpenJDK Runtime Environment (IcedTea6 1.10.2) (6b22-1.10.2-0ubuntu1~11.04.1) OpenJDK Server VM (build 20.0-b11, mixed mode) => HANGS java version "1.6.0_16" Java(TM) SE Runtime Environment (build 1.6.0_16-b01) Java HotSpot(TM) Server VM (build 14.2-b01, mixed mode) => HANGS java version "1.7.0-ea" Java(TM) SE Runtime Environment (build 1.7.0-ea-b144) Java HotSpot(TM) Server VM (build 21.0-b14, mixed mode) => CORRECT! When passing -Xint to the JVM all versions that I tried correctly execute even the "buggy" class file. => Looks like a bug in the HotSpot JIT compiler. This is confirmed by the fact that J9 has no problem either. Has anybody seen a corresponding bug report against HotSpot? (In reply to comment #4) Well yes, but the statement "i <= Integer.MAX_VALUE - 1" isn't true for all possible values of i. The entire point of the report was to note that if I put a statement that always evaluates to true regardless of what happens in the loop (like "i <= Integer.MAX_VALUE", "i >= Integer.MIN_VALUE", or just "true"), the program hangs, whereas if I have something that doesn't have to be always true but happens to always evaluate to true while the program is being run, like "i <= Integer.MAX_VALUE - 1" (or less drastically, "i > 0"), the program works just fine. (For those who haven't seen the code itself, the program is supposed to reach a line with "System.exit(0);" inside the loop.) > Never mind, I found that changing > for (int i = 1; i <= Integer.MAX_VALUE; i++) { > to > for (int i = 1; i <= Integer.MAX_VALUE-1; i++) { > fixes the program. > > Next I inserted System.out.print(i); as the last statement of the > outermost loop => program correctly prints and terminates. > > However, when comparing the byte code of these two versions I couldn't > see any significant change other than a changed constant (plus the > added statement of course). > > Next I ran the "buggy" .class files on different JVMs: > > java version "1.6.0_22" > OpenJDK Runtime Environment (IcedTea6 1.10.2) (6b22-1.10.2-0ubuntu1~11.04.1) > OpenJDK Server VM (build 20.0-b11, mixed mode) > > => HANGS > > java version "1.6.0_16" > Java(TM) SE Runtime Environment (build 1.6.0_16-b01) > Java HotSpot(TM) Server VM (build 14.2-b01, mixed mode) > > => HANGS > > java version "1.7.0-ea" > Java(TM) SE Runtime Environment (build 1.7.0-ea-b144) > Java HotSpot(TM) Server VM (build 21.0-b14, mixed mode) > > => CORRECT! (In reply to comment #6) > (In reply to comment #4) > > Well yes, but the statement "i <= Integer.MAX_VALUE - 1" isn't true for all > possible values of i. > > The entire point of the report was to note that if I put a statement that > always evaluates to true regardless of what happens in the loop (like "i <= > Integer.MAX_VALUE", "i >= Integer.MIN_VALUE", or just "true"), the program > hangs, whereas if I have something that doesn't have to be always true but > happens to always evaluate to true while the program is being run, like "i <= > Integer.MAX_VALUE - 1" (or less drastically, "i > 0"), the program works just > fine. Yes, and my analysis showed that the Eclipse Java Compiler doesn't generate different code for these cases except inserting a different constant value. More explicitly: in this case no optimization is performed by the compiler. I can't see a bug in our compiler, but I can see that the same code works or works not depending on how you run it: only HotSpot VMs with JIT enabled hang, all other settings work. So: who's to blame? :) Just making sure we're clear as to exactly what I am reporting: namely that I was already well aware that replacing "i <= Integer.MAX_VALUE" with "i <= Integer.MAX_VALUE - 1" would then let the program normally. The only reason that this report exists at all is that there shouldn't be a noticeable difference between the two in my program. I realize that the problem appears to lie with a particular setting. (In reply to comment #7) > (In reply to comment #6) > > (In reply to comment #4) > > > > Well yes, but the statement "i <= Integer.MAX_VALUE - 1" isn't true for all > > possible values of i. > > > > The entire point of the report was to note that if I put a statement that > > always evaluates to true regardless of what happens in the loop (like "i <= > > Integer.MAX_VALUE", "i >= Integer.MIN_VALUE", or just "true"), the program > > hangs, whereas if I have something that doesn't have to be always true but > > happens to always evaluate to true while the program is being run, like "i <= > > Integer.MAX_VALUE - 1" (or less drastically, "i > 0"), the program works just > > fine. > > Yes, and my analysis showed that the Eclipse Java Compiler doesn't generate > different code for these cases except inserting a different constant value. > More explicitly: in this case no optimization is performed by the compiler. > > I can't see a bug in our compiler, but I can see that the same code > works or works not depending on how you run it: only HotSpot VMs with > JIT enabled hang, all other settings work. So: who's to blame? :) (In reply to comment #8) > Just making sure we're clear as to exactly what I am reporting: namely that I > was already well aware that replacing "i <= Integer.MAX_VALUE" with "i <= > Integer.MAX_VALUE - 1" would then let the program normally. The only reason > that this report exists at all is that there shouldn't be a noticeable > difference between the two in my program. Yes, that was perfectly clear from the beginning. Only one thing I couldn't see from your initial report: which condition were you referring to? And what change were you making to toggle between correct and buggy behavior? I filled in that information by giving the "Integer.MAX_VALUE - 1" version as an example of the working versions. Maybe I wasn't clear at what point I switched back to your original program, which was in comment #4: > Next I ran the "buggy" .class files on different JVMs: All experiments from that point used your original example. (In reply to comment #8) > I realize that the problem appears to lie with a particular setting. Yes, and that setting seems to be the "-Xint" option of the HotSpot virtual machine which is not part of Eclipse. Therefor I'm inclined to close this as NOT_ECLIPSE, but first I would like to see if that bug has already been reported at Oracle. Have you checked their bug database? Additional background information: so far I couldn't reproduce this bug with only Oracle software, because their compiler translates the loops in a slightly different scheme: they have all the loop conditions at the top of the loop whereas we generate them at the end of the loop and the top of the loop has a goto to those checks. Apparently the bug in the VM is sensitive to these differences in the translation scheme. (In reply to comment #9) I have not actually, and will do that as my next step. Thanks for your help. > Yes, and that setting seems to be the "-Xint" option of the HotSpot > virtual machine which is not part of Eclipse. Therefor I'm inclined to > close this as NOT_ECLIPSE, but first I would like to see if that bug > has already been reported at Oracle. > Have you checked their bug database? > > Additional background information: so far I couldn't reproduce this bug > with only Oracle software, because their compiler translates the loops in > a slightly different scheme: they have all the loop conditions at the top > of the loop whereas we generate them at the end of the loop and the top > of the loop has a goto to those checks. Apparently the bug in the VM is > sensitive to these differences in the translation scheme. This is an unfortunate interaction between our compiling scheme and the JIT of HotSpot JVMs <= 1.6. However, since IBM's J9 and also the newest HotSpot JVM produce the correct behavior the generated byte code must be considered legal. Closing as NOT_ECLIPSE. Disabling the JIT does fix the issue. Verified for 3.8M2. |