From andreas.lundblad at oracle.com Sun Mar 1 10:43:47 2015 From: andreas.lundblad at oracle.com (Andreas Lundblad) Date: Sun, 1 Mar 2015 11:43:47 +0100 Subject: RFR: 8054717: SJavac should track changes in the public apis of classpath classes! In-Reply-To: <54EE5481.7070605@oracle.com> References: <20141127012617.GA17122@e6430> <20141204155932.GC28610@e6430> <20141211104528.GA18525@e6430> <20141215224906.GB6858@e6430> <20150212215046.GA6527@e6430> <54EE5481.7070605@oracle.com> Message-ID: <20150301104346.GB3466@e6430> On Wed, Feb 25, 2015 at 03:02:25PM -0800, Jonathan Gibbons wrote: > > On 02/12/2015 01:50 PM, Andreas Lundblad wrote: > > + $1_JAVAC_FLAGS := -bootclasspath "/home/alundbla/bootcp" -classpath "$$($1_CLASSPATH)" > > I doubt that any change should contain references to your personal > home directory. Obviously. I thought I'll leave it to Erik to figure out the best way to create a temporary dummy directory. Just wanted to include enough instructions to try out the sjavac-patch in the JDK-build. -- Andreas From andreas.lundblad at oracle.com Sun Mar 1 11:15:55 2015 From: andreas.lundblad at oracle.com (Andreas Lundblad) Date: Sun, 1 Mar 2015 12:15:55 +0100 Subject: RFR: 8054717: SJavac should track changes in the public apis of classpath classes! In-Reply-To: <20150212215046.GA6527@e6430> References: <20141127012617.GA17122@e6430> <20141204155932.GC28610@e6430> <20141211104528.GA18525@e6430> <20141215224906.GB6858@e6430> <20150212215046.GA6527@e6430> Message-ID: <20150301111554.GC3466@e6430> On Thu, Feb 12, 2015 at 10:50:47PM +0100, Andreas Lundblad wrote: > On Mon, Dec 15, 2014 at 11:49:06PM +0100, Andreas Lundblad wrote: > > [...] > > > > Link to web review: > > http://cr.openjdk.java.net/~alundblad/8054717 > > > > Link to bug report: > > http://bugs.openjdk.java.net/browse/JDK-8054717 > Attach: /home/alundbla/Downloads/langtools_v0.diff JDK-8066725 patch > > Version 5 up for review. (See links above.) > > A few remarks: > > 1. The attached langtools patch (currently under review) needs to be applied as well. > > 2. Two changes to CompileJavaModules.gmk are required: > - The classpath should be used instead of the bootclasspath (and the bootclasspath should be set to an empty direcotry) > > - $1_JAVAC_FLAGS := -bootclasspath "$$($1_CLASSPATH)" > + $1_JAVAC_FLAGS := -bootclasspath "/home/alundbla/bootcp" -classpath "$$($1_CLASSPATH)" > > - Eriks current workaround should be disabled: > > - $$(if $$(filter-out $$($1_SRCS), $$?), $(FIND) $$(@D) -name "*.class" $(FIND_DELETE)) > +# $$(if $$(filter-out $$($1_SRCS), $$?), $(FIND) $$(@D) -name "*.class" $(FIND_DELETE)) Here's the current status of this work: - The blocking class reader issue (JDK-8066725) has now been resolved and pushed - Joel reviewed this patch a while ago. Since then I've fixed a couple of bugs found by Erik (without changing the overall structure). - When building a different repo, Erik discovered another issue regarding deprecation warnings. This does however reproduce without this patch applied (and was in fact independently reported by Per Liden a while ago). I filed issue JDK-8074071 to track this, but I suggest we address this in a separate patch. In other words: I'm ready to push this work. (I'm however unsure if Joels slighly dated review is 'valid'.) We should definitely address the deprecation issue before thinking about making sjavac default in the JDK build. -- Andreas From erik.joelsson at oracle.com Mon Mar 2 08:42:58 2015 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Mon, 02 Mar 2015 09:42:58 +0100 Subject: RFR: 8054717: SJavac should track changes in the public apis of classpath classes! In-Reply-To: <20150301111554.GC3466@e6430> References: <20141127012617.GA17122@e6430> <20141204155932.GC28610@e6430> <20141211104528.GA18525@e6430> <20141215224906.GB6858@e6430> <20150212215046.GA6527@e6430> <20150301111554.GC3466@e6430> Message-ID: <54F42292.8080708@oracle.com> Sounds good to me. So you think I should do the makefile changes to adapt the JDK build to this patch in a separate bug? /Erik On 2015-03-01 12:15, Andreas Lundblad wrote: > On Thu, Feb 12, 2015 at 10:50:47PM +0100, Andreas Lundblad wrote: >> On Mon, Dec 15, 2014 at 11:49:06PM +0100, Andreas Lundblad wrote: >>> [...] >>> >>> Link to web review: >>> http://cr.openjdk.java.net/~alundblad/8054717 >>> >>> Link to bug report: >>> http://bugs.openjdk.java.net/browse/JDK-8054717 >> Attach: /home/alundbla/Downloads/langtools_v0.diff JDK-8066725 patch >> >> Version 5 up for review. (See links above.) >> >> A few remarks: >> >> 1. The attached langtools patch (currently under review) needs to be applied as well. >> >> 2. Two changes to CompileJavaModules.gmk are required: >> - The classpath should be used instead of the bootclasspath (and the bootclasspath should be set to an empty direcotry) >> >> - $1_JAVAC_FLAGS := -bootclasspath "$$($1_CLASSPATH)" >> + $1_JAVAC_FLAGS := -bootclasspath "/home/alundbla/bootcp" -classpath "$$($1_CLASSPATH)" >> >> - Eriks current workaround should be disabled: >> >> - $$(if $$(filter-out $$($1_SRCS), $$?), $(FIND) $$(@D) -name "*.class" $(FIND_DELETE)) >> +# $$(if $$(filter-out $$($1_SRCS), $$?), $(FIND) $$(@D) -name "*.class" $(FIND_DELETE)) > Here's the current status of this work: > > - The blocking class reader issue (JDK-8066725) has now been resolved and pushed > > - Joel reviewed this patch a while ago. Since then I've fixed a couple of bugs found by Erik (without changing the overall structure). > > - When building a different repo, Erik discovered another issue regarding deprecation warnings. This does however reproduce without this patch applied (and was in fact independently reported by Per Liden a while ago). I filed issue JDK-8074071 to track this, but I suggest we address this in a separate patch. > > In other words: I'm ready to push this work. (I'm however unsure if Joels slighly dated review is 'valid'.) We should definitely address the deprecation issue before thinking about making sjavac default in the JDK build. > > -- Andreas From andreas.lundblad at oracle.com Mon Mar 2 12:31:13 2015 From: andreas.lundblad at oracle.com (Andreas Lundblad) Date: Mon, 2 Mar 2015 13:31:13 +0100 Subject: RFR: 8054717: SJavac should track changes in the public apis of classpath classes! In-Reply-To: <54F42292.8080708@oracle.com> References: <20141127012617.GA17122@e6430> <20141204155932.GC28610@e6430> <20141211104528.GA18525@e6430> <20141215224906.GB6858@e6430> <20150212215046.GA6527@e6430> <20150301111554.GC3466@e6430> <54F42292.8080708@oracle.com> Message-ID: <20150302123112.GB11414@e6430> On Mon, Mar 02, 2015 at 09:42:58AM +0100, Erik Joelsson wrote: > Sounds good to me. So you think I should do the makefile changes to > adapt the JDK build to this patch in a separate bug? I'm not sure what's best, but I don't think we need a separate bug-entry. If you give me a pointer (or patch) on how to create/clean up a dummy empty bootclasspath directory, I can do the push. -- Andreas From erik.joelsson at oracle.com Tue Mar 3 11:17:12 2015 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Tue, 03 Mar 2015 12:17:12 +0100 Subject: RFR: 8054717: SJavac should track changes in the public apis of classpath classes! In-Reply-To: <20150302123112.GB11414@e6430> References: <20141127012617.GA17122@e6430> <20141204155932.GC28610@e6430> <20141211104528.GA18525@e6430> <20141215224906.GB6858@e6430> <20150212215046.GA6527@e6430> <20150301111554.GC3466@e6430> <54F42292.8080708@oracle.com> <20150302123112.GB11414@e6430> Message-ID: <54F59838.1040405@oracle.com> Hello, Here is my suggestion for makefile changes to go with the sjavac changes. Adding build-dev to get review for my part. Webrev: http://cr.openjdk.java.net/~erikj/8054717/webrev.root.01/ Bug: https://bugs.openjdk.java.net/browse/JDK-8054717 /Erik On 2015-03-02 13:31, Andreas Lundblad wrote: > On Mon, Mar 02, 2015 at 09:42:58AM +0100, Erik Joelsson wrote: >> Sounds good to me. So you think I should do the makefile changes to >> adapt the JDK build to this patch in a separate bug? > I'm not sure what's best, but I don't think we need a separate bug-entry. > > If you give me a pointer (or patch) on how to create/clean up a dummy empty bootclasspath directory, I can do the push. > > -- Andreas From erik.joelsson at oracle.com Tue Mar 3 11:53:33 2015 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Tue, 03 Mar 2015 12:53:33 +0100 Subject: RFR: 8054717: SJavac should track changes in the public apis of classpath classes! In-Reply-To: <54F59838.1040405@oracle.com> References: <20141127012617.GA17122@e6430> <20141204155932.GC28610@e6430> <20141211104528.GA18525@e6430> <20141215224906.GB6858@e6430> <20150212215046.GA6527@e6430> <20150301111554.GC3466@e6430> <54F42292.8080708@oracle.com> <20150302123112.GB11414@e6430> <54F59838.1040405@oracle.com> Message-ID: <54F5A0BD.6060506@oracle.com> That combination didn't actually build for me. When compiling jdk.jconsole, the following happened: java.lang.RuntimeException: com.sun.tools.javac.code.Symbol$CompletionFailure: class file for java.awt.datatransfer.UnsupportedFlavorException not found at com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:143) at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:92) at com.sun.tools.sjavac.comp.SjavacImpl.compile(SjavacImpl.java:129) at com.sun.tools.sjavac.comp.PooledSjavac.lambda$compile$65(PooledSjavac.java:80) at com.sun.tools.sjavac.comp.PooledSjavac$$Lambda$4/703614162.call(Unknown Source) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:744) Caused by: com.sun.tools.javac.code.Symbol$CompletionFailure: class file for java.awt.datatransfer.UnsupportedFlavorException not found From what I can tell, jdk.jconsole uses java.desktop, which uses java.datatransfer (and re-exports it), where the missing class is. My best guess is that something in sjavac (API checking?) needs to traverse down into the transitive dependencies. This might be wrong, but as a workaround, it's easiest to fix in the makefiles so that we can have a working sjavac enabled jdk build. Here is an updated webrev which adds 3 levels (should cover everything I think) of transitive dependencies on the classpath when compiling modules: http://cr.openjdk.java.net/~erikj/8054717/webrev.root.02/ /Erik On 2015-03-03 12:17, Erik Joelsson wrote: > Hello, > > Here is my suggestion for makefile changes to go with the sjavac > changes. Adding build-dev to get review for my part. > > Webrev: http://cr.openjdk.java.net/~erikj/8054717/webrev.root.01/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8054717 > > /Erik > > On 2015-03-02 13:31, Andreas Lundblad wrote: >> On Mon, Mar 02, 2015 at 09:42:58AM +0100, Erik Joelsson wrote: >>> Sounds good to me. So you think I should do the makefile changes to >>> adapt the JDK build to this patch in a separate bug? >> I'm not sure what's best, but I don't think we need a separate >> bug-entry. >> >> If you give me a pointer (or patch) on how to create/clean up a dummy >> empty bootclasspath directory, I can do the push. >> >> -- Andreas > From magnus.ihse.bursie at oracle.com Tue Mar 3 12:53:02 2015 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Tue, 03 Mar 2015 13:53:02 +0100 Subject: RFR: 8054717: SJavac should track changes in the public apis of classpath classes! In-Reply-To: <54F5A0BD.6060506@oracle.com> References: <20141127012617.GA17122@e6430> <20141204155932.GC28610@e6430> <20141211104528.GA18525@e6430> <20141215224906.GB6858@e6430> <20150212215046.GA6527@e6430> <20150301111554.GC3466@e6430> <54F42292.8080708@oracle.com> <20150302123112.GB11414@e6430> <54F59838.1040405@oracle.com> <54F5A0BD.6060506@oracle.com> Message-ID: <54F5AEAE.9070001@oracle.com> On 2015-03-03 12:53, Erik Joelsson wrote: > That combination didn't actually build for me. When compiling > jdk.jconsole, the following happened: > > java.lang.RuntimeException: > com.sun.tools.javac.code.Symbol$CompletionFailure: class file for > java.awt.datatransfer.UnsupportedFlavorException not found > at > com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:143) > at > com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:92) > at com.sun.tools.sjavac.comp.SjavacImpl.compile(SjavacImpl.java:129) > at > com.sun.tools.sjavac.comp.PooledSjavac.lambda$compile$65(PooledSjavac.java:80) > at > com.sun.tools.sjavac.comp.PooledSjavac$$Lambda$4/703614162.call(Unknown Source) > > at java.util.concurrent.FutureTask.run(FutureTask.java:266) > at > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) > at > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) > at java.lang.Thread.run(Thread.java:744) > Caused by: com.sun.tools.javac.code.Symbol$CompletionFailure: class > file for java.awt.datatransfer.UnsupportedFlavorException not found > > From what I can tell, jdk.jconsole uses java.desktop, which uses > java.datatransfer (and re-exports it), where the missing class is. My > best guess is that something in sjavac (API checking?) needs to > traverse down into the transitive dependencies. This might be wrong, > but as a workaround, it's easiest to fix in the makefiles so that we > can have a working sjavac enabled jdk build. > > Here is an updated webrev which adds 3 levels (should cover everything > I think) of transitive dependencies on the classpath when compiling > modules: > > http://cr.openjdk.java.net/~erikj/8054717/webrev.root.02/ I'm not quite following this. This change affects the dependency calculation even when not using sjavac, right? Will that not cause any issues? What is the reasoning with the 3 levels? Is that the maximum depth currently in the JDK? Also, a minor nit, I thought we'd agreed to get rid of the $BUILD/tmp directory, and store intermediate build stuff in support or make-support. /Magnus From erik.joelsson at oracle.com Tue Mar 3 14:03:24 2015 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Tue, 03 Mar 2015 15:03:24 +0100 Subject: RFR: 8054717: SJavac should track changes in the public apis of classpath classes! In-Reply-To: <54F5AEAE.9070001@oracle.com> References: <20141127012617.GA17122@e6430> <20141204155932.GC28610@e6430> <20141211104528.GA18525@e6430> <20141215224906.GB6858@e6430> <20150212215046.GA6527@e6430> <20150301111554.GC3466@e6430> <54F42292.8080708@oracle.com> <20150302123112.GB11414@e6430> <54F59838.1040405@oracle.com> <54F5A0BD.6060506@oracle.com> <54F5AEAE.9070001@oracle.com> Message-ID: <54F5BF2C.9000407@oracle.com> On 2015-03-03 13:53, Magnus Ihse Bursie wrote: > On 2015-03-03 12:53, Erik Joelsson wrote: >> That combination didn't actually build for me. When compiling >> jdk.jconsole, the following happened: >> >> java.lang.RuntimeException: >> com.sun.tools.javac.code.Symbol$CompletionFailure: class file for >> java.awt.datatransfer.UnsupportedFlavorException not found >> at >> com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:143) >> at >> com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:92) >> at com.sun.tools.sjavac.comp.SjavacImpl.compile(SjavacImpl.java:129) >> at >> com.sun.tools.sjavac.comp.PooledSjavac.lambda$compile$65(PooledSjavac.java:80) >> at >> com.sun.tools.sjavac.comp.PooledSjavac$$Lambda$4/703614162.call(Unknown >> Source) >> at java.util.concurrent.FutureTask.run(FutureTask.java:266) >> at >> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) >> at >> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) >> at java.lang.Thread.run(Thread.java:744) >> Caused by: com.sun.tools.javac.code.Symbol$CompletionFailure: class >> file for java.awt.datatransfer.UnsupportedFlavorException not found >> >> From what I can tell, jdk.jconsole uses java.desktop, which uses >> java.datatransfer (and re-exports it), where the missing class is. My >> best guess is that something in sjavac (API checking?) needs to >> traverse down into the transitive dependencies. This might be wrong, >> but as a workaround, it's easiest to fix in the makefiles so that we >> can have a working sjavac enabled jdk build. >> >> Here is an updated webrev which adds 3 levels (should cover >> everything I think) of transitive dependencies on the classpath when >> compiling modules: >> >> http://cr.openjdk.java.net/~erikj/8054717/webrev.root.02/ > > I'm not quite following this. This change affects the dependency > calculation even when not using sjavac, right? Will that not cause any > issues? What is the reasoning with the 3 levels? Is that the maximum > depth currently in the JDK? > I changed this to only affect SJAVAC_ENABLED builds. The implementation of FindTransitiveDependenciesForModule was taken from another branch where I had already needed it for a different reason. There, 3 levels happened to be enough and applying this patch solved the problem with sjavac, so I took it as it was for now. > Also, a minor nit, I thought we'd agreed to get rid of the $BUILD/tmp > directory, and store intermediate build stuff in support or make-support. > Right, I moved it to support. New webrev: http://cr.openjdk.java.net/~erikj/8054717/webrev.root.03/ /Erik From magnus.ihse.bursie at oracle.com Tue Mar 3 14:07:53 2015 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Tue, 03 Mar 2015 15:07:53 +0100 Subject: RFR: 8054717: SJavac should track changes in the public apis of classpath classes! In-Reply-To: <54F5BF2C.9000407@oracle.com> References: <20141127012617.GA17122@e6430> <20141204155932.GC28610@e6430> <20141211104528.GA18525@e6430> <20141215224906.GB6858@e6430> <20150212215046.GA6527@e6430> <20150301111554.GC3466@e6430> <54F42292.8080708@oracle.com> <20150302123112.GB11414@e6430> <54F59838.1040405@oracle.com> <54F5A0BD.6060506@oracle.com> <54F5AEAE.9070001@oracle.com> <54F5BF2C.9000407@oracle.com> Message-ID: <54F5C039.6010801@oracle.com> On 2015-03-03 15:03, Erik Joelsson wrote: > > On 2015-03-03 13:53, Magnus Ihse Bursie wrote: >> On 2015-03-03 12:53, Erik Joelsson wrote: >>> That combination didn't actually build for me. When compiling >>> jdk.jconsole, the following happened: >>> >>> java.lang.RuntimeException: >>> com.sun.tools.javac.code.Symbol$CompletionFailure: class file for >>> java.awt.datatransfer.UnsupportedFlavorException not found >>> at >>> com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:143) >>> at >>> com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:92) >>> at >>> com.sun.tools.sjavac.comp.SjavacImpl.compile(SjavacImpl.java:129) >>> at >>> com.sun.tools.sjavac.comp.PooledSjavac.lambda$compile$65(PooledSjavac.java:80) >>> at >>> com.sun.tools.sjavac.comp.PooledSjavac$$Lambda$4/703614162.call(Unknown >>> Source) >>> at java.util.concurrent.FutureTask.run(FutureTask.java:266) >>> at >>> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) >>> at >>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) >>> at java.lang.Thread.run(Thread.java:744) >>> Caused by: com.sun.tools.javac.code.Symbol$CompletionFailure: class >>> file for java.awt.datatransfer.UnsupportedFlavorException not found >>> >>> From what I can tell, jdk.jconsole uses java.desktop, which uses >>> java.datatransfer (and re-exports it), where the missing class is. >>> My best guess is that something in sjavac (API checking?) needs to >>> traverse down into the transitive dependencies. This might be wrong, >>> but as a workaround, it's easiest to fix in the makefiles so that we >>> can have a working sjavac enabled jdk build. >>> >>> Here is an updated webrev which adds 3 levels (should cover >>> everything I think) of transitive dependencies on the classpath when >>> compiling modules: >>> >>> http://cr.openjdk.java.net/~erikj/8054717/webrev.root.02/ >> >> I'm not quite following this. This change affects the dependency >> calculation even when not using sjavac, right? Will that not cause >> any issues? What is the reasoning with the 3 levels? Is that the >> maximum depth currently in the JDK? >> > I changed this to only affect SJAVAC_ENABLED builds. The > implementation of FindTransitiveDependenciesForModule was taken from > another branch where I had already needed it for a different reason. > There, 3 levels happened to be enough and applying this patch solved > the problem with sjavac, so I took it as it was for now. >> Also, a minor nit, I thought we'd agreed to get rid of the $BUILD/tmp >> directory, and store intermediate build stuff in support or >> make-support. >> > Right, I moved it to support. > > New webrev: http://cr.openjdk.java.net/~erikj/8054717/webrev.root.03/ Thanks. I'm happy now! :-) /Magnus From jan.lahoda at oracle.com Wed Mar 4 16:02:52 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Wed, 04 Mar 2015 17:02:52 +0100 Subject: History data for "JDK-8058150: Compile for Specific Platform Version" In-Reply-To: <54F0A14E.7080401@oracle.com> References: <54F02B54.3030700@oracle.com> <54F07590.90509@oracle.com> <54F0940F.7060007@oracle.com> <54F09CBE.200@oracle.com> <54F0A14E.7080401@oracle.com> Message-ID: <54F72CAC.5060001@oracle.com> Magnus, Jon, As per your suggestions, I've split the ct.sym.txt into several files approximately per (current) module. I've changed to format to a baseline+change files as well. The biggest file is java.desktop baseline (OpenJDK 7 content) which is <5MB, followed by java.base baseline whose size is ~4.5MB. The total size of all these files inside the .hg folder is still ~1.7MB. The files can be seen here: http://hg.openjdk.java.net/jdk9/sandbox/file/7f017edb8377/make/data/symbols An example of the change file: http://hg.openjdk.java.net/jdk9/sandbox/file/7f017edb8377/make/data/symbols/jdk.dev-8.sym.txt Does this look reasonable? Thanks for your help! Jan On 27.2.2015 17:54, Jonathan Gibbons wrote: > On 02/27/2015 08:35 AM, Magnus Ihse Bursie wrote: >> On 2015-02-27 16:58, Jan Lahoda wrote: >>> On 27.2.2015 14:48, Magnus Ihse Bursie wrote: >>>> Hi Jan, >>>> >>>> On 2015-02-27 09:31, Jan Lahoda wrote: >>>>> Hi, >>>>> >>>>> I have a question on JDK-8058150: "Compile for Specific Platform >>>>> Version". To support compilation for older versions of the platform, >>>>> javac will need some description of the APIs as they existed in the >>>>> target platforms. >>>>> >>>>> For this, the current proposal is to use lib/ct.sym file (similar, but >>>>> different, to the JDK 8 lib/ct.sym), containing classfiles of the >>>>> older APIs. This file would be constructed at build time from a >>>>> textual representation of the APIs stored in an OpenJDK repository >>>>> (currently called ct.sym.txt). >>>>> >>>>> The current ct.sym.txt is a single file that contains APIs for all >>>>> supported versions, reusing entries for multiple versions when needed. >>>>> An alternative would be to use ct7.sym.txt for JDK 7 APIs, ct8.sym.txt >>>>> for JDK 8 APIs, etc. Using a single file leads to a smaller total size >>>>> (as it reuses entries where it can), but needs to be considerably >>>>> changed when a new version is added or an obsolete version is removed. >>>>> >>>>> The size of the file is considerable: for the "ct.sym.txt" that >>>>> represents APIs from OpenJDK 7 and 8, the size of the checked-out file >>>>> in the working copy is (currently[2]) ~23MB, and inside the .hg >>>>> directory, the file has ~1.7MB (Mercurial is apparently able to >>>>> compress the ct.sym.txt file very well - but as all history is kept >>>>> inside .hg directory, the size of the file inside the .hg directory >>>>> increases when the ct.sym.txt is updated). >>>> >>>> In my opinion, the only size that matters here is in the .hg directory. >>>> If the workspace takes 23 MB more or less is a non-issue when a full >>>> forest clone is in the gigabyte range. But I don't think 1.7 MB extra >>>> for the top-level repo is much of a problem either. Since the top-level >>>> repo currently is so tiny, it will grow noticably in percentage. But >>>> compare this with hotspot/.hg on 67 MB or jdk/.hg on 351 MB. >>> >>> Thanks. I also think the size inside the .hg folder is more important. >>> >>>> >>>> If you have a proper text format so future edits can be made as trivial >>>> diffs, then the mercurial storage will not grow noticable in the future >>>> either. >>> >>> The file currently contains version numbers on most lines, so adding >>> or removing a support for a platform version means a significant >>> update to the file. I am thinking of some ways to limit that, though. >> >> I peaked at your current solution. Is it possible to store the file as >> a baseline version (JDK 7, or however far back you want to go) and a >> set of deltas? Instead of like: >> header extends java/lang/Object flags 31 classAnnotations >> @Ljdk/Profile+Annotation;(value=I4) versions 78 >> method name descriptor ()V flags 8 versions 78 >> method name descriptor ()V flags 1 versions 8 >> method name getHostId descriptor ()Ljava/lang/String; flags 1 versions 7 >> >> Store it like: >> baseline-jdk7.sym.txt >> header extends java/lang/Object flags 31 classAnnotations >> @Ljdk/Profile+Annotation;(value=I4) >> method name descriptor ()V flags 8 >> >> jdk8.sym.txt >> +method name descriptor ()V flags 1 >> -method name getHostId descriptor ()Ljava/lang/String; flags 1 >> >> ? >> >> In fact, if it is not too expensive to generate this kind of file from >> the build, you could perhaps do it the other way round, and create a >> "baseline" for the current JDK just built, and just store the diffs to >> previous versions. (Although that might be a maintainence burden to >> make sure that these reverse diffs are up to date). >> >> >>> >>>> >>>>> Another alternative would be to partition the file into several >>>>> smaller files - would be easier to grasp, but if the files would be >>>>> too small, the compression would be worse (leading to bigger >>>>> repositories). >>>> What is the actual difference? Having too large files can be burdensome >>>> on other tools as well, eg. if you open it (mistakenly or not) in a >>>> text >>>> editor. I would tend to prefer several smaller files than one huge. >>> >>> That depends on how is the file split up. Originally, I was thinking >>> of having a file per package, but that produces (too) many small >>> files - 797 files, the biggest one having ~650kB (in the working >>> copy), consumes ~5.9MB total inside .hg. >> Can you match it to modules? I realize older JDKs has no module >> concept, but that sounds like it could be a reasonable number of >> reasonable sized chunks. >> >> /Magnus >> >>> >>> There was a proposal to have a single ct.sym file per each jar file >>> on the bootclasspath (in the target platform), but this produces >>> ~20MB (in the working copy) file for ct.sym, while the next biggest >>> file is for nashorn.jar: ~1MB (in the working copy). This consumes >>> ~1.7MB inside the .hg directory. >>> >>> I tried to split the big ct.sym.txt artificially at approximately >>> 1MB, this leads to 23 files, and still consumes ~1.7MB inside the .hg >>> directory. >>> >>>>> Currently, the proposal is to place the ct.sym.txt file into the >>>>> top-level repository. A prototype of this feature is currently in the >>>>> jdk9/sandbox forest, on branch JDK-8058150-branch. The current >>>>> ct.sym.txt file is >>>>> /make/data/symbols/ct.sym.txt. >>>> Sounds like a good place to put such a file. I assume it will be >>>> processed during building? >>> >>> Yes, the file is processed during build and the ct.sym file in >>> produced into the "lib" directory. In my current prototype, I've >>> tweaked the make/Images.gmk to do that: >>> http://hg.openjdk.java.net/jdk9/sandbox/file/087692cc2663/make/Images.gmk >>> >>> (in the "ct.sym" section). >>> >>> Thanks for the comments, >>> Jan >>> >>>> >>>> /Magnus >> > > > Magnus, > > The simplified generalization of your suggestion would be to simply use > patch/diff files. > > We could have a baseline of (say) > > jdk7.sym.txt > > then have a patch file > > jdk8.sym.patch > > which can be applied (in the build) to jdk7.sym.txt to get jdk8.sym.txt > > Since the .txt and .patch files reflect existing releases, they would > almost never change, so the .hg files would be constant. > > Maybe once in a while, we would prune the history, remove older version > info, and add a new baseline. > > -- Jon From staffan.larsen at oracle.com Fri Mar 6 13:30:37 2015 From: staffan.larsen at oracle.com (Staffan Larsen) Date: Fri, 6 Mar 2015 14:30:37 +0100 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: <3CB05A58-C466-4F91-A405-694F2ADDA401@oracle.com> References: <54E1D71A.1080906@univ-mlv.fr> <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> <313ABEF2-036C-4E7F-A15D-F3240E417629@oracle.com> <3CB05A58-C466-4F91-A405-694F2ADDA401@oracle.com> Message-ID: I would like to backport this bug fix to jdk8 - does anyone see any problems with that? The patch applies cleanly (after shuffling) and the java/lang/invoke/ tests succeed. Thanks, /Staffan From forax at univ-mlv.fr Fri Mar 6 14:09:08 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Fri, 06 Mar 2015 15:09:08 +0100 Subject: RFR: JDK-8025636 Hide lambda proxy frames in stacktraces In-Reply-To: References: <54E1D71A.1080906@univ-mlv.fr> <7AE8811E-F669-480E-AD91-8300561BD8B7@oracle.com> <313ABEF2-036C-4E7F-A15D-F3240E417629@oracle.com> <3CB05A58-C466-4F91-A405-694F2ADDA401@oracle.com> Message-ID: <54F9B504.6070208@univ-mlv.fr> On 03/06/2015 02:30 PM, Staffan Larsen wrote: > I would like to backport this bug fix to jdk8 - does anyone see any problems with that? The patch applies cleanly (after shuffling) and the java/lang/invoke/ tests succeed. > > Thanks, > /Staffan I see no problem, quite the opposite, please backport it, nobody like big stack traces. R?mi From magnus.ihse.bursie at oracle.com Fri Mar 6 14:52:42 2015 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Fri, 06 Mar 2015 15:52:42 +0100 Subject: History data for "JDK-8058150: Compile for Specific Platform Version" In-Reply-To: <54F72CAC.5060001@oracle.com> References: <54F02B54.3030700@oracle.com> <54F07590.90509@oracle.com> <54F0940F.7060007@oracle.com> <54F09CBE.200@oracle.com> <54F0A14E.7080401@oracle.com> <54F72CAC.5060001@oracle.com> Message-ID: <54F9BF3A.2020804@oracle.com> On 2015-03-04 17:02, Jan Lahoda wrote: > Magnus, Jon, > > As per your suggestions, I've split the ct.sym.txt into several files > approximately per (current) module. I've changed to format to a > baseline+change files as well. The biggest file is java.desktop > baseline (OpenJDK 7 content) which is <5MB, followed by java.base > baseline whose size is ~4.5MB. The total size of all these files > inside the .hg folder is still ~1.7MB. > > The files can be seen here: > http://hg.openjdk.java.net/jdk9/sandbox/file/7f017edb8377/make/data/symbols > > > An example of the change file: > http://hg.openjdk.java.net/jdk9/sandbox/file/7f017edb8377/make/data/symbols/jdk.dev-8.sym.txt > > > Does this look reasonable? Most definitely! I think you've found a sweetspot between too many small and too few large files. Also, the baselining seems reasonable. Hopefully future changes can be stored as highly compressible diffs. /Magnus From joel.franck at oracle.com Mon Mar 9 20:07:41 2015 From: joel.franck at oracle.com (=?utf-8?Q?Joel_Borggr=C3=A9n-Franck?=) Date: Mon, 9 Mar 2015 21:07:41 +0100 Subject: Annotated Type bugs in OpenJDK 8 In-Reply-To: References: <54EE1BB6.5010205@oracle.com> <54EE5847.6000706@oracle.com> <6470DE5A-712A-46EF-91E1-B09BA69037FB@oracle.com> Message-ID: <427A69A8-C51F-4AAB-9EB7-E498D64C87ED@oracle.com> Hi, > On 28 feb 2015, at 03:09, Joshua Humphries wrote: > > While working on tests for the changes I'm making, I've come across at least two other bugs. > > One is in core reflection: sun.reflect.annotation.TypeAnnotationParser#parseAnnotatedBounds is computing the wrong start index if the first type argument is a parameterized type but represents a class (vs. an interface). That is easy enough to include in the patch I am working on. > > Another seems to be in the compiler. I have a case where the wrong location info is being recorded (for a class type parameter bound), so when we rehydrate the annotations, they get attributed to the wrong part of the type parameter. (I haven't dug into this one yet at all, but I do at least have a repro case.) > > > But this brings up a question: should I add additional bug reports for everything I find as I'm working on this patch? Since I am not a member, I cannot interact with the bug tracking system, other than to submit an anonymous bug through http://bugs.java.com/. (At least that I know of: if there are other ways for me to submit info for bugs, I'd be glad to hear it.) If you post an example of the error here on compiler-dev I hope one of my colleagues will pick it up and file a bug. > > Also, are there any guidelines as to how/when to break changes into multiple patches? Would it be okay if I try to include all fixes in a single patch (which is what I'm currently doing)? Or do I need to make a separate patch per bug? Or does it depend on the size of the changes (e.g. handful of small changes may be fine to combine into single patch)? > I prefer smaller fixes and I would guess that potential reviewers for this will agree. Also since only parts of the work can be backported I think it makes sense to split it up. cheers /Joel From vicente.romero at oracle.com Wed Mar 11 06:46:24 2015 From: vicente.romero at oracle.com (Vicente-Arturo Romero-Zaldivar) Date: Tue, 10 Mar 2015 23:46:24 -0700 Subject: tiered attribution for all Message-ID: <54FFE4C0.3080008@oracle.com> Hi all, Starting from today the repository for tiered attribution [1] is live and is ready for testing at [2]. The base code for tiered attribution is current javac9 code. The main goal of this project is to rewrite the core of the javac compiler: type attribution. We want code that is easier to maintain. The side effect is that we are producing a very very fast compiler, for some people the fastest in the west :) If you wanna give it a try just clone the repo at [2], build it, and please let us know about your experience. Please send comments, bug reports, and how-can-javac-be-that-fast questions to [3] :) *Disclaimer* Not all regression tests are passing right now. This is still a beta version. Much failing tests are tests with golden files for which the currently produced output doesn't match the golden file. The code is still being cleaned up, we are working on it. Tiered attribution won't imply changes to the JVM so currently we are only maintaining the repository at [2]. If you want to use the latest JVM code to test tiered attribution you can get it from [4]. Thanks, Vicente [1] http://openjdk.java.net/jeps/215 [2] http://hg.openjdk.java.net/tiered-attrib/dev/langtools [3] tiered-attrib-dev at openjdk.java.net [4] http://hg.openjdk.java.net/jdk9/dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Wed Mar 11 18:24:05 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 11 Mar 2015 11:24:05 -0700 Subject: tiered attribution for all In-Reply-To: <54FFE4C0.3080008@oracle.com> References: <54FFE4C0.3080008@oracle.com> Message-ID: <55008845.70706@oracle.com> Vicente, Thanks for sharing this, and for the work that has gone into this so far. -- Jon On 03/10/2015 11:46 PM, Vicente-Arturo Romero-Zaldivar wrote: > Hi all, > > Starting from today the repository for tiered attribution [1] is live > and is ready for testing at [2]. The base code for tiered attribution > is current javac9 code. The main goal of this project is to rewrite > the core of the javac compiler: type attribution. We want code that is > easier to maintain. The side effect is that we are producing a very > very fast compiler, for some people the fastest in the west :) > > If you wanna give it a try just clone the repo at [2], build it, and > please let us know about your experience. Please send comments, bug > reports, and how-can-javac-be-that-fast questions to [3] :) > > *Disclaimer* > > Not all regression tests are passing right now. This is still a beta > version. Much failing tests are tests with golden files for which the > currently produced output doesn't match the golden file. The code is > still being cleaned up, we are working on it. Tiered attribution won't > imply changes to the JVM so currently we are only maintaining the > repository at [2]. If you want to use the latest JVM code to test > tiered attribution you can get it from [4]. > > Thanks, > Vicente > > [1] http://openjdk.java.net/jeps/215 > [2] http://hg.openjdk.java.net/tiered-attrib/dev/langtools > [3] tiered-attrib-dev at openjdk.java.net > [4] http://hg.openjdk.java.net/jdk9/dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From vicente.romero at oracle.com Wed Mar 11 18:31:46 2015 From: vicente.romero at oracle.com (Vicente-Arturo Romero-Zaldivar) Date: Wed, 11 Mar 2015 11:31:46 -0700 Subject: tiered attribution for all In-Reply-To: <55008845.70706@oracle.com> References: <54FFE4C0.3080008@oracle.com> <55008845.70706@oracle.com> Message-ID: <55008A12.4090101@oracle.com> On 03/11/2015 11:24 AM, Jonathan Gibbons wrote: > Vicente, > > Thanks for sharing this, and for the work that has gone into this so far. Thanks! Vicente > > -- Jon > > On 03/10/2015 11:46 PM, Vicente-Arturo Romero-Zaldivar wrote: >> Hi all, >> >> Starting from today the repository for tiered attribution [1] is live >> and is ready for testing at [2]. The base code for tiered attribution >> is current javac9 code. The main goal of this project is to rewrite >> the core of the javac compiler: type attribution. We want code that >> is easier to maintain. The side effect is that we are producing a >> very very fast compiler, for some people the fastest in the west :) >> >> If you wanna give it a try just clone the repo at [2], build it, and >> please let us know about your experience. Please send comments, bug >> reports, and how-can-javac-be-that-fast questions to [3] :) >> >> *Disclaimer* >> >> Not all regression tests are passing right now. This is still a beta >> version. Much failing tests are tests with golden files for which the >> currently produced output doesn't match the golden file. The code is >> still being cleaned up, we are working on it. Tiered attribution >> won't imply changes to the JVM so currently we are only maintaining >> the repository at [2]. If you want to use the latest JVM code to test >> tiered attribution you can get it from [4]. >> >> Thanks, >> Vicente >> >> [1] http://openjdk.java.net/jeps/215 >> [2] http://hg.openjdk.java.net/tiered-attrib/dev/langtools >> [3] tiered-attrib-dev at openjdk.java.net >> [4] http://hg.openjdk.java.net/jdk9/dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lowasser at google.com Wed Mar 11 21:01:26 2015 From: lowasser at google.com (Louis Wasserman) Date: Wed, 11 Mar 2015 21:01:26 +0000 Subject: String concatenation tweaks Message-ID: OpenJDK's implementation of String concatenation compiles "foo" + bar + "quux" + baz into essentially the same bytecode as new StringBuilder() .append("foo") .append(bar) .append("quux") .append(baz) .toString() We've been successfully experimenting at Google with presizing the StringBuilder to avoid the need for rebuffering, with extensive consultation with martinrb@ and cushon at . I have not yet ported the patch to head, but wanted to bounce the idea off this list before doing so. Some key points of interest: - It suffices to provide an upper bound on the size, if that's not too much bigger than the real length. For example, for primitives, we use the bound of the maximum length of the toString of that primitive type: for example, a boolean is treated as having length bounded at 5. - Nonconstant Objects, including CharSequences, have their toString stored in a local. For example, "foo" + myStringBuilder would be compiled to approximately String myStringBuilderToString = myStringBuilder.toString(); return new StringBuilder(3 + myStringBuilderToString.length()) .append("foo") .append(myStringBuilderToString) .toString(); This is necessary to deal with the possibility of mutation midexpression. (Nonconstant primitives are also stored in a local to preserve evaluation order and avoid mutation, but not converted to Strings. There might be some room for optimization here for primitive values coming from final fields or locals.) - Some mostly-redundant null checking is necessary to deal with the evil edge case where toString() returns null. - Taking all the above into account, our benchmarks showed 15% CPU improvements and 25% fewer bytes allocated relative to the status quo, independent of -XX:+OptimizeStringConcat. - While we were at it, in the case of two arguments that are statically known to be Strings, our benchmarks show String.concat to be firmly more efficient than the StringBuilder, even in the presence of flags like -XX:+OptimizeStringConcat. This is arguably a separate optimization, but nonetheless effective; our benchmarks at the time suggested 40% CPU improvements and 60% fewer bytes allocated relative to the status quo. So for example, "foo" + myInt + myString + "bar" + myObj would be compiled to the equivalent of int myIntTmp = myInt; String myStringTmp = String.valueOf(myString); // defend against null String myObjTmp = String.valueOf(String.valueOf(myObj)); // defend against evil toString implementations returning null return new StringBuilder( 17 // length of "foo" (3) + max length of myInt (11) + length of "bar" (3) + myStringTmp.length() + myObjTmp.length()) .append("foo") .append(myIntTmp) .append(myStringTmp) .append("bar") .append(myObjTmp) .toString(); As far as language constraints go, the JLS is (apparently deliberately) vague about how string concatenation is implemented. "An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression." We see no reason this approach would not qualify as a "similar technique." If these suggestions (and performance numbers) are of interest, I can port our patch for upstream use. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex.buckley at oracle.com Thu Mar 12 01:13:51 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 11 Mar 2015 18:13:51 -0700 Subject: String concatenation tweaks In-Reply-To: References: Message-ID: <5500E84F.3080800@oracle.com> On 3/11/2015 2:01 PM, Louis Wasserman wrote: > So for example, "foo" + myInt + myString + "bar" + myObj would be > compiled to the equivalent of > > int myIntTmp = myInt; > String myStringTmp = String.valueOf(myString); // defend against null > String myObjTmp = String.valueOf(String.valueOf(myObj)); // defend > against evil toString implementations returning null > > return new StringBuilder( > 17 // length of "foo" (3) + max length of myInt (11) + length of > "bar" (3) > + myStringTmp.length() > + myObjTmp.length()) > .append("foo") > .append(myIntTmp) > .append(myStringTmp) > .append("bar") > .append(myObjTmp) > .toString(); > > As far as language constraints go, the JLS is (apparently deliberately) > vague about how string concatenation is implemented. "An implementation > may choose to perform conversion and concatenation in one step to avoid > creating and then discarding an intermediate String object. To increase > the performance of repeated string concatenation, a Java compiler may > use the StringBuffer class or a similar technique to reduce the number > of intermediate String objects that are created by evaluation of an > expression." We see no reason this approach would not qualify as a > "similar technique." The really key property of the string concatenation operator is left-associativity. Later subexpressions must not be evaluated until earlier subexpressions have been successfully evaluated AND concatenated. Consider this expression: "foo" + m() + n() which JLS8 15.8 specifies to mean: ("foo" + m()) + n() We know from JLS8 15.6 that if m() throws, then foo+m() throws, and n() will never be evaluated. Happily, your translation doesn't appear to catch and swallow exceptions when eagerly evaluating each subexpression in turn, so I believe you won't evaluate n() if m() already threw. Unhappily, a call to append(..) can in general fail with OutOfMemoryError. (I'm not talking about asynchronous exceptions in general, but rather the sense that append(..) manipulates the heap so an OOME is at least plausible.) In the OpenJDK implementation, if blah.append(m()) fails with OOME, then n() hasn't been evaluated yet -- that's "real" left-associativity. In the proposed implementation, it's possible that more memory is available when evaluating m() and n() upfront than at the time of an append call, so n() is evaluated even if append(<>) fails -- that's not left-associative. Perhaps you can set my mind at ease that append(..) can't fail with OOME? Alex From jeremymanson at google.com Thu Mar 12 05:26:08 2015 From: jeremymanson at google.com (Jeremy Manson) Date: Wed, 11 Mar 2015 22:26:08 -0700 Subject: String concatenation tweaks In-Reply-To: <5500E84F.3080800@oracle.com> References: <5500E84F.3080800@oracle.com> Message-ID: Isn't Louis's proposed behavior equivalent to saying "the rightmost concatenation threw an OOME" instead of "some concatenation in the middle threw an OOME"? It's true that the intermediate String concatenations haven't occurred at that point, but in the JDK's current implementation, that's true, too: the concatenations that have occurred at that point are StringBuilder ones, not String ones. If any of the append operations throws an OOME, no Strings have been created at all, either in Louis's implementation or in the JDK's. Ultimately, isn't this a quality of implementation issue? And if so, isn't it a quality of implementation issue that doesn't provide any additional quality? I can't imagine code whose semantics relies on this, and if they do, they are relying on something implementation-dependent. Jeremy On Wed, Mar 11, 2015 at 6:13 PM, Alex Buckley wrote: > On 3/11/2015 2:01 PM, Louis Wasserman wrote: > >> So for example, "foo" + myInt + myString + "bar" + myObj would be >> compiled to the equivalent of >> >> int myIntTmp = myInt; >> String myStringTmp = String.valueOf(myString); // defend against null >> String myObjTmp = String.valueOf(String.valueOf(myObj)); // defend >> against evil toString implementations returning null >> >> return new StringBuilder( >> 17 // length of "foo" (3) + max length of myInt (11) + length of >> "bar" (3) >> + myStringTmp.length() >> + myObjTmp.length()) >> .append("foo") >> .append(myIntTmp) >> .append(myStringTmp) >> .append("bar") >> .append(myObjTmp) >> .toString(); >> >> As far as language constraints go, the JLS is (apparently deliberately) >> vague about how string concatenation is implemented. "An implementation >> may choose to perform conversion and concatenation in one step to avoid >> creating and then discarding an intermediate String object. To increase >> the performance of repeated string concatenation, a Java compiler may >> use the StringBuffer class or a similar technique to reduce the number >> of intermediate String objects that are created by evaluation of an >> expression." We see no reason this approach would not qualify as a >> "similar technique." >> > > The really key property of the string concatenation operator is > left-associativity. Later subexpressions must not be evaluated until > earlier subexpressions have been successfully evaluated AND concatenated. > Consider this expression: > > "foo" + m() + n() > > which JLS8 15.8 specifies to mean: > > ("foo" + m()) + n() > > We know from JLS8 15.6 that if m() throws, then foo+m() throws, and n() > will never be evaluated. > > Happily, your translation doesn't appear to catch and swallow exceptions > when eagerly evaluating each subexpression in turn, so I believe you won't > evaluate n() if m() already threw. > > Unhappily, a call to append(..) can in general fail with OutOfMemoryError. > (I'm not talking about asynchronous exceptions in general, but rather the > sense that append(..) manipulates the heap so an OOME is at least > plausible.) In the OpenJDK implementation, if blah.append(m()) fails with > OOME, then n() hasn't been evaluated yet -- that's "real" > left-associativity. In the proposed implementation, it's possible that more > memory is available when evaluating m() and n() upfront than at the time of > an append call, so n() is evaluated even if append(<>) > fails -- that's not left-associative. > > Perhaps you can set my mind at ease that append(..) can't fail with OOME? > > Alex > -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Thu Mar 12 07:03:23 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 12 Mar 2015 08:03:23 +0100 Subject: String concatenation tweaks In-Reply-To: References: Message-ID: <55013A3B.6010101@univ-mlv.fr> Hi Louis, On 03/11/2015 10:01 PM, Louis Wasserman wrote: > OpenJDK's implementation of String concatenation compiles > > "foo" + bar + "quux" + baz > > into essentially the same bytecode as > > new StringBuilder() > .append("foo") > .append(bar) > .append("quux") > .append(baz) > .toString() > > We've been successfully experimenting at Google with presizing the > StringBuilder to avoid the need for rebuffering, with extensive > consultation with martinrb@ and cushon at . I have not yet ported the > patch to head, but wanted to bounce the idea off this list before > doing so. Some key points of interest: > > * It suffices to provide an upper bound on the size, if that's not > too much bigger than the real length. For example, for > primitives, we use the bound of the maximum length of the toString > of that primitive type: for example, a boolean is treated as > having length bounded at 5. > * Nonconstant Objects, including CharSequences, have their toString > stored in a local. For example, "foo" + myStringBuilder would be > compiled to approximately > > String myStringBuilderToString = myStringBuilder.toString(); > return new StringBuilder(3 + myStringBuilderToString.length()) > .append("foo") > .append(myStringBuilderToString) > .toString(); > > This is necessary to deal with the possibility of mutation > midexpression. > Interresting, here you have two optimizations, one is to call toString() and store the result in local variable for each objects to append, the second one is to try to pre-calculate the size of the resulting String. Do you have done some measurement of former without being combined with the later ? I ask that because I think that the code of OptimizeStringConcat only works if Hotspot is able to determine that all the objects to append are Strings. > * (Nonconstant primitives are also stored in a local to preserve > evaluation order and avoid mutation, but not converted to > Strings. There might be some room for optimization here for > primitive values coming from final fields or locals.) > * Some mostly-redundant null checking is necessary to deal with the > evil edge case where toString() returns null. > valueOf(valueOf(x)) is quite ugly but i don't see how to do better :( > * Taking all the above into account, our benchmarks showed 15% CPU > improvements and 25% fewer bytes allocated relative to the status > quo, independent of -XX:+OptimizeStringConcat. > * While we were at it, in the case of two arguments that are > statically known to be Strings, our benchmarks show String.concat > to be firmly more efficient than the StringBuilder, even in the > presence of flags like -XX:+OptimizeStringConcat. This is > arguably a separate optimization, but nonetheless effective; our > benchmarks at the time suggested 40% CPU improvements and 60% > fewer bytes allocated relative to the status quo. > > So for example, "foo" + myInt + myString + "bar" + myObj would be > compiled to the equivalent of > > int myIntTmp = myInt; > String myStringTmp = String.valueOf(myString); // defend against null > String myObjTmp = String.valueOf(String.valueOf(myObj)); // defend > against evil toString implementations returning null > > return new StringBuilder( > 17 // length of "foo" (3) + max length of myInt (11) + length of > "bar" (3) > + myStringTmp.length() > + myObjTmp.length()) > .append("foo") > .append(myIntTmp) > .append(myStringTmp) > .append("bar") > .append(myObjTmp) > .toString(); > > As far as language constraints go, the JLS is (apparently > deliberately) vague about how string concatenation is implemented. > "An implementation may choose to perform conversion and concatenation > in one step to avoid creating and then discarding an intermediate > String object. To increase the performance of repeated string > concatenation, a Java compiler may use the StringBuffer class or a > similar technique to reduce the number of intermediate String objects > that are created by evaluation of an expression." We see no reason > this approach would not qualify as a "similar technique." > > If these suggestions (and performance numbers) are of interest, I can > port our patch for upstream use. cheers, R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From dawid.weiss at gmail.com Thu Mar 12 08:03:10 2015 From: dawid.weiss at gmail.com (Dawid Weiss) Date: Thu, 12 Mar 2015 09:03:10 +0100 Subject: String concatenation tweaks In-Reply-To: <5500E84F.3080800@oracle.com> References: <5500E84F.3080800@oracle.com> Message-ID: Hello. Very interesting discussion. I just wanted to observe that while Alex's statement is an interesting theoretical debate with regard to the specification: > Unhappily, a call to append(..) can in general fail with OutOfMemoryError. in reality if such a situation happens and you're running so close to heap exhaustion then whether a method got called during string concatenation or not is probably of small practical importance (because the program is very likely to crash anyway, even when concatenating/ formatting any further exception messages...). I am not advocating to violate the spec, just trying to be realistic. Dawid From aleksey.shipilev at oracle.com Thu Mar 12 08:34:04 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Thu, 12 Mar 2015 11:34:04 +0300 Subject: String concatenation tweaks In-Reply-To: References: Message-ID: <55014F7C.20201@oracle.com> Hi Louis, I am not really fond of doing the optimizations on javac level: asking users to recompile their programs for better performance and/or fixing the (probable) javac bugs is arguably against what users expect. But in this case, changing the bytecode shape before hitting the JIT compiler seems to be the sanest route. JIT compilers have to maintain more strong invariants than most users let on, see e.g.: https://bugs.openjdk.java.net/browse/JDK-8043677 On 03/12/2015 12:01 AM, Louis Wasserman wrote: > * While we were at it, in the case of two arguments that are > statically known to be Strings, our benchmarks show String.concat to > be firmly more efficient than the StringBuilder, even in the > presence of flags like -XX:+OptimizeStringConcat. This is arguably > a separate optimization, but nonetheless effective; our benchmarks > at the time suggested 40% CPU improvements and 60% fewer bytes > allocated relative to the status quo. I agree, this is a separate issue, probably against the JIT compiler itself. > If these suggestions (and performance numbers) are of interest, I can > port our patch for upstream use. I am interested in this patch, pending the evaluation order questions are resolved. Thanks, -Aleksey. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From alex.buckley at oracle.com Thu Mar 12 23:28:20 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 12 Mar 2015 16:28:20 -0700 Subject: String concatenation tweaks In-Reply-To: References: <5500E84F.3080800@oracle.com> Message-ID: <55022114.8040904@oracle.com> More abstract presentation. Given the expression: "foo" + m() + n() you must not evaluate n() if evaluation of "foo" + m() completes abruptly. The proposed implementation evaluates n() regardless. All is not lost. In the proposed implementation, the abrupt completion of "foo" + m() could occur because an append call fails or (thanks to Jon for pointing this out) the StringBuilder ctor fails. The quality-of-implementation issue is thus: if the proposed implementation is of sufficiently high quality to guarantee that the ctor and the first append both succeed, then the evaluation of "foo" + m() will always complete normally, and it would be an unobservable (thus acceptable) implementation detail to evaluate n() early. Alex On 3/11/2015 10:26 PM, Jeremy Manson wrote: > Isn't Louis's proposed behavior equivalent to saying "the rightmost > concatenation threw an OOME" instead of "some concatenation in the > middle threw an OOME"? > > It's true that the intermediate String concatenations haven't occurred > at that point, but in the JDK's current implementation, that's true, > too: the concatenations that have occurred at that point are > StringBuilder ones, not String ones. If any of the append operations > throws an OOME, no Strings have been created at all, either in Louis's > implementation or in the JDK's. > > Ultimately, isn't this a quality of implementation issue? And if so, > isn't it a quality of implementation issue that doesn't provide any > additional quality? I can't imagine code whose semantics relies on > this, and if they do, they are relying on something > implementation-dependent. > > Jeremy > > On Wed, Mar 11, 2015 at 6:13 PM, Alex Buckley > wrote: > > On 3/11/2015 2:01 PM, Louis Wasserman wrote: > > So for example, "foo" + myInt + myString + "bar" + myObj would be > compiled to the equivalent of > > int myIntTmp = myInt; > String myStringTmp = String.valueOf(myString); // defend against > null > String myObjTmp = String.valueOf(String.valueOf(__myObj)); // defend > against evil toString implementations returning null > > return new StringBuilder( > 17 // length of "foo" (3) + max length of myInt (11) + > length of > "bar" (3) > + myStringTmp.length() > + myObjTmp.length()) > .append("foo") > .append(myIntTmp) > .append(myStringTmp) > .append("bar") > .append(myObjTmp) > .toString(); > > As far as language constraints go, the JLS is (apparently > deliberately) > vague about how string concatenation is implemented. "An > implementation > may choose to perform conversion and concatenation in one step > to avoid > creating and then discarding an intermediate String object. To > increase > the performance of repeated string concatenation, a Java > compiler may > use the StringBuffer class or a similar technique to reduce the > number > of intermediate String objects that are created by evaluation of an > expression." We see no reason this approach would not qualify as a > "similar technique." > > > The really key property of the string concatenation operator is > left-associativity. Later subexpressions must not be evaluated until > earlier subexpressions have been successfully evaluated AND > concatenated. Consider this expression: > > "foo" + m() + n() > > which JLS8 15.8 specifies to mean: > > ("foo" + m()) + n() > > We know from JLS8 15.6 that if m() throws, then foo+m() throws, and > n() will never be evaluated. > > Happily, your translation doesn't appear to catch and swallow > exceptions when eagerly evaluating each subexpression in turn, so I > believe you won't evaluate n() if m() already threw. > > Unhappily, a call to append(..) can in general fail with > OutOfMemoryError. (I'm not talking about asynchronous exceptions in > general, but rather the sense that append(..) manipulates the heap > so an OOME is at least plausible.) In the OpenJDK implementation, if > blah.append(m()) fails with OOME, then n() hasn't been evaluated yet > -- that's "real" left-associativity. In the proposed implementation, > it's possible that more memory is available when evaluating m() and > n() upfront than at the time of an append call, so n() is evaluated > even if append(<>) fails -- that's not > left-associative. > > Perhaps you can set my mind at ease that append(..) can't fail with > OOME? > > Alex > > From lowasser at google.com Fri Mar 13 01:01:01 2015 From: lowasser at google.com (Louis Wasserman) Date: Fri, 13 Mar 2015 01:01:01 +0000 Subject: String concatenation tweaks In-Reply-To: <55022114.8040904@oracle.com> References: <5500E84F.3080800@oracle.com> <55022114.8040904@oracle.com> Message-ID: I confess I'm not sure how that "quality" goal would be achievable in bytecode without deliberately allocating arrays we then discard. For what it's worth, delaying or avoiding OOMEs seems a desirable goal in general, and up to a constant multiplicative factor, this implementation seems to allocate the same amount in the same order. That is, we're still computing m().toString() before n().toString(), and up to a constant multiplicative factor, m().toString() allocates the same number of bytes as the StringBuilder the status quo generates. So if m() does something like allocate a char[Integer.MAX_VALUE], we still OOM at the appropriate time. Other notes: this implementation would tend to decrease maximum allocation, so it'd reduce OOMEs. Also, since the StringBuilder will never need further expansion and we're only using the String and primitive overloads of append, the only way for append to OOME would be in append(float) and append(double), which allocate a FloatingDecimal (which may, in turn, allocate a new thread-local char[26] if one isn't already there). On Thu, Mar 12, 2015 at 4:28 PM Alex Buckley wrote: > More abstract presentation. Given the expression: > > "foo" + m() + n() > > you must not evaluate n() if evaluation of "foo" + m() completes > abruptly. The proposed implementation evaluates n() regardless. > > All is not lost. In the proposed implementation, the abrupt completion > of "foo" + m() could occur because an append call fails or (thanks to > Jon for pointing this out) the StringBuilder ctor fails. The > quality-of-implementation issue is thus: if the proposed implementation > is of sufficiently high quality to guarantee that the ctor and the first > append both succeed, then the evaluation of "foo" + m() will always > complete normally, and it would be an unobservable (thus acceptable) > implementation detail to evaluate n() early. > > Alex > > On 3/11/2015 10:26 PM, Jeremy Manson wrote: > > Isn't Louis's proposed behavior equivalent to saying "the rightmost > > concatenation threw an OOME" instead of "some concatenation in the > > middle threw an OOME"? > > > > It's true that the intermediate String concatenations haven't occurred > > at that point, but in the JDK's current implementation, that's true, > > too: the concatenations that have occurred at that point are > > StringBuilder ones, not String ones. If any of the append operations > > throws an OOME, no Strings have been created at all, either in Louis's > > implementation or in the JDK's. > > > > Ultimately, isn't this a quality of implementation issue? And if so, > > isn't it a quality of implementation issue that doesn't provide any > > additional quality? I can't imagine code whose semantics relies on > > this, and if they do, they are relying on something > > implementation-dependent. > > > > Jeremy > > > > On Wed, Mar 11, 2015 at 6:13 PM, Alex Buckley > > wrote: > > > > On 3/11/2015 2:01 PM, Louis Wasserman wrote: > > > > So for example, "foo" + myInt + myString + "bar" + myObj would be > > compiled to the equivalent of > > > > int myIntTmp = myInt; > > String myStringTmp = String.valueOf(myString); // defend against > > null > > String myObjTmp = String.valueOf(String.valueOf(__myObj)); // > defend > > against evil toString implementations returning null > > > > return new StringBuilder( > > 17 // length of "foo" (3) + max length of myInt (11) + > > length of > > "bar" (3) > > + myStringTmp.length() > > + myObjTmp.length()) > > .append("foo") > > .append(myIntTmp) > > .append(myStringTmp) > > .append("bar") > > .append(myObjTmp) > > .toString(); > > > > As far as language constraints go, the JLS is (apparently > > deliberately) > > vague about how string concatenation is implemented. "An > > implementation > > may choose to perform conversion and concatenation in one step > > to avoid > > creating and then discarding an intermediate String object. To > > increase > > the performance of repeated string concatenation, a Java > > compiler may > > use the StringBuffer class or a similar technique to reduce the > > number > > of intermediate String objects that are created by evaluation of > an > > expression." We see no reason this approach would not qualify > as a > > "similar technique." > > > > > > The really key property of the string concatenation operator is > > left-associativity. Later subexpressions must not be evaluated until > > earlier subexpressions have been successfully evaluated AND > > concatenated. Consider this expression: > > > > "foo" + m() + n() > > > > which JLS8 15.8 specifies to mean: > > > > ("foo" + m()) + n() > > > > We know from JLS8 15.6 that if m() throws, then foo+m() throws, and > > n() will never be evaluated. > > > > Happily, your translation doesn't appear to catch and swallow > > exceptions when eagerly evaluating each subexpression in turn, so I > > believe you won't evaluate n() if m() already threw. > > > > Unhappily, a call to append(..) can in general fail with > > OutOfMemoryError. (I'm not talking about asynchronous exceptions in > > general, but rather the sense that append(..) manipulates the heap > > so an OOME is at least plausible.) In the OpenJDK implementation, if > > blah.append(m()) fails with OOME, then n() hasn't been evaluated yet > > -- that's "real" left-associativity. In the proposed implementation, > > it's possible that more memory is available when evaluating m() and > > n() upfront than at the time of an append call, so n() is evaluated > > even if append(<>) fails -- that's not > > left-associative. > > > > Perhaps you can set my mind at ease that append(..) can't fail with > > OOME? > > > > Alex > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex.buckley at oracle.com Fri Mar 13 19:59:05 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 13 Mar 2015 12:59:05 -0700 Subject: String concatenation tweaks In-Reply-To: References: <5500E84F.3080800@oracle.com> <55022114.8040904@oracle.com> Message-ID: <55034189.4000900@oracle.com> I do recognize that the proposed implementation doesn't reorder the evaluation of subexpressions. When discussing the proposed implementation of '+' -- whose key element is calling append(String) with a pre-computed value -- I was careful to set aside asynchronous OOMEs, but I see that even synchronous OOMEs are sidetracking us. My concern is not heap pressure; my concern is arbitrary unchecked exceptions arising from the (int) and append(String) calls. For sake of argument, I'll simplify "unchecked exceptions" to just RuntimeExceptions, not Errors. If you can guarantee that no RuntimeExceptions are thrown synchronously during the execution of those method bodies on the JVM, then '+' cannot fail and the timing of subexpression evaluation is unobservable (ordering is still observable, as required). I think this guarantee is just a matter of reviewing the method bodies. Alex On 3/12/2015 6:01 PM, Louis Wasserman wrote: > I confess I'm not sure how that "quality" goal would be achievable in > bytecode without deliberately allocating arrays we then discard. > > For what it's worth, delaying or avoiding OOMEs seems a desirable goal > in general, and up to a constant multiplicative factor, this > implementation seems to allocate the same amount in the same order. > That is, we're still computing m().toString() before n().toString(), and > up to a constant multiplicative factor, m().toString() allocates the > same number of bytes as the StringBuilder the status quo generates. So > if m() does something like allocate a char[Integer.MAX_VALUE], we still > OOM at the appropriate time. > > Other notes: this implementation would tend to decrease maximum > allocation, so it'd reduce OOMEs. Also, since the StringBuilder will > never need further expansion and we're only using the String and > primitive overloads of append, the only way for append to OOME would be > in append(float) and append(double), which allocate a FloatingDecimal > (which may, in turn, allocate a new thread-local char[26] if one isn't > already there). > > On Thu, Mar 12, 2015 at 4:28 PM Alex Buckley > wrote: > > More abstract presentation. Given the expression: > > "foo" + m() + n() > > you must not evaluate n() if evaluation of "foo" + m() completes > abruptly. The proposed implementation evaluates n() regardless. > > All is not lost. In the proposed implementation, the abrupt completion > of "foo" + m() could occur because an append call fails or (thanks to > Jon for pointing this out) the StringBuilder ctor fails. The > quality-of-implementation issue is thus: if the proposed implementation > is of sufficiently high quality to guarantee that the ctor and the first > append both succeed, then the evaluation of "foo" + m() will always > complete normally, and it would be an unobservable (thus acceptable) > implementation detail to evaluate n() early. > > Alex > > On 3/11/2015 10:26 PM, Jeremy Manson wrote: > > Isn't Louis's proposed behavior equivalent to saying "the rightmost > > concatenation threw an OOME" instead of "some concatenation in the > > middle threw an OOME"? > > > > It's true that the intermediate String concatenations haven't > occurred > > at that point, but in the JDK's current implementation, that's true, > > too: the concatenations that have occurred at that point are > > StringBuilder ones, not String ones. If any of the append operations > > throws an OOME, no Strings have been created at all, either in > Louis's > > implementation or in the JDK's. > > > > Ultimately, isn't this a quality of implementation issue? And if so, > > isn't it a quality of implementation issue that doesn't provide any > > additional quality? I can't imagine code whose semantics relies on > > this, and if they do, they are relying on something > > implementation-dependent. > > > > Jeremy > > > > On Wed, Mar 11, 2015 at 6:13 PM, Alex Buckley > > > >> wrote: > > > > On 3/11/2015 2:01 PM, Louis Wasserman wrote: > > > > So for example, "foo" + myInt + myString + "bar" + myObj > would be > > compiled to the equivalent of > > > > int myIntTmp = myInt; > > String myStringTmp = String.valueOf(myString); // defend > against > > null > > String myObjTmp = > String.valueOf(String.valueOf(____myObj)); // defend > > against evil toString implementations returning null > > > > return new StringBuilder( > > 17 // length of "foo" (3) + max length of myInt (11) + > > length of > > "bar" (3) > > + myStringTmp.length() > > + myObjTmp.length()) > > .append("foo") > > .append(myIntTmp) > > .append(myStringTmp) > > .append("bar") > > .append(myObjTmp) > > .toString(); > > > > As far as language constraints go, the JLS is (apparently > > deliberately) > > vague about how string concatenation is implemented. "An > > implementation > > may choose to perform conversion and concatenation in one > step > > to avoid > > creating and then discarding an intermediate String > object. To > > increase > > the performance of repeated string concatenation, a Java > > compiler may > > use the StringBuffer class or a similar technique to > reduce the > > number > > of intermediate String objects that are created by > evaluation of an > > expression." We see no reason this approach would not > qualify as a > > "similar technique." > > > > > > The really key property of the string concatenation operator is > > left-associativity. Later subexpressions must not be > evaluated until > > earlier subexpressions have been successfully evaluated AND > > concatenated. Consider this expression: > > > > "foo" + m() + n() > > > > which JLS8 15.8 specifies to mean: > > > > ("foo" + m()) + n() > > > > We know from JLS8 15.6 that if m() throws, then foo+m() > throws, and > > n() will never be evaluated. > > > > Happily, your translation doesn't appear to catch and swallow > > exceptions when eagerly evaluating each subexpression in > turn, so I > > believe you won't evaluate n() if m() already threw. > > > > Unhappily, a call to append(..) can in general fail with > > OutOfMemoryError. (I'm not talking about asynchronous > exceptions in > > general, but rather the sense that append(..) manipulates the > heap > > so an OOME is at least plausible.) In the OpenJDK > implementation, if > > blah.append(m()) fails with OOME, then n() hasn't been > evaluated yet > > -- that's "real" left-associativity. In the proposed > implementation, > > it's possible that more memory is available when evaluating > m() and > > n() upfront than at the time of an append call, so n() is > evaluated > > even if append(<>) fails -- that's not > > left-associative. > > > > Perhaps you can set my mind at ease that append(..) can't > fail with > > OOME? > > > > Alex > > > > > From lowasser at google.com Fri Mar 13 21:40:28 2015 From: lowasser at google.com (Louis Wasserman) Date: Fri, 13 Mar 2015 21:40:28 +0000 Subject: String concatenation tweaks In-Reply-To: <55034189.4000900@oracle.com> References: <5500E84F.3080800@oracle.com> <55022114.8040904@oracle.com> <55034189.4000900@oracle.com> Message-ID: Got it. I think the only cases we have to worry about, then, are buffer size overflows resulting in NegativeArraySizeException, or possibly an explicitly thrown OutOfMemoryError (which is StringBuilder's response when the buffer size tries to exceed Integer.MAX_VALUE). I think we might conceivably deal with this by rewriting the bytecode to -- I think we can improve on this with jump hackery to avoid repetition, but essentially -- int length = 3; // sum of the constant strings; we can check that this won't overflow at compile time but I think it couldn't no matter what because of method length constraints String mStr = m().toString(); length += mStr.length(); if (length < 0) { throw new OutOfMemoryError(); } String nStr = n().toString(); length += nStr.length(); if (length < 0) { throw new OutOfMemoryError(); } This continues to expand the bytecode, but probably manageably -- we don't actually need a local for length; if (int < 0) is easy in bytecode, and we can have only one OOME site that all the ifs jump to? On Fri, Mar 13, 2015 at 12:59 PM Alex Buckley wrote: > I do recognize that the proposed implementation doesn't reorder the > evaluation of subexpressions. > > When discussing the proposed implementation of '+' -- whose key element > is calling append(String) with a pre-computed value -- I was careful to > set aside asynchronous OOMEs, but I see that even synchronous OOMEs are > sidetracking us. My concern is not heap pressure; my concern is > arbitrary unchecked exceptions arising from the (int) and > append(String) calls. > > For sake of argument, I'll simplify "unchecked exceptions" to just > RuntimeExceptions, not Errors. If you can guarantee that no > RuntimeExceptions are thrown synchronously during the execution of those > method bodies on the JVM, then '+' cannot fail and the timing of > subexpression evaluation is unobservable (ordering is still observable, > as required). I think this guarantee is just a matter of reviewing the > method bodies. > > Alex > > On 3/12/2015 6:01 PM, Louis Wasserman wrote: > > I confess I'm not sure how that "quality" goal would be achievable in > > bytecode without deliberately allocating arrays we then discard. > > > > For what it's worth, delaying or avoiding OOMEs seems a desirable goal > > in general, and up to a constant multiplicative factor, this > > implementation seems to allocate the same amount in the same order. > > That is, we're still computing m().toString() before n().toString(), and > > up to a constant multiplicative factor, m().toString() allocates the > > same number of bytes as the StringBuilder the status quo generates. So > > if m() does something like allocate a char[Integer.MAX_VALUE], we still > > OOM at the appropriate time. > > > > Other notes: this implementation would tend to decrease maximum > > allocation, so it'd reduce OOMEs. Also, since the StringBuilder will > > never need further expansion and we're only using the String and > > primitive overloads of append, the only way for append to OOME would be > > in append(float) and append(double), which allocate a FloatingDecimal > > (which may, in turn, allocate a new thread-local char[26] if one isn't > > already there). > > > > On Thu, Mar 12, 2015 at 4:28 PM Alex Buckley > > wrote: > > > > More abstract presentation. Given the expression: > > > > "foo" + m() + n() > > > > you must not evaluate n() if evaluation of "foo" + m() completes > > abruptly. The proposed implementation evaluates n() regardless. > > > > All is not lost. In the proposed implementation, the abrupt > completion > > of "foo" + m() could occur because an append call fails or (thanks to > > Jon for pointing this out) the StringBuilder ctor fails. The > > quality-of-implementation issue is thus: if the proposed > implementation > > is of sufficiently high quality to guarantee that the ctor and the > first > > append both succeed, then the evaluation of "foo" + m() will always > > complete normally, and it would be an unobservable (thus acceptable) > > implementation detail to evaluate n() early. > > > > Alex > > > > On 3/11/2015 10:26 PM, Jeremy Manson wrote: > > > Isn't Louis's proposed behavior equivalent to saying "the > rightmost > > > concatenation threw an OOME" instead of "some concatenation in the > > > middle threw an OOME"? > > > > > > It's true that the intermediate String concatenations haven't > > occurred > > > at that point, but in the JDK's current implementation, that's > true, > > > too: the concatenations that have occurred at that point are > > > StringBuilder ones, not String ones. If any of the append > operations > > > throws an OOME, no Strings have been created at all, either in > > Louis's > > > implementation or in the JDK's. > > > > > > Ultimately, isn't this a quality of implementation issue? And if > so, > > > isn't it a quality of implementation issue that doesn't provide > any > > > additional quality? I can't imagine code whose semantics relies > on > > > this, and if they do, they are relying on something > > > implementation-dependent. > > > > > > Jeremy > > > > > > On Wed, Mar 11, 2015 at 6:13 PM, Alex Buckley > > > > > > >> wrote: > > > > > > On 3/11/2015 2:01 PM, Louis Wasserman wrote: > > > > > > So for example, "foo" + myInt + myString + "bar" + myObj > > would be > > > compiled to the equivalent of > > > > > > int myIntTmp = myInt; > > > String myStringTmp = String.valueOf(myString); // defend > > against > > > null > > > String myObjTmp = > > String.valueOf(String.valueOf(____myObj)); // defend > > > against evil toString implementations returning null > > > > > > return new StringBuilder( > > > 17 // length of "foo" (3) + max length of myInt > (11) + > > > length of > > > "bar" (3) > > > + myStringTmp.length() > > > + myObjTmp.length()) > > > .append("foo") > > > .append(myIntTmp) > > > .append(myStringTmp) > > > .append("bar") > > > .append(myObjTmp) > > > .toString(); > > > > > > As far as language constraints go, the JLS is (apparently > > > deliberately) > > > vague about how string concatenation is implemented. "An > > > implementation > > > may choose to perform conversion and concatenation in one > > step > > > to avoid > > > creating and then discarding an intermediate String > > object. To > > > increase > > > the performance of repeated string concatenation, a Java > > > compiler may > > > use the StringBuffer class or a similar technique to > > reduce the > > > number > > > of intermediate String objects that are created by > > evaluation of an > > > expression." We see no reason this approach would not > > qualify as a > > > "similar technique." > > > > > > > > > The really key property of the string concatenation operator > is > > > left-associativity. Later subexpressions must not be > > evaluated until > > > earlier subexpressions have been successfully evaluated AND > > > concatenated. Consider this expression: > > > > > > "foo" + m() + n() > > > > > > which JLS8 15.8 specifies to mean: > > > > > > ("foo" + m()) + n() > > > > > > We know from JLS8 15.6 that if m() throws, then foo+m() > > throws, and > > > n() will never be evaluated. > > > > > > Happily, your translation doesn't appear to catch and swallow > > > exceptions when eagerly evaluating each subexpression in > > turn, so I > > > believe you won't evaluate n() if m() already threw. > > > > > > Unhappily, a call to append(..) can in general fail with > > > OutOfMemoryError. (I'm not talking about asynchronous > > exceptions in > > > general, but rather the sense that append(..) manipulates the > > heap > > > so an OOME is at least plausible.) In the OpenJDK > > implementation, if > > > blah.append(m()) fails with OOME, then n() hasn't been > > evaluated yet > > > -- that's "real" left-associativity. In the proposed > > implementation, > > > it's possible that more memory is available when evaluating > > m() and > > > n() upfront than at the time of an append call, so n() is > > evaluated > > > even if append(<>) fails -- that's not > > > left-associative. > > > > > > Perhaps you can set my mind at ease that append(..) can't > > fail with > > > OOME? > > > > > > Alex > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex.buckley at oracle.com Fri Mar 13 22:18:52 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 13 Mar 2015 15:18:52 -0700 Subject: String concatenation tweaks In-Reply-To: References: <5500E84F.3080800@oracle.com> <55022114.8040904@oracle.com> <55034189.4000900@oracle.com> Message-ID: <5503624C.6000508@oracle.com> Thanks for analyzing how the lower layers of your '+' implementation can fail, and for prefiguring the failures so as to know that if you start concatenating the subexpression strings then you'll be able to finish. This mitigates my concern about excessively eager evaluation of subexpressions when concatenation might yet fail -- now it "can't fail", so from the outside it looks left-associative. Nice! Alex On 3/13/2015 2:40 PM, Louis Wasserman wrote: > Got it. I think the only cases we have to worry about, then, are buffer > size overflows resulting in NegativeArraySizeException, or possibly an > explicitly thrown OutOfMemoryError (which is StringBuilder's response > when the buffer size tries to exceed Integer.MAX_VALUE). I think we > might conceivably deal with this by rewriting the bytecode to -- I think > we can improve on this with jump hackery to avoid repetition, but > essentially -- > > int length = 3; // sum of the constant strings; we can check that this > won't overflow at compile time but I think it couldn't no matter what > because of method length constraints > String mStr = m().toString(); > length += mStr.length(); > if (length < 0) { > throw new OutOfMemoryError(); > } > String nStr = n().toString(); > length += nStr.length(); > if (length < 0) { > throw new OutOfMemoryError(); > } > > This continues to expand the bytecode, but probably manageably -- we > don't actually need a local for length; if (int < 0) is easy in > bytecode, and we can have only one OOME site that all the ifs jump to? > > On Fri, Mar 13, 2015 at 12:59 PM Alex Buckley > wrote: > > I do recognize that the proposed implementation doesn't reorder the > evaluation of subexpressions. > > When discussing the proposed implementation of '+' -- whose key element > is calling append(String) with a pre-computed value -- I was careful to > set aside asynchronous OOMEs, but I see that even synchronous OOMEs are > sidetracking us. My concern is not heap pressure; my concern is > arbitrary unchecked exceptions arising from the (int) and > append(String) calls. > > For sake of argument, I'll simplify "unchecked exceptions" to just > RuntimeExceptions, not Errors. If you can guarantee that no > RuntimeExceptions are thrown synchronously during the execution of those > method bodies on the JVM, then '+' cannot fail and the timing of > subexpression evaluation is unobservable (ordering is still observable, > as required). I think this guarantee is just a matter of reviewing the > method bodies. > > Alex > > On 3/12/2015 6:01 PM, Louis Wasserman wrote: > > I confess I'm not sure how that "quality" goal would be achievable in > > bytecode without deliberately allocating arrays we then discard. > > > > For what it's worth, delaying or avoiding OOMEs seems a desirable > goal > > in general, and up to a constant multiplicative factor, this > > implementation seems to allocate the same amount in the same order. > > That is, we're still computing m().toString() before > n().toString(), and > > up to a constant multiplicative factor, m().toString() allocates the > > same number of bytes as the StringBuilder the status quo > generates. So > > if m() does something like allocate a char[Integer.MAX_VALUE], we > still > > OOM at the appropriate time. > > > > Other notes: this implementation would tend to decrease maximum > > allocation, so it'd reduce OOMEs. Also, since the StringBuilder will > > never need further expansion and we're only using the String and > > primitive overloads of append, the only way for append to OOME > would be > > in append(float) and append(double), which allocate a FloatingDecimal > > (which may, in turn, allocate a new thread-local char[26] if one > isn't > > already there). > > > > On Thu, Mar 12, 2015 at 4:28 PM Alex Buckley > > > >> wrote: > > > > More abstract presentation. Given the expression: > > > > "foo" + m() + n() > > > > you must not evaluate n() if evaluation of "foo" + m() completes > > abruptly. The proposed implementation evaluates n() regardless. > > > > All is not lost. In the proposed implementation, the abrupt > completion > > of "foo" + m() could occur because an append call fails or > (thanks to > > Jon for pointing this out) the StringBuilder ctor fails. The > > quality-of-implementation issue is thus: if the proposed > implementation > > is of sufficiently high quality to guarantee that the ctor > and the first > > append both succeed, then the evaluation of "foo" + m() will > always > > complete normally, and it would be an unobservable (thus > acceptable) > > implementation detail to evaluate n() early. > > > > Alex > > > > On 3/11/2015 10:26 PM, Jeremy Manson wrote: > > > Isn't Louis's proposed behavior equivalent to saying "the > rightmost > > > concatenation threw an OOME" instead of "some > concatenation in the > > > middle threw an OOME"? > > > > > > It's true that the intermediate String concatenations haven't > > occurred > > > at that point, but in the JDK's current implementation, > that's true, > > > too: the concatenations that have occurred at that point are > > > StringBuilder ones, not String ones. If any of the append > operations > > > throws an OOME, no Strings have been created at all, either in > > Louis's > > > implementation or in the JDK's. > > > > > > Ultimately, isn't this a quality of implementation issue? > And if so, > > > isn't it a quality of implementation issue that doesn't > provide any > > > additional quality? I can't imagine code whose semantics > relies on > > > this, and if they do, they are relying on something > > > implementation-dependent. > > > > > > Jeremy > > > > > > On Wed, Mar 11, 2015 at 6:13 PM, Alex Buckley > > > > > > > ____com > > >>> wrote: > > > > > > On 3/11/2015 2:01 PM, Louis Wasserman wrote: > > > > > > So for example, "foo" + myInt + myString + "bar" + > myObj > > would be > > > compiled to the equivalent of > > > > > > int myIntTmp = myInt; > > > String myStringTmp = String.valueOf(myString); // > defend > > against > > > null > > > String myObjTmp = > > String.valueOf(String.valueOf(______myObj)); // defend > > > against evil toString implementations returning null > > > > > > return new StringBuilder( > > > 17 // length of "foo" (3) + max length of > myInt (11) + > > > length of > > > "bar" (3) > > > + myStringTmp.length() > > > + myObjTmp.length()) > > > .append("foo") > > > .append(myIntTmp) > > > .append(myStringTmp) > > > .append("bar") > > > .append(myObjTmp) > > > .toString(); > > > > > > As far as language constraints go, the JLS is > (apparently > > > deliberately) > > > vague about how string concatenation is > implemented. "An > > > implementation > > > may choose to perform conversion and concatenation > in one > > step > > > to avoid > > > creating and then discarding an intermediate String > > object. To > > > increase > > > the performance of repeated string concatenation, > a Java > > > compiler may > > > use the StringBuffer class or a similar technique to > > reduce the > > > number > > > of intermediate String objects that are created by > > evaluation of an > > > expression." We see no reason this approach would not > > qualify as a > > > "similar technique." > > > > > > > > > The really key property of the string concatenation > operator is > > > left-associativity. Later subexpressions must not be > > evaluated until > > > earlier subexpressions have been successfully > evaluated AND > > > concatenated. Consider this expression: > > > > > > "foo" + m() + n() > > > > > > which JLS8 15.8 specifies to mean: > > > > > > ("foo" + m()) + n() > > > > > > We know from JLS8 15.6 that if m() throws, then foo+m() > > throws, and > > > n() will never be evaluated. > > > > > > Happily, your translation doesn't appear to catch and > swallow > > > exceptions when eagerly evaluating each subexpression in > > turn, so I > > > believe you won't evaluate n() if m() already threw. > > > > > > Unhappily, a call to append(..) can in general fail with > > > OutOfMemoryError. (I'm not talking about asynchronous > > exceptions in > > > general, but rather the sense that append(..) > manipulates the > > heap > > > so an OOME is at least plausible.) In the OpenJDK > > implementation, if > > > blah.append(m()) fails with OOME, then n() hasn't been > > evaluated yet > > > -- that's "real" left-associativity. In the proposed > > implementation, > > > it's possible that more memory is available when > evaluating > > m() and > > > n() upfront than at the time of an append call, so n() is > > evaluated > > > even if append(<>) fails -- that's not > > > left-associative. > > > > > > Perhaps you can set my mind at ease that append(..) can't > > fail with > > > OOME? > > > > > > Alex > > > > > > > > > From cushon at google.com Sun Mar 15 22:00:51 2015 From: cushon at google.com (Liam Miller-Cushon) Date: Sun, 15 Mar 2015 15:00:51 -0700 Subject: Compilation (still) depends on order of imports Message-ID: I think I found a bug related to JEP 216. With javac9-dev @ r2850, the following program fails to compile unless the order of imports is reversed. It looks like the current implementation isn't lazy enough to handle the dependency between the two on-demand imports if 'I' is inherited into 'C'. If 'I' is declared directly in 'C' then it works. {{{ package P; import static P.Outer.Nested.*; import static P.Q.C.*; public class Outer { public static class Nested implements I { } } package P.Q; public class C extends D { } package P.Q; public class D { public interface I { } } }}} $ javac P/Outer.java P/Q/D.java P/Q/C.java P/Outer.java:7: error: cannot find symbol public static class Nested implements I { ^ symbol: class I location: class Outer 1 error -------------- next part -------------- An HTML attachment was scrubbed... URL: From jan.lahoda at oracle.com Mon Mar 16 08:08:39 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Mon, 16 Mar 2015 09:08:39 +0100 Subject: Compilation (still) depends on order of imports In-Reply-To: References: Message-ID: <55068F87.60302@oracle.com> Hi Liam, Thanks for the report. I am afraid I was not able to reproduce. I tried on: $ javac -fullversion javac full version "1.9.0-ea-b54" and on a custom build from jdk9/dev/langtools, tip: $ hg tip changeset: 2850:32a2e7249884 tag: tip parent: 2849:75cedc6db8c2 parent: 2848:f5a1cb1309ae user: lana date: Thu Mar 12 21:13:42 2015 -0700 summary: Merge Is there something special I need to do? Could you please try on JDK 9 b54? Thanks, Jan On 15.3.2015 23:00, Liam Miller-Cushon wrote: > I think I found a bug related to JEP 216. With javac9-dev @ r2850, the > following program fails to compile unless the order of imports is reversed. > > It looks like the current implementation isn't lazy enough to handle the > dependency between the two on-demand imports if 'I' is inherited into > 'C'. If 'I' is declared directly in 'C' then it works. > > {{{ > package P; > > import static P.Outer.Nested.*; > import static P.Q.C.*; > > public class Outer { > public static class Nested implements I { > } > } > > package P.Q; > > public class C extends D { > } > > package P.Q; > > public class D { > public interface I { > } > } > }}} > > $ javac P/Outer.java P/Q/D.java P/Q/C.java > P/Outer.java:7: error: cannot find symbol > public static class Nested implements I { > ^ > symbol: class I > location: class Outer > 1 error From cushon at google.com Mon Mar 16 15:23:28 2015 From: cushon at google.com (Liam Miller-Cushon) Date: Mon, 16 Mar 2015 08:23:28 -0700 Subject: Compilation (still) depends on order of imports In-Reply-To: <55068F87.60302@oracle.com> References: <55068F87.60302@oracle.com> Message-ID: Hi Jan, I see the same behaviour with JDK 9 b54. I've included a more verbose version of the repro below. Sorry if I'm missing something obvious. One additional bit of weirdness is that the order of the source files passed to javac matters: the issue occurs for "P/Outer.java P/Q/C.java P/Q/D.java" but not "P/Q/C.java P/Q/D.java P/Outer.java". Here's the repro: $ ~/jdk/jdk1.9.0/bin/java -version java version "1.9.0-ea" Java(TM) SE Runtime Environment (build 1.9.0-ea-b54) Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b54, mixed mode) $ for f in $(find . -name "*.java"); do echo "=== $f ==="; cat $f; done === ./P/Q/C.java === package P.Q; public class C extends D { } === ./P/Q/D.java === package P.Q; public class D { public interface I { } } === ./P/Outer.java === package P; import static P.Outer.Nested.*; import static P.Q.C.*; public class Outer { public static class Nested implements I { } } $ ~/jdk/jdk1.9.0/bin/javac P/Outer.java P/Q/C.java P/Q/D.java P/Outer.java:7: error: cannot find symbol public static class Nested implements I { ^ symbol: class I location: class Outer 1 error # Now, flip the order of the two imports in P.Outer $ for f in $(find . -name "*.java"); do echo "=== $f ==="; cat $f; done === ./P/Q/C.java === package P.Q; public class C extends D { } === ./P/Q/D.java === package P.Q; public class D { public interface I { } } === ./P/Outer.java === package P; import static P.Q.C.*; import static P.Outer.Nested.*; public class Outer { public static class Nested implements I { } } $ ~/jdk/jdk1.9.0/bin/javac P/Outer.java P/Q/C.java P/Q/D.java # ... compiles cleanly On Mon, Mar 16, 2015 at 1:08 AM, Jan Lahoda wrote: > Hi Liam, > > Thanks for the report. I am afraid I was not able to reproduce. I tried on: > $ javac -fullversion > javac full version "1.9.0-ea-b54" > > and on a custom build from jdk9/dev/langtools, tip: > $ hg tip > changeset: 2850:32a2e7249884 > tag: tip > parent: 2849:75cedc6db8c2 > parent: 2848:f5a1cb1309ae > user: lana > date: Thu Mar 12 21:13:42 2015 -0700 > summary: Merge > > Is there something special I need to do? Could you please try on JDK 9 b54? > > Thanks, > Jan > > > On 15.3.2015 23:00, Liam Miller-Cushon wrote: > >> I think I found a bug related to JEP 216. With javac9-dev @ r2850, the >> following program fails to compile unless the order of imports is >> reversed. >> >> It looks like the current implementation isn't lazy enough to handle the >> dependency between the two on-demand imports if 'I' is inherited into >> 'C'. If 'I' is declared directly in 'C' then it works. >> >> {{{ >> package P; >> >> import static P.Outer.Nested.*; >> import static P.Q.C.*; >> >> public class Outer { >> public static class Nested implements I { >> } >> } >> >> package P.Q; >> >> public class C extends D { >> } >> >> package P.Q; >> >> public class D { >> public interface I { >> } >> } >> }}} >> >> $ javac P/Outer.java P/Q/D.java P/Q/C.java >> P/Outer.java:7: error: cannot find symbol >> public static class Nested implements I { >> ^ >> symbol: class I >> location: class Outer >> 1 error >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jan.lahoda at oracle.com Mon Mar 16 20:05:24 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Mon, 16 Mar 2015 21:05:24 +0100 Subject: Compilation (still) depends on order of imports In-Reply-To: References: <55068F87.60302@oracle.com> Message-ID: <55073784.1060801@oracle.com> Thanks Liam, I can reproduce now. I've filled: https://bugs.openjdk.java.net/browse/JDK-8075274 Thanks, Jan On 16.3.2015 16:23, Liam Miller-Cushon wrote: > Hi Jan, > > I see the same behaviour with JDK 9 b54. I've included a more verbose > version of the repro below. Sorry if I'm missing something obvious. > > One additional bit of weirdness is that the order of the source files > passed to javac matters: the issue occurs for "P/Outer.java P/Q/C.java > P/Q/D.java" but not "P/Q/C.java P/Q/D.java P/Outer.java". > > Here's the repro: > > $ ~/jdk/jdk1.9.0/bin/java -version > java version "1.9.0-ea" > Java(TM) SE Runtime Environment (build 1.9.0-ea-b54) > Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b54, mixed mode) > > $ for f in $(find . -name "*.java"); do echo "=== $f ==="; cat $f; done > === ./P/Q/C.java === > package P.Q; > > public class C extends D { > } > === ./P/Q/D.java === > package P.Q; > > public class D { > public interface I { > } > } > === ./P/Outer.java === > package P; > > import static P.Outer.Nested.*; > import static P.Q.C.*; > > public class Outer { > public static class Nested implements I { > } > } > > $ ~/jdk/jdk1.9.0/bin/javac P/Outer.java P/Q/C.java P/Q/D.java > P/Outer.java:7: error: cannot find symbol > public static class Nested implements I { > ^ > symbol: class I > location: class Outer > 1 error > > # Now, flip the order of the two imports in P.Outer > > $ for f in $(find . -name "*.java"); do echo "=== $f ==="; cat $f; done > === ./P/Q/C.java === > package P.Q; > > public class C extends D { > } > === ./P/Q/D.java === > package P.Q; > > public class D { > public interface I { > } > } > === ./P/Outer.java === > package P; > > import static P.Q.C.*; > import static P.Outer.Nested.*; > > public class Outer { > public static class Nested implements I { > } > } > > $ ~/jdk/jdk1.9.0/bin/javac P/Outer.java P/Q/C.java P/Q/D.java > > # ... compiles cleanly > > > > On Mon, Mar 16, 2015 at 1:08 AM, Jan Lahoda > wrote: > > Hi Liam, > > Thanks for the report. I am afraid I was not able to reproduce. I > tried on: > $ javac -fullversion > javac full version "1.9.0-ea-b54" > > and on a custom build from jdk9/dev/langtools, tip: > $ hg tip > changeset: 2850:32a2e7249884 > tag: tip > parent: 2849:75cedc6db8c2 > parent: 2848:f5a1cb1309ae > user: lana > date: Thu Mar 12 21:13:42 2015 -0700 > summary: Merge > > Is there something special I need to do? Could you please try on JDK > 9 b54? > > Thanks, > Jan > > > On 15.3.2015 23:00, Liam Miller-Cushon wrote: > > I think I found a bug related to JEP 216. With javac9-dev @ > r2850, the > following program fails to compile unless the order of imports > is reversed. > > It looks like the current implementation isn't lazy enough to > handle the > dependency between the two on-demand imports if 'I' is inherited > into > 'C'. If 'I' is declared directly in 'C' then it works. > > {{{ > package P; > > import static P.Outer.Nested.*; > import static P.Q.C.*; > > public class Outer { > public static class Nested implements I { > } > } > > package P.Q; > > public class C extends D { > } > > package P.Q; > > public class D { > public interface I { > } > } > }}} > > $ javac P/Outer.java P/Q/D.java P/Q/C.java > P/Outer.java:7: error: cannot find symbol > public static class Nested implements I { > ^ > symbol: class I > location: class Outer > 1 error > > From cushon at google.com Tue Mar 17 18:38:07 2015 From: cushon at google.com (Liam Miller-Cushon) Date: Tue, 17 Mar 2015 11:38:07 -0700 Subject: Compilation (still) depends on order of imports In-Reply-To: <55073784.1060801@oracle.com> References: <55068F87.60302@oracle.com> <55073784.1060801@oracle.com> Message-ID: Great, thanks Jan. I'm curious what the resolution will be. The only solution that occurs to me is to make a pass over all of the imports and ignore any that can't be processed, and then keep retrying until a fixed point is reached. But that's unsatisfying for a variety of reasons. On Mon, Mar 16, 2015 at 1:05 PM, Jan Lahoda wrote: > Thanks Liam, I can reproduce now. I've filled: > https://bugs.openjdk.java.net/browse/JDK-8075274 > > Thanks, > Jan > > > On 16.3.2015 16:23, Liam Miller-Cushon wrote: > >> Hi Jan, >> >> I see the same behaviour with JDK 9 b54. I've included a more verbose >> version of the repro below. Sorry if I'm missing something obvious. >> >> One additional bit of weirdness is that the order of the source files >> passed to javac matters: the issue occurs for "P/Outer.java P/Q/C.java >> P/Q/D.java" but not "P/Q/C.java P/Q/D.java P/Outer.java". >> >> Here's the repro: >> >> $ ~/jdk/jdk1.9.0/bin/java -version >> java version "1.9.0-ea" >> Java(TM) SE Runtime Environment (build 1.9.0-ea-b54) >> Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b54, mixed mode) >> >> $ for f in $(find . -name "*.java"); do echo "=== $f ==="; cat $f; done >> === ./P/Q/C.java === >> package P.Q; >> >> public class C extends D { >> } >> === ./P/Q/D.java === >> package P.Q; >> >> public class D { >> public interface I { >> } >> } >> === ./P/Outer.java === >> package P; >> >> import static P.Outer.Nested.*; >> import static P.Q.C.*; >> >> public class Outer { >> public static class Nested implements I { >> } >> } >> >> $ ~/jdk/jdk1.9.0/bin/javac P/Outer.java P/Q/C.java P/Q/D.java >> P/Outer.java:7: error: cannot find symbol >> public static class Nested implements I { >> ^ >> symbol: class I >> location: class Outer >> 1 error >> >> # Now, flip the order of the two imports in P.Outer >> >> $ for f in $(find . -name "*.java"); do echo "=== $f ==="; cat $f; done >> === ./P/Q/C.java === >> package P.Q; >> >> public class C extends D { >> } >> === ./P/Q/D.java === >> package P.Q; >> >> public class D { >> public interface I { >> } >> } >> === ./P/Outer.java === >> package P; >> >> import static P.Q.C.*; >> import static P.Outer.Nested.*; >> >> public class Outer { >> public static class Nested implements I { >> } >> } >> >> $ ~/jdk/jdk1.9.0/bin/javac P/Outer.java P/Q/C.java P/Q/D.java >> >> # ... compiles cleanly >> >> >> >> On Mon, Mar 16, 2015 at 1:08 AM, Jan Lahoda > > wrote: >> >> Hi Liam, >> >> Thanks for the report. I am afraid I was not able to reproduce. I >> tried on: >> $ javac -fullversion >> javac full version "1.9.0-ea-b54" >> >> and on a custom build from jdk9/dev/langtools, tip: >> $ hg tip >> changeset: 2850:32a2e7249884 >> tag: tip >> parent: 2849:75cedc6db8c2 >> parent: 2848:f5a1cb1309ae >> user: lana >> date: Thu Mar 12 21:13:42 2015 -0700 >> summary: Merge >> >> Is there something special I need to do? Could you please try on JDK >> 9 b54? >> >> Thanks, >> Jan >> >> >> On 15.3.2015 23:00, Liam Miller-Cushon wrote: >> >> I think I found a bug related to JEP 216. With javac9-dev @ >> r2850, the >> following program fails to compile unless the order of imports >> is reversed. >> >> It looks like the current implementation isn't lazy enough to >> handle the >> dependency between the two on-demand imports if 'I' is inherited >> into >> 'C'. If 'I' is declared directly in 'C' then it works. >> >> {{{ >> package P; >> >> import static P.Outer.Nested.*; >> import static P.Q.C.*; >> >> public class Outer { >> public static class Nested implements I { >> } >> } >> >> package P.Q; >> >> public class C extends D { >> } >> >> package P.Q; >> >> public class D { >> public interface I { >> } >> } >> }}} >> >> $ javac P/Outer.java P/Q/D.java P/Q/C.java >> P/Outer.java:7: error: cannot find symbol >> public static class Nested implements I { >> ^ >> symbol: class I >> location: class Outer >> 1 error >> >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From fweimer at redhat.com Fri Mar 20 10:52:34 2015 From: fweimer at redhat.com (Florian Weimer) Date: Fri, 20 Mar 2015 11:52:34 +0100 Subject: String concatenation tweaks In-Reply-To: <55022114.8040904@oracle.com> References: <5500E84F.3080800@oracle.com> <55022114.8040904@oracle.com> Message-ID: <550BFBF2.9030301@redhat.com> On 03/13/2015 12:28 AM, Alex Buckley wrote: > More abstract presentation. Given the expression: > > "foo" + m() + n() > > you must not evaluate n() if evaluation of "foo" + m() completes > abruptly. The proposed implementation evaluates n() regardless. > > All is not lost. In the proposed implementation, the abrupt completion > of "foo" + m() could occur because an append call fails or (thanks to > Jon for pointing this out) the StringBuilder ctor fails. The > quality-of-implementation issue is thus: if the proposed implementation > is of sufficiently high quality to guarantee that the ctor and the first > append both succeed, then the evaluation of "foo" + m() will always > complete normally, and it would be an unobservable (thus acceptable) > implementation detail to evaluate n() early. The current implementation can still call m() and n() and fail with OOME in something somewhat related to the concatenation, with a sufficiently unfortunate garbage collection. (That's why OOME is a VirtualMachineError and not a RuntimeException.) I don't think preserving the OOME behavior is worth the effort. -- Florian Weimer / Red Hat Product Security From alex.buckley at oracle.com Fri Mar 20 21:10:26 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 20 Mar 2015 14:10:26 -0700 Subject: String concatenation tweaks In-Reply-To: <550BFBF2.9030301@redhat.com> References: <5500E84F.3080800@oracle.com> <55022114.8040904@oracle.com> <550BFBF2.9030301@redhat.com> Message-ID: <550C8CC2.2010809@oracle.com> On 3/20/2015 3:52 AM, Florian Weimer wrote: > On 03/13/2015 12:28 AM, Alex Buckley wrote: >> More abstract presentation. Given the expression: >> >> "foo" + m() + n() >> >> you must not evaluate n() if evaluation of "foo" + m() completes >> abruptly. The proposed implementation evaluates n() regardless. >> >> All is not lost. In the proposed implementation, the abrupt completion >> of "foo" + m() could occur because an append call fails or (thanks to >> Jon for pointing this out) the StringBuilder ctor fails. The >> quality-of-implementation issue is thus: if the proposed implementation >> is of sufficiently high quality to guarantee that the ctor and the first >> append both succeed, then the evaluation of "foo" + m() will always >> complete normally, and it would be an unobservable (thus acceptable) >> implementation detail to evaluate n() early. > > The current implementation can still call m() and n() and fail with OOME > in something somewhat related to the concatenation, with a sufficiently > unfortunate garbage collection. (That's why OOME is a > VirtualMachineError and not a RuntimeException.) In the OpenJDK implementation, n() is only called if m()'s result was concatenated successfully; if the concatenation failed for any reason (OOME is an obvious one; maybe there will be additional failure modes for StringBuilder#append in future) then n() isn't called. > I don't think preserving the OOME behavior is worth the effort. We came to a nice agreement in the follow-ups to the quoted mail. Alex From bitterfoxc at gmail.com Sat Mar 21 08:53:01 2015 From: bitterfoxc at gmail.com (ShinyaYoshida) Date: Sat, 21 Mar 2015 17:53:01 +0900 Subject: RFR 8075664: NPE for illegall super call with MethodReference Message-ID: Hi, compier-dev, jdk8u-dev, I found a bug and have a fix for the bug. Please review my patch. Bugs: https://bugs.openjdk.java.net/browse/JDK-8075664 Webrev: http://cr.openjdk.java.net/~shinyafox/8075664/webrev.00/ Regards, shinyafox(Shinya Yoshida) -------------- next part -------------- An HTML attachment was scrubbed... URL: From sven.reimers at gmail.com Sat Mar 21 11:49:47 2015 From: sven.reimers at gmail.com (Sven Reimers) Date: Sat, 21 Mar 2015 12:49:47 +0100 Subject: IAE trying to compile with JDK1.8.0_40 Message-ID: Hi guys, ever seen this: An exception has occurred in the compiler (1.8.0_40). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you. java.lang.IllegalAccessError: com/sun/tools/javac/file/Locations$1 at com.sun.tools.javac.file.Locations$BootClassPathLocationHandler.canonicalize(Locations.java:563) at com.sun.tools.javac.file.Locations$BootClassPathLocationHandler.handleOption(Locations.java:550) at com.sun.tools.javac.file.Locations$LocationHandler.update(Locations.java:342) at com.sun.tools.javac.file.Locations.lazy(Locations.java:712) at com.sun.tools.javac.file.Locations.getHandler(Locations.java:702) at com.sun.tools.javac.file.Locations.getLocation(Locations.java:677) at com.sun.tools.javac.file.JavacFileManager.getLocation(JavacFileManager.java:803) at com.sun.tools.javac.file.JavacFileManager.hasLocation(JavacFileManager.java:654) at com.sun.tools.javac.processing.JavacProcessingEnvironment.initProcessorClassLoader(JavacProcessingEnvironment.java:219) at com.sun.tools.javac.processing.JavacProcessingEnvironment.(JavacProcessingEnvironment.java:195) at com.sun.tools.javac.processing.JavacProcessingEnvironment.instance(JavacProcessingEnvironment.java:161) at com.sun.tools.javac.main.JavaCompiler.initProcessAnnotations(JavaCompiler.java:1048) at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:852) at com.sun.tools.javac.main.Main.compile(Main.java:523) at com.sun.tools.javac.main.Main.compile(Main.java:381) at com.sun.tools.javac.main.Main.compile(Main.java:370) at com.sun.tools.javac.main.Main.compile(Main.java:361) at com.sun.tools.javac.Main.compile(Main.java:56) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.apache.tools.ant.taskdefs.compilers.Javac13.execute(Javac13.java:56) at org.apache.tools.ant.taskdefs.Javac.compile(Javac.java:1159) at org.netbeans.nbbuild.CustomJavac.compile(CustomJavac.java:124) at org.apache.tools.ant.taskdefs.Javac.execute(Javac.java:935) at org.netbeans.nbbuild.CustomJavac.execute(CustomJavac.java:105) at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292) at sun.reflect.GeneratedMethodAccessor622.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) at org.apache.tools.ant.Task.perform(Task.java:348) at org.apache.tools.ant.Target.execute(Target.java:435) at org.apache.tools.ant.Target.performTasks(Target.java:456) at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393) at org.apache.tools.ant.helper.SingleCheckExecutor.executeTargets(SingleCheckExecutor.java:38) at org.apache.tools.ant.Project.executeTargets(Project.java:1248) at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:441) at org.apache.tools.ant.taskdefs.SubAnt.execute(SubAnt.java:306) at org.apache.tools.ant.taskdefs.SubAnt.execute(SubAnt.java:221) at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292) at sun.reflect.GeneratedMethodAccessor622.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) at org.apache.tools.ant.Task.perform(Task.java:348) at org.apache.tools.ant.Target.execute(Target.java:435) at org.apache.tools.ant.Target.performTasks(Target.java:456) at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393) at org.apache.tools.ant.Project.executeTarget(Project.java:1364) at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41) at org.apache.tools.ant.Project.executeTargets(Project.java:1248) at org.apache.tools.ant.module.bridge.impl.BridgeImpl.run(BridgeImpl.java:286) at org.apache.tools.ant.module.run.TargetExecutor.run(TargetExecutor.java:555) at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:153) Shall I file a new bug report? Thanks -Sven -- Sven Reimers * Senior Expert Software Architect * Java Champion * NetBeans Dream Team Member: http://dreamteam.netbeans.org * Community Leader NetBeans: http://community.java.net/netbeans Desktop Java: http://community.java.net/javadesktop * JUG Leader JUG Bodensee: http://www.jug-bodensee.de * Duke's Choice Award Winner 2009 * Blog: https://www.java.net//blog/sven * XING: https://www.xing.com/profile/Sven_Reimers8 * LinkedIn: http://www.linkedin.com/in/svenreimers Join the NetBeans Groups: * XING: http://www.xing.com/group-20148.82db20 * NUGM: http://haug-server.dyndns.org/display/NUGM/Home * LinkedIn: http://www.linkedin.com/groups?gid=1860468 http://www.linkedin.com/groups?gid=107402 http://www.linkedin.com/groups?gid=1684717 * Oracle: https://mix.oracle.com/groups/18497 -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Sat Mar 21 12:07:35 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 21 Mar 2015 13:07:35 +0100 Subject: IAE trying to compile with JDK1.8.0_40 In-Reply-To: References: Message-ID: <550D5F07.5020306@univ-mlv.fr> I maybe wrong but it seems like you are using the wrong version of javac to try to compile the jdk8. cheers, R?mi On 03/21/2015 12:49 PM, Sven Reimers wrote: > Hi guys, > > ever seen this: > > An exception has occurred in the compiler (1.8.0_40). Please file a > bug at the Java Developer Connection > (http://java.sun.com/webapps/bugreport) after checking the Bug Parade > for duplicates. Include your program and the following diagnostic in > your report. Thank you. > java.lang.IllegalAccessError: com/sun/tools/javac/file/Locations$1 > at > com.sun.tools.javac.file.Locations$BootClassPathLocationHandler.canonicalize(Locations.java:563) > at > com.sun.tools.javac.file.Locations$BootClassPathLocationHandler.handleOption(Locations.java:550) > at > com.sun.tools.javac.file.Locations$LocationHandler.update(Locations.java:342) > at com.sun.tools.javac.file.Locations.lazy(Locations.java:712) > at com.sun.tools.javac.file.Locations.getHandler(Locations.java:702) > at com.sun.tools.javac.file.Locations.getLocation(Locations.java:677) > at > com.sun.tools.javac.file.JavacFileManager.getLocation(JavacFileManager.java:803) > at > com.sun.tools.javac.file.JavacFileManager.hasLocation(JavacFileManager.java:654) > at > com.sun.tools.javac.processing.JavacProcessingEnvironment.initProcessorClassLoader(JavacProcessingEnvironment.java:219) > at > com.sun.tools.javac.processing.JavacProcessingEnvironment.(JavacProcessingEnvironment.java:195) > at > com.sun.tools.javac.processing.JavacProcessingEnvironment.instance(JavacProcessingEnvironment.java:161) > at > com.sun.tools.javac.main.JavaCompiler.initProcessAnnotations(JavaCompiler.java:1048) > at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:852) > at com.sun.tools.javac.main.Main.compile(Main.java:523) > at com.sun.tools.javac.main.Main.compile(Main.java:381) > at com.sun.tools.javac.main.Main.compile(Main.java:370) > at com.sun.tools.javac.main.Main.compile(Main.java:361) > at com.sun.tools.javac.Main.compile(Main.java:56) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:497) > at > org.apache.tools.ant.taskdefs.compilers.Javac13.execute(Javac13.java:56) > at org.apache.tools.ant.taskdefs.Javac.compile(Javac.java:1159) > at org.netbeans.nbbuild.CustomJavac.compile(CustomJavac.java:124) > at org.apache.tools.ant.taskdefs.Javac.execute(Javac.java:935) > at org.netbeans.nbbuild.CustomJavac.execute(CustomJavac.java:105) > at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292) > at sun.reflect.GeneratedMethodAccessor622.invoke(Unknown Source) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:497) > at > org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) > at org.apache.tools.ant.Task.perform(Task.java:348) > at org.apache.tools.ant.Target.execute(Target.java:435) > at org.apache.tools.ant.Target.performTasks(Target.java:456) > at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393) > at > org.apache.tools.ant.helper.SingleCheckExecutor.executeTargets(SingleCheckExecutor.java:38) > at org.apache.tools.ant.Project.executeTargets(Project.java:1248) > at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:441) > at org.apache.tools.ant.taskdefs.SubAnt.execute(SubAnt.java:306) > at org.apache.tools.ant.taskdefs.SubAnt.execute(SubAnt.java:221) > at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292) > at sun.reflect.GeneratedMethodAccessor622.invoke(Unknown Source) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:497) > at > org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) > at org.apache.tools.ant.Task.perform(Task.java:348) > at org.apache.tools.ant.Target.execute(Target.java:435) > at org.apache.tools.ant.Target.performTasks(Target.java:456) > at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393) > at org.apache.tools.ant.Project.executeTarget(Project.java:1364) > at > org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41) > at org.apache.tools.ant.Project.executeTargets(Project.java:1248) > at > org.apache.tools.ant.module.bridge.impl.BridgeImpl.run(BridgeImpl.java:286) > at > org.apache.tools.ant.module.run.TargetExecutor.run(TargetExecutor.java:555) > at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:153) > > > Shall I file a new bug report? > > Thanks > > -Sven > > -- > Sven Reimers > > * Senior Expert Software Architect > * Java Champion > * NetBeans Dream Team Member: http://dreamteam.netbeans.org > * Community Leader NetBeans: http://community.java.net/netbeans > Desktop Java: > http://community.java.net/javadesktop > * JUG Leader JUG Bodensee: http://www.jug-bodensee.de > * Duke's Choice Award Winner 2009 > * Blog: https://www.java.net//blog/sven > > * XING: https://www.xing.com/profile/Sven_Reimers8 > * LinkedIn: http://www.linkedin.com/in/svenreimers > > Join the NetBeans Groups: > * XING: http://www.xing.com/group-20148.82db20 > * NUGM: http://haug-server.dyndns.org/display/NUGM/Home > * LinkedIn: http://www.linkedin.com/groups?gid=1860468 > http://www.linkedin.com/groups?gid=107402 > http://www.linkedin.com/groups?gid=1684717 > * Oracle: https://mix.oracle.com/groups/18497 -------------- next part -------------- An HTML attachment was scrubbed... URL: From sven.reimers at gmail.com Sat Mar 21 14:25:36 2015 From: sven.reimers at gmail.com (Sven Reimers) Date: Sat, 21 Mar 2015 15:25:36 +0100 Subject: IAE trying to compile with JDK1.8.0_40 In-Reply-To: <550D5F07.5020306@univ-mlv.fr> References: <550D5F07.5020306@univ-mlv.fr> Message-ID: Hmm.. will try check.. Occurs when building inside NetBeans... Will let you know... Thanks for looking into it -Sven Am 21.03.2015 13:08 schrieb "Remi Forax" : > I maybe wrong but it seems like you are using the wrong version of javac > to try to compile the jdk8. > > cheers, > R?mi > > > On 03/21/2015 12:49 PM, Sven Reimers wrote: > > Hi guys, > > ever seen this: > > An exception has occurred in the compiler (1.8.0_40). Please file a bug > at the Java Developer Connection (http://java.sun.com/webapps/bugreport) > after checking the Bug Parade for duplicates. Include your program and the > following diagnostic in your report. Thank you. > java.lang.IllegalAccessError: com/sun/tools/javac/file/Locations$1 > at > com.sun.tools.javac.file.Locations$BootClassPathLocationHandler.canonicalize(Locations.java:563) > at > com.sun.tools.javac.file.Locations$BootClassPathLocationHandler.handleOption(Locations.java:550) > at > com.sun.tools.javac.file.Locations$LocationHandler.update(Locations.java:342) > at com.sun.tools.javac.file.Locations.lazy(Locations.java:712) > at com.sun.tools.javac.file.Locations.getHandler(Locations.java:702) > at com.sun.tools.javac.file.Locations.getLocation(Locations.java:677) > at > com.sun.tools.javac.file.JavacFileManager.getLocation(JavacFileManager.java:803) > at > com.sun.tools.javac.file.JavacFileManager.hasLocation(JavacFileManager.java:654) > at > com.sun.tools.javac.processing.JavacProcessingEnvironment.initProcessorClassLoader(JavacProcessingEnvironment.java:219) > at > com.sun.tools.javac.processing.JavacProcessingEnvironment.(JavacProcessingEnvironment.java:195) > at > com.sun.tools.javac.processing.JavacProcessingEnvironment.instance(JavacProcessingEnvironment.java:161) > at > com.sun.tools.javac.main.JavaCompiler.initProcessAnnotations(JavaCompiler.java:1048) > at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:852) > at com.sun.tools.javac.main.Main.compile(Main.java:523) > at com.sun.tools.javac.main.Main.compile(Main.java:381) > at com.sun.tools.javac.main.Main.compile(Main.java:370) > at com.sun.tools.javac.main.Main.compile(Main.java:361) > at com.sun.tools.javac.Main.compile(Main.java:56) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:497) > at > org.apache.tools.ant.taskdefs.compilers.Javac13.execute(Javac13.java:56) > at org.apache.tools.ant.taskdefs.Javac.compile(Javac.java:1159) > at org.netbeans.nbbuild.CustomJavac.compile(CustomJavac.java:124) > at org.apache.tools.ant.taskdefs.Javac.execute(Javac.java:935) > at org.netbeans.nbbuild.CustomJavac.execute(CustomJavac.java:105) > at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292) > at sun.reflect.GeneratedMethodAccessor622.invoke(Unknown Source) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:497) > at > org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) > at org.apache.tools.ant.Task.perform(Task.java:348) > at org.apache.tools.ant.Target.execute(Target.java:435) > at org.apache.tools.ant.Target.performTasks(Target.java:456) > at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393) > at > org.apache.tools.ant.helper.SingleCheckExecutor.executeTargets(SingleCheckExecutor.java:38) > at org.apache.tools.ant.Project.executeTargets(Project.java:1248) > at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:441) > at org.apache.tools.ant.taskdefs.SubAnt.execute(SubAnt.java:306) > at org.apache.tools.ant.taskdefs.SubAnt.execute(SubAnt.java:221) > at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292) > at sun.reflect.GeneratedMethodAccessor622.invoke(Unknown Source) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:497) > at > org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106) > at org.apache.tools.ant.Task.perform(Task.java:348) > at org.apache.tools.ant.Target.execute(Target.java:435) > at org.apache.tools.ant.Target.performTasks(Target.java:456) > at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393) > at org.apache.tools.ant.Project.executeTarget(Project.java:1364) > at > org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41) > at org.apache.tools.ant.Project.executeTargets(Project.java:1248) > at > org.apache.tools.ant.module.bridge.impl.BridgeImpl.run(BridgeImpl.java:286) > at > org.apache.tools.ant.module.run.TargetExecutor.run(TargetExecutor.java:555) > at > org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:153) > > > Shall I file a new bug report? > > Thanks > > -Sven > > -- > Sven Reimers > > * Senior Expert Software Architect > * Java Champion > * NetBeans Dream Team Member: http://dreamteam.netbeans.org > * Community Leader NetBeans: http://community.java.net/netbeans > Desktop Java: > http://community.java.net/javadesktop > * JUG Leader JUG Bodensee: http://www.jug-bodensee.de > * Duke's Choice Award Winner 2009 > * Blog: https://www.java.net//blog/sven > > * XING: https://www.xing.com/profile/Sven_Reimers8 > * LinkedIn: http://www.linkedin.com/in/svenreimers > > Join the NetBeans Groups: > * XING: http://www.xing.com/group-20148.82db20 > * NUGM: http://haug-server.dyndns.org/display/NUGM/Home > * LinkedIn: http://www.linkedin.com/groups?gid=1860468 > http://www.linkedin.com/groups?gid=107402 > http://www.linkedin.com/groups?gid=1684717 > * Oracle: https://mix.oracle.com/groups/18497 > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From konstantin.barzilovich at oracle.com Wed Mar 25 14:44:15 2015 From: konstantin.barzilovich at oracle.com (konstantin barzilovich) Date: Wed, 25 Mar 2015 17:44:15 +0300 Subject: Implicit declaration of resources in try statement Message-ID: <5512C9BF.4030807@oracle.com> Hello, Jan Would you please clarify, what does it mean to declare resource of try statement implicitly. As I understand, explicit declaration is: try (AutoCloseable ac = new AutoCloseable()) {} Thanks, Konstantin. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jan.lahoda at oracle.com Thu Mar 26 13:24:17 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Thu, 26 Mar 2015 14:24:17 +0100 Subject: Implicit declaration of resources in try statement In-Reply-To: <5512C9BF.4030807@oracle.com> References: <5512C9BF.4030807@oracle.com> Message-ID: <55140881.1090905@oracle.com> Hello Konstantin, When the statement looks like this: try (variable) {} then it is automatically expanded to: try ( #r = variable) {} The " #r = variable" declaration is the implicit declaration. Jan On 25.3.2015 15:44, konstantin barzilovich wrote: > Hello, Jan > > Would you please clarify, what does it mean to declare resource of try > statement implicitly. > As I understand, explicit declaration is: > > try (AutoCloseable ac = new AutoCloseable()) {} > > Thanks, > Konstantin. From konstantin.barzilovich at oracle.com Thu Mar 26 13:55:44 2015 From: konstantin.barzilovich at oracle.com (konstantin barzilovich) Date: Thu, 26 Mar 2015 16:55:44 +0300 Subject: Implicit declaration of resources in try statement In-Reply-To: <55140881.1090905@oracle.com> References: <5512C9BF.4030807@oracle.com> <55140881.1090905@oracle.com> Message-ID: <55140FE0.1030107@oracle.com> Hello Jan. Thank you. Now I understand, that scope of #r should be inside of try block. Konstantin. On 26.03.2015 16:24, Jan Lahoda wrote: > Hello Konstantin, > > When the statement looks like this: > try (variable) {} > > then it is automatically expanded to: > try ( #r = variable) {} > > The " #r = variable" declaration is the implicit declaration. > > Jan > > On 25.3.2015 15:44, konstantin barzilovich wrote: >> Hello, Jan >> >> Would you please clarify, what does it mean to declare resource of try >> statement implicitly. >> As I understand, explicit declaration is: >> >> try (AutoCloseable ac = new AutoCloseable()) {} >> >> Thanks, >> Konstantin. From cushon at google.com Thu Mar 26 23:05:47 2015 From: cushon at google.com (Liam Miller-Cushon) Date: Thu, 26 Mar 2015 16:05:47 -0700 Subject: [PATCH] fix self-assignment in TypeVar Message-ID: I think this is harmless, but it looks suspicious and is probably worth cleaning up. (If it's actually a bug then this is not the right patch.) # HG changeset patch # User Liam Miller-Cushon # Date 1427408687 25200 # Thu Mar 26 15:24:47 2015 -0700 # Node ID 99c3cd409d0a12538c6f7e96c45e87b81d9db8bf # Parent 1a0808932668a1fa688d3c0ed1f794adc9b3ce18 Remove self-assignment in TypeVar diff -r 1a0808932668 -r 99c3cd409d0a src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java Thu Mar 26 16:17:36 2015 +0100 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java Thu Mar 26 15:24:47 2015 -0700 @@ -1466,7 +1466,6 @@ public TypeVar(Name name, Symbol owner, Type lower) { super(null, TypeMetadata.empty); tsym = new TypeVariableSymbol(0, name, this, owner); - this.bound = bound; this.lower = lower; }