Bug 169017 - [1.6][compiler] VerifyError: Inconsistent stackmap frames
Summary: [1.6][compiler] VerifyError: Inconsistent stackmap frames
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.3 M5   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL: http://jroller.com/page/andyl?entry=s...
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-12-24 18:41 EST by Andrey Loskutov CLA
Modified: 2007-02-06 06:57 EST (History)
5 users (show)

See Also:


Attachments
classsloading log files with updated ecj.jar (47.19 KB, application/zip)
2006-12-27 16:07 EST, Andrey Loskutov CLA
no flags Details
Proposed fix (first draft) (18.15 KB, patch)
2007-01-13 22:02 EST, Olivier Thomann CLA
no flags Details | Diff
Polished patch (24.19 KB, patch)
2007-01-19 22:29 EST, Olivier Thomann CLA
no flags Details | Diff
Updated regression tests + new XLargeTest (293.46 KB, patch)
2007-01-19 22:30 EST, Olivier Thomann CLA
no flags Details | Diff
1.7 vs 1.6 startup logs (58.66 KB, application/zip)
2007-01-23 17:17 EST, Andrey Loskutov CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andrey Loskutov CLA 2006-12-24 18:41:08 EST
Build ID: M20060921-0945

Steps To Reproduce:
I've found a strange performance degradation of ECJ generated code comparing with javac generated code, see full story at http://jroller.com/page/andyl?entry=sun_javac_vs_eclipse_ecj

AS IS:
Compile Eclipse 3.2.1 final sources with 1.6 target and 1.6 source and ECJ compiler, then try to start it with 1.6 JDK and:
java -XX:-FailOverToOldVerifier -Xverify:all -jar startup.jar -debug

This would fail with:
Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 589 in method org.eclipse.core.launcher.Main.processCommandLine([Ljava/lang/String;)[Ljava/lang/String; at offset 44

Starting same build with
java -XX:+FailOverToOldVerifier -Xverify:all -jar startup.jar -debug

works fine, and it seems (see https://jdk.dev.java.net/verifier.html) that 1.6 JDK silently switch from new (type-checking) verifier to the old one (inferencing), which then causes the runtime performance degradation of generated code (about 7%).

More information:

decompiled ECJ code looks like:

  // access flags 4
  protected processCommandLine([Ljava/lang/String;)[Ljava/lang/String;
   L0
    LINENUMBER 1029 L0
    ALOAD 1
    ARRAYLENGTH
    IFNE L1
   L2
    LINENUMBER 1030 L2
    ALOAD 1
    ARETURN
   L1
    LINENUMBER 1031 L1
   FRAME SAME
    ALOAD 1
    ARRAYLENGTH
    NEWARRAY T_INT
    ASTORE 2
   L3
    LINENUMBER 1032 L3
    ALOAD 2
    ICONST_0
    ICONST_M1
    IASTORE
   L4
    LINENUMBER 1033 L4
    ICONST_0
    ISTORE 3
   L5
    LINENUMBER 1034 L5
    ICONST_0
    ISTORE 4
   L6
    GOTO L7
   L8
    LINENUMBER 1035 L8
   FRAME APPEND [[I I I]
    ICONST_0
    ISTORE 5
   L9
    LINENUMBER 1038 L9
    ALOAD 1
    ILOAD 4
    AALOAD
    LDC "-debug"
    INVOKEVIRTUAL java/lang/String.equalsIgnoreCase(Ljava/lang/String;)Z
    IFEQ L10
   L11
    LINENUMBER 1039 L11
    ALOAD 0
    ICONST_1
    PUTFIELD org/eclipse/core/launcher/Main.debug : Z
   L12
    LINENUMBER 1041 L12
    GOTO L13
   L10
    LINENUMBER 1046 L10
   FRAME APPEND [I] <--------------- /// offset 44
    ALOAD 1
    ILOAD 4
    AALOAD
    LDC "-nosplash"
    INVOKEVIRTUAL java/lang/String.equalsIgnoreCase(Ljava/lang/String;)Z
    IFEQ L14
   L15
[...]

but I have no idea what is the problem here...
Comment 1 Olivier Thomann CLA 2006-12-24 21:40:29 EST
I'll investigate. This needs to be fixed asap.
Comment 2 Olivier Thomann CLA 2006-12-27 13:48:08 EST
Could you please provide the build id of the ecj compiler you used?
I tried with latest and I could not reproduce. I also tried with the version of the Eclipse compiler provided  by 3.2.1 and it doesn't fail.
So the build id is required for further investigation.
On your side, if you could try the Eclipse compiler from HEAD or 3.2.1 build, it would be great.
Decreasing severity since I cannot reproduce.
Thanks.
Comment 3 Olivier Thomann CLA 2006-12-27 13:48:56 EST
If you need it, I can provide you a ecj.jar corresponding to the HEAD contents.
Comment 4 Andrey Loskutov CLA 2006-12-27 14:28:03 EST
Hmm. I've used this url:
http://download.eclipse.org/eclipse/downloads/drops/R-3.2.1-200609210945/

There is a link to:
http://download.eclipse.org/eclipse/downloads/drops/R-3.2.1-200609210945/download.php?dropFile=eclipse-sourceBuild-srcIncluded-3.2.1.zip

I've downloaded this zip file, unpacked it, changed build.xml from root directory to compile with 1.6 source and target, as described in blog. Then I've just started build.bat from the root of directory:
build -os win32 -ws win32 -arch x86 -java5home F:\java\jdk1.6.0
Both java_home env. variable and java5home was pointing to same directory above.

And I think the first thing the build does is to compile ECJ from source with javac and then it uses the ecj.jar to build other stuff (see \jdtcoresrc\compilejdtcorewithjavac.xml in the zip file).

Basically I want to have "stable" 3.2.1 build, just compiled to 1.6 bytecode.

Which version of ECJ sources was included in this zip - no idea. I hope 3.2.1 :) but if you could point me where the compiler version is, I could check it. May be it is just a deployment problem.

I'm using stable release of JDK 1.6 for WinXp & Ant 1.6.2.

And yes, you could send me the jar file per email (I think it's too big for bugzilla), I would then try it (I would need to modify build file additionally to NOT to rebuild ecj.jar from sources as it does now).
Comment 5 Olivier Thomann CLA 2006-12-27 15:04:39 EST
The compiler source in this zip seems to be the one from 3.2.0. We fixed several problems in stack map generation since 3.2.0. So this could explain why it failed for you and not for me. I'll send you an updated jar. It would be nice if you could confirm that it works for you.
Thanks for your help.
Comment 6 Andrey Loskutov CLA 2006-12-27 16:07:30 EST
Created attachment 56207 [details]
classsloading log files with updated ecj.jar

Hmm, it is not better now with the new ecj.jar: 
Eclipse didn't start as before, but now WITHOUT any verifier message. I've started then with -verbose argument to see classloading, and stored results to the logs:

java -XX:-FailOverToOldVerifier -Xverify:all -verbose -jar startup.jar > error.log
java -XX:+FailOverToOldVerifier -Xverify:all -verbose -jar startup.jar > ok.log

You will see, that the difference starts now on loading of MRUBundleFileList, see line 616 in the ok/error log. Next line loads VerifyError in the error log, but BundleContextImpl in ok.log
Comment 7 Andrey Loskutov CLA 2006-12-27 16:45:39 EST
[offtopic]
It seems that Sun javac has also problems to generate good Eclipse bytecode with 1.6 target (I didn't find appropriated bug report in sun's bugs database): 

although you may start javac compiled Eclipse with "-XX:-FailOverToOldVerifier" without problems, but then when you would try to open Java editor, you would get this one:

java.lang.VerifyError: Bad access to protected <init> method in method org.eclipse.jdt.internal.ui.text.correction.QuickAssistLightBulbUpdater$AssistAnnotation.<clinit>()V at offset 8 at org.eclipse.jdt.internal.ui.text.correction.QuickAssistLightBulbUpdater.<init>(QuickAssistLightBulbUpdater.java:115)

Nobody is perfect :)
Comment 8 Andrey Loskutov CLA 2006-12-28 08:29:51 EST
I've tried now to do the same procedure with 3.3 M4 (using *included* ECJ sources, not the new ones), and I've got exactly the same error as in comment 0. 

Does it mean, that ECJ sources, included in all Eclipse source distributions since 3.2.0 are not updated at all (?!?) and deployment script(s) must be fixed? Could you verify if the appropriated version is included (at least in 3.3 M4), and if not, I would then open a separated bug for this deployment issue (if it is one).
Comment 9 Olivier Thomann CLA 2007-01-03 14:34:11 EST
I thought that the ECJ sources are the one from the previous milestone build.
In this case the sources for 3.3M4 are the same than the ones from 3.2.0. (i.e. the 3.2.0 sources, 0.670 from the compiler point of view).
I entered bug 169466 to track this issue.

I will rebuild Eclipse source using latest compiler version to track the issue with stack map tables.
Comment 10 Olivier Thomann CLA 2007-01-13 22:02:04 EST
Created attachment 56874 [details]
Proposed fix (first draft)

With this patch, I can rebuild Eclipse in 1.6 mode and run it successfully. At least I can open a Java editor without a problem.
I still need to polish it a bit, but I am hoping to release it in HEAD soon.
If you want a new version of the batch compiler ecj.jar to play with it, let me know.
Comment 11 Andrey Loskutov CLA 2007-01-14 03:51:46 EST
(In reply to comment #10)
> If you want a new version of the batch compiler ecj.jar to play with it, 
> let me know.

Thank you very much Olivier, may you send the "polished" version to my gmx account?
Comment 12 Olivier Thomann CLA 2007-01-19 09:09:00 EST
I still get this error with the polished version.
Caused by: java.lang.VerifyError: Bad access to protected <init> method in method org.eclipse.jdt.internal.compiler.util.GenericXMLWriter.<init>(Ljava/io/OutputStream;Ljava/lang/String;Z)V at offset 6
	at org.eclipse.jdt.internal.core.JavaProject.encodeClasspath(JavaProject.java:953)
	at org.eclipse.jdt.internal.core.JavaProject.saveClasspath(JavaProject.java:2617)
	at org.eclipse.jdt.internal.core.SetClasspathOperation.executeOperation(SetClasspathOperation.java:60)
	at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:720)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1781)
	at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:784)

But I don't understand it. I don't see why this is a problem since there is no protected access. All invoked methods are public. This looks very similar to the error you reported in comment 7.
If someone has any clue, please let me know.

  public GenericXMLWriter(java.io.OutputStream stream, java.lang.String lineSeparator, boolean printXmlVersion);
     0  aload_0 [this]
     1  new java.io.PrintWriter [3]
     4  dup
     5  aload_1 [stream]
     6  invokespecial java.io.PrintWriter(java.io.OutputStream) [73]
     9  aload_2 [lineSeparator]
    10  iload_3 [printXmlVersion]
    11  invokespecial org.eclipse.jdt.internal.compiler.util.GenericXMLWriter(java.io.Writer, java.lang.String, boolean) [76]
    14  return
      Line numbers:
        [pc: 0, line: 60]
        [pc: 14, line: 61]
      Local variable table:
        [pc: 0, pc: 15] local: this index: 0 type: org.eclipse.jdt.internal.compiler.util.GenericXMLWriter
        [pc: 0, pc: 15] local: stream index: 1 type: java.io.OutputStream
        [pc: 0, pc: 15] local: lineSeparator index: 2 type: java.lang.String
        [pc: 0, pc: 15] local: printXmlVersion index: 3 type: boolean

Comment 13 Ismael Juma CLA 2007-01-19 09:20:23 EST
By the way, I am not sure if this is relevant, but the latest JDK7 build (b06) has the following fix with title:

Bug 6504193[1] : typechecker incorrectly rejects valid classfiles when -XX:-FailOverToOldVerifier is specified

You can see this in the bugs fixed page[2]. The problem is that the bug's information does not seem to be available (perhaps it has security implications).

[1] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6504193
[2] http://download.java.net/jdk7/changes/jdk7-b06.html
Comment 14 Andrey Loskutov CLA 2007-01-19 09:25:09 EST
(In reply to comment #12)
> I still get this error with the polished version.
> Caused by: java.lang.VerifyError: Bad access to protected <init> method in
> method

I'm just wondering if this is an error in verifier itself? Last time I've tried to extract some smaller test case which would fail (compiled with javac) but I had no success - the code I've extracted (from comment 7) didn't fail if running in a small java app, so it was only reproducible in context of Eclipse startup...

If you have a better example which fails with both javac and ECJ, so I would post it as a verifier bug, because from my limited Java compiler knowledge there shouldn't be any "protected <init>" problems in the code.

Comment 15 Olivier Thomann CLA 2007-01-19 09:25:52 EST
yes, it looks like something might be wrong with the vm in this case.
I'll try to get the JDK7b06 and try again my recompiled Eclipse binaries.
The difference between the previous patch I had is that I didn't recompile the same sources exactly. In the first case I recompile Eclipse 3.2.1 and in the latter I recompiler this week integration build.
I'll try to rebuild Eclipse 3.2.1 code to see if I end up with the same problem.
Comment 16 Olivier Thomann CLA 2007-01-19 22:29:36 EST
Created attachment 57204 [details]
Polished patch

This should be the final patch unless issues are found with it.
Comment 17 Olivier Thomann CLA 2007-01-19 22:30:04 EST
Created attachment 57205 [details]
Updated regression tests + new XLargeTest
Comment 18 Olivier Thomann CLA 2007-01-22 14:48:53 EST
Fixed and released in HEAD.
Regression tests updated and new tests added in:
org.eclipse.jdt.core.tests.compiler.regression.StackMapAttributeTest#test026/027/028
org.eclipse.jdt.core.tests.compiler.regression.XLargeTest#test015.

Andrei,

Could you please confirm that everything works fine using a JDK7b06 VM? I don't have access to such VM yet.
Comment 19 Olivier Thomann CLA 2007-01-22 14:50:44 EST
Andrei, it would also be interesting to see if the performance issue is fixed.
We might need to do it with a JDK7b06 VM due the bug referenced in comment 13.
Comment 20 Andrey Loskutov CLA 2007-01-22 14:59:30 EST
Olivier, could you please send me the latest ecj.jar binary? Otherwise I guess I would need to wait for the M5?
Comment 21 Andrey Loskutov CLA 2007-01-23 16:33:47 EST
Hi Olivier, I have good news and not so good :)

Good news: I can now startup ecj/1.6 - compiled 3.2.1 Eclipse with  -XX:-FailOverToOldVerifier flag. I would test the performance later.

Now to the not so good news, and I not sure if it should be in the same bug?

1) JDK 1.6 verifier problems
After starting ecj/1.6 recompiled 3.2.1 Eclipse with -XX:-FailOverToOldVerifier flag on top of 1.6 JDK, I've created a new Java project, then a new package and a new class file inside. By opening this Java file in Java editor I see at least 2 different verifier errors, and the first one is new:

java.lang.VerifyError: Instruction type does not match stack map in method org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerDescriptor.computeCompletionProposals(Lorg/eclipse/jdt/ui/text/java/ContentAssistInvocationContext;Lorg/eclipse/core/runtime/IProgressMonitor;)Ljava/util/List; at offset 185

Second one is the old "protected <init>" problem we've already seen before:

java.lang.VerifyError: Bad access to protected <init> method in method org.eclipse.jdt.internal.ui.text.correction.QuickAssistLightBulbUpdater$AssistAnnotation.<clinit>()V at offset 8

and there of course a lot of Java Editor errors which just are followups of this two.

So for now it seems that the patch has introduced a new verifier problem.

2) JDK 1.7 problems

I've downloaded the latest available 1.7 binary JDK snapshot with version "build 1.7.0-ea-b06" from http://download.java.net/jdk7/binaries/, direct link is: http://download.java.net/download/jdk7/binaries/jdk-7-ea-bin-b06-windows-i586-18_jan_2007.exe
According to the build notes at http://download.java.net/jdk7/changes/jdk7-b06.html, the Bug 6504193 (see comment 13) should be fixed in this build.

With this JDK I have another problem: Eclipse didn't start at all, neither the original 3.2.1 nor the ecj/1.6 recompiled one, doesn't matter if I start it with default eclipse.exe or with java -jar command line, with or without any flags. Even the javac-recompiled 3.2.1 was not working... I guess 1.7 JDK is not yet stable enough to test it with Eclipse???

Interestingly, I was able to run SwingSet2 and Java2D sample applications included in 1.7 JDK without any problem...
Comment 22 Olivier Thomann CLA 2007-01-23 16:48:11 EST
(In reply to comment #21)
> java.lang.VerifyError: Instruction type does not match stack map in method
org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerDescriptor.computeCompletionProposals(Lorg/eclipse/jdt/ui/text/java/ContentAssistInvocationContext;Lorg/eclipse/core/runtime/IProgressMonitor;)Ljava/util/List;
> at offset 185
I'll check this one. I will open a new bug report for it. I don't think it is worth reopening this one.

> Second one is the old "protected <init>" problem we've already seen before:
Looks like a VM bug.

> With this JDK I have another problem: Eclipse didn't start at all, neither the
> original 3.2.1 nor the ecj/1.6 recompiled one, doesn't matter if I start it
> with default eclipse.exe or with java -jar command line, with or without any
> flags. Even the javac-recompiled 3.2.1 was not working... I guess 1.7 JDK is
> not yet stable enough to test it with Eclipse???
How does it fail? I don't have access to the b06 build of the JDK7 so I cannot investigate this failure right now.
Comment 23 Olivier Thomann CLA 2007-01-23 16:48:37 EST
And of course. Thank you for your investigation and time!
Comment 24 Andrey Loskutov CLA 2007-01-23 17:17:34 EST
Created attachment 57386 [details]
1.7 vs 1.6 startup logs

I've tried to start the *original* 3.2.1 eclipse with both JDK 1.6 and 1.7, and the logs are created by starting eclipse with this command line:
java -verbose:class -verbose:jni -jar startup.jar > 1.X.txt

With 1.6 JDK Eclipse starts just fine, as expected :)

In case of 1.7 JDK, eclipse just silently fails to start, I do not see any errors in log, even the workspace selection dialog couldn't be shown... 

P.S
Thank you to working on compiler :)
Comment 25 Olivier Thomann CLA 2007-01-23 17:29:23 EST
I opened bug 171472 and added you on the CC list.
Comment 26 Olivier Thomann CLA 2007-01-23 17:33:11 EST
(In reply to comment #24)
> Created an attachment (id=57386) [details]
> 1.7 vs 1.6 startup logs
I could not see anything special in them.

> I've tried to start the *original* 3.2.1 eclipse with both JDK 1.6 and 1.7, and
> the logs are created by starting eclipse with this command line:
> java -verbose:class -verbose:jni -jar startup.jar > 1.X.txt
> 
> With 1.6 JDK Eclipse starts just fine, as expected :)
> 
> In case of 1.7 JDK, eclipse just silently fails to start, I do not see any
> errors in log, even the workspace selection dialog couldn't be shown... 
Would be worth opening a bug against Platform/Runtime. Might not be a problem with JDT specifically.
 
> Thank you to working on compiler :)
You are welcome. I thank you for your dedication to solve this issue :-).

Comment 27 Andrey Loskutov CLA 2007-01-23 18:01:53 EST
Hmm, before creating a new bug about 1.7 JDK, I've tried to reproduce it with "fresh" eclipse with no workspace etc, and it starts now... Seems to be a workspace/configuration area related problem, so I will just skip this one.
Comment 28 Eric Jodet CLA 2007-02-06 06:19:18 EST
verified by user for 3.3 M5