Community
Participate
Working Groups
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...
I'll investigate. This needs to be fixed asap.
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.
If you need it, I can provide you a ecj.jar corresponding to the HEAD contents.
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).
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.
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
[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 :)
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).
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.
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.
(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?
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
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
(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.
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.
Created attachment 57204 [details] Polished patch This should be the final patch unless issues are found with it.
Created attachment 57205 [details] Updated regression tests + new XLargeTest
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.
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.
Olivier, could you please send me the latest ecj.jar binary? Otherwise I guess I would need to wait for the M5?
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...
(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.
And of course. Thank you for your investigation and time!
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 :)
I opened bug 171472 and added you on the CC list.
(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 :-).
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.
verified by user for 3.3 M5