Community
Participate
Working Groups
Build Identifier: M20110909-1335 Executing the following test case will result in a VerifyError "Inconsistent stackmap frames at branch target". Environment: - Eclipse 3.7.1 (M20110909-1335) - Linux (x86_64/GTK 2) - JDK7 Stacktrace: --- Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 48 in method E7Bug.main([Ljava/lang/String;)V at offset 34 at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2442) at java.lang.Class.getMethod0(Class.java:2685) at java.lang.Class.getMethod(Class.java:1620) at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:484) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:476) --- --- import java.util.Arrays; import java.util.List; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class E7Bug { public static void main(final String[] args) { final Lock lock = new ReentrantLock(); final List<String> strings = Arrays.asList(args); lock.lock(); try { for (final String string : strings) { return; } return; } finally { lock.unlock(); } } } --- Reproducible: Always Steps to Reproduce: 1. Run testcase in Eclipse with JavaSE-1.7 target
Reproduced when -preserveAllLocals option is used. If unused locals are optimized out, the code runs fine.
In this case, both return statements are "shared". We compare state index of both return statements and they are identical. Now I need to investigate why they are identical when one should define one more local than the other one.
(In reply to comment #1) > Reproduced when -preserveAllLocals option is used. If unused locals are > optimized out, the code runs fine. If the loop for (final String string : strings) { return; } is replaced with for (final String string : strings) { if(string == null) return; } the code causes the error regardless of whether the -preserveAllLocals option is used. But removing either of the return statements from the try block or the lock.unlock() statement from the finally block will allow the code to run fine.
(In reply to comment #3) > the code causes the error regardless of whether the -preserveAllLocals option > is used. But removing either of the return statements from the try block or > the lock.unlock() statement from the finally block will allow the code to run > fine. The problem comes from the sharing of the return statement and we do so because we believe they both have the same state index which is wrong. I am investigating what is going on.
Ayushman, could you please investigate why the state index is identical for both return statements? I believe this is the key of the problem here. They should not be identical since the locals initializations state is different for both return statement. If I replace the code with its for statement equivalent, the code generation is fine.
(In reply to comment #5) > Ayushman, could you please investigate why the state index is identical for > both return statements? I think this happens because the merged info that we return after the foreach statement has been analysed still consists of the initialization info of the foreach condition variable 'string' (it is still marked as definitely initialized in the flow info at the end of foreach analysis). This polluted flow info, is in turn, used to initialize the state index for the second return as well, and thus both return statements end up with the same indices. The flow info outside the foreach should not contain any initialization info for 'string'
Created attachment 204440 [details] proposed fix v1.0 + regression tests The fix for the foreach case is fairly localised. We were adding the initialization info from the condition into the exit branch's info, which was finding its way into the final merged info. But since in foreach, a variable is always declared in the condition, and its scope ends with end of the foreach, we should not add any initialization info from the foreach condition. Also added a test for this. I also saw the same thing happening in for statement case, although there was no verify error there as such. But again, any variable initialized in the for statement itself has no business to pollute the flow info after the for loop. This needed some more work as currently there was no infrastructure to remove the init info of specific variables from the flow info. Now the generated code is same as the one generated by javac 7 in both for and foreach case. (I still need to run the complete test suite)
(In reply to comment #7) > (I still need to run the complete test suite) All tests pass.
Released in HEAD via commit 99350dc001d49db8dc24214c00ce73e1cd4de055.
Reopening for backporting in R3_7_maintenance. Olivier, need your +1 on this.
Looks good to me.
Released commit 4b5d6df0b2e1a9471a757e456125a40aa1a7569d in R3_7_maintenance.
Verified for 3.8 M3 using build id: N20111022-2000
Verified for 3.7.2RC2 using build M20120118-0800
*** Bug 368996 has been marked as a duplicate of this bug. ***
(In reply to comment #14) > Verified for 3.7.2RC2 using build M20120118-0800 Sadly, this is not fixed in 3.7.2 build M20120208-0800. Should it be fixed? If so, please reopen this bug (or my original one #368996). Thanks, Carsten
(In reply to comment #16) > (In reply to comment #14) > > Verified for 3.7.2RC2 using build M20120118-0800 > > Sadly, this is not fixed in 3.7.2 build M20120208-0800. Should it be fixed? If > so, please reopen this bug (or my original one #368996). Version: 3.7.2 Build id: M20120127-0800 runs the test case from https://bugs.eclipse.org/bugs/show_bug.cgi?id=368996#c2 just fine. Are you sure you are not confusing the same symptom for the same problem ? We have had multiple fixes in this area - one is also underway as we speak. Could you test with 3.8 RC1 bits posted ?
(In reply to comment #16) > (In reply to comment #14) > > Verified for 3.7.2RC2 using build M20120118-0800 > > Sadly, this is not fixed in 3.7.2 build M20120208-0800. Should it be fixed? If > so, please reopen this bug (or my original one #368996). > > Thanks, > Carsten I downloaded the build and tried both the test cases in comment 0 of this bug and also the one that you gave in bug 368996. Both run fine without any errors. What problem do you see?
> Are you sure you are not confusing the same symptom for the same problem ? This may indeed be the problem. Sorry! > We have had multiple fixes in this area - one is also underway as we > speak. Where can I find it? > Could you test with 3.8 RC1 bits posted ? I do not have Eclipse 3.8 RC1. However, I can provide a simple test case that breaks with Eclipse 3.7SR2 (20120216-1857): public class E7Bug { public final static Object f() { final Object a = null; Object b; label: do { switch (0) { case 1: { b = a; } break; default: break label; } } while (true); return a; } public static void main(final String[] args) { f(); } } Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 25 in method E7Bug.f()Ljava/lang/Object; at offset 3 This code results out of code generated by antlr (which is why we cannot easlily work around the bug). Please re-open this ticket (or create a new one?). Best regards, Carsten Otto
Carsten, This is still an issue with the code in latest. I opened bug 380927 to cover your test case. Thanks for the test case.