From eric.mccorkle at oracle.com Tue Jun 3 14:24:54 2014 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Tue, 03 Jun 2014 10:24:54 -0400 Subject: Public review of rearchitected front-end type annotations pipeline In-Reply-To: <5374EE10.5060500@oracle.com> References: <536D3130.2010500@oracle.com> <5374EE10.5060500@oracle.com> Message-ID: <538DDAB6.9060804@oracle.com> Since I last posted a revision, there has been a significant amount of review activity by the javac team. I have, at this point, merged what I had intended to be the third patch in the series, and created a combined patch. I have also fixed a few issues that were found in our review. The current revision can be found here: http://cr.openjdk.java.net/~emc/8027262/webrev.02/ Note that since this incorporates what was to be the third patch in the series, there will not be a third patch anymore. It should be possible to test Checkers at this point. It is also likely that this will be integrated very shortly. At this point, I will begin evaluating this entire body of work for inclusion in the upcoming 8u20 update release. One thing I would like to do is a "before/after" evaluation with as many "real-world" uses of type annotations as possible. To facilitate this, I will shortly post a large patch which combines all of my work thus far, which should be applied against the 8-update repo. When that patch is published, I would very much appreciate if anyone who is actually using type annotations at this point could evaluate and report on the correctness of the 8-update repo with and without the patch. As a final note, we are currently putting plans together for 8u40 work. My tentative plans at this point focus on the javax.lang.model API and internal javac API's, with particular focus on ensuring that Type's always have the annotations they should, and on using that to facilitate cleaning up some code in the backend (mainly Gen), though that is not set in stone at this point. On 05/15/14 12:40, Eric McCorkle wrote: > I have integrated a number of edits to the patch, from both the public > and internal reviews, and I have fixed a few issues I found. A new > version has been posted here: > > http://cr.openjdk.java.net/~emc/8027262/webrev.01/ > > It is likely that this change will be integrated later today, or > tomorrow. At that point, I will post the third and final patch in the > series. > > On 05/09/14 15:49, Eric McCorkle wrote: >> Hello, >> >> This is the public review of the second in my series of patches dealing >> with type annotations. >> >> http://cr.openjdk.java.net/~emc/8027262/ >> >> This patch rearchitects the type annotations pipeline, integrating >> handling of type annotations directly into the javac >> MemberEnter/Annotate/Attr pipeline. It represents the majority of the >> work I have been doing regarding type annotations for 8u20. >> >> The handling of type annotations is now dispatched by the MemberEnter or >> Attr visitors and uses information from those visitors. Most of the >> actual functionality is now implemented in Annotate. >> >> The new test Stress.java is the test for this patch. Stress.java will >> cause 8-release javac to fail with an assertion failure. Its addition >> to the test suite demonstrates that this change fixes those cases. >> >> This patch addresses a number of JBS issues: >> https://bugs.openjdk.java.net/browse/JDK-8027262 >> https://bugs.openjdk.java.net/browse/JDK-8027261 >> https://bugs.openjdk.java.net/browse/JDK-8027258 >> https://bugs.openjdk.java.net/browse/JDK-8027182 >> and possibly others as well. >> >> Note: this patch does not attempt to remove code made obsolete; however, >> any such code is very clearly marked as deprecated. Removal of dead >> code will be done in the last of the series. This patch also does not >> attempt to re-enable tests which were previously disabled. That will be >> done as a separate patch as well. >> -------------- next part -------------- A non-text attachment was scrubbed... Name: eric_mccorkle.vcf Type: text/x-vcard Size: 314 bytes Desc: not available URL: From paul.govereau at oracle.com Tue Jun 3 20:35:10 2014 From: paul.govereau at oracle.com (Paul Govereau) Date: Tue, 03 Jun 2014 16:35:10 -0400 Subject: Clarification on JDK-8038975 Message-ID: <538E317E.9050405@oracle.com> Hello, I have recently fixed https://bugs.openjdk.java.net/browse/JDK-8038975 . Which is a difference in access enforcement for inner classes depending on if an enhanced-for is used or not. However, now the reviewers and I are having doubts that this is a bug. Perhaps javac is correctly handling the enhanced-for and the "diminished" for is not handled correctly. Can anyone help clarify the spec in regard to this issue? Thanks, Paul From alex.buckley at oracle.com Tue Jun 3 22:57:44 2014 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 03 Jun 2014 15:57:44 -0700 Subject: Clarification on JDK-8038975 In-Reply-To: <538E317E.9050405@oracle.com> References: <538E317E.9050405@oracle.com> Message-ID: <538E52E8.7030300@oracle.com> I believe the code should compile. The body of OuterImpl certainly has access to the protected member class Inner. Nothing is accessed via qualified names that would cause additional protected rules to kick in. The fact that 'Inner' is an accessible type for the formal parameter 'inner' indicates everything should be well with 'inner.iterator()'. Alex On 6/3/2014 1:35 PM, Paul Govereau wrote: > Hello, > > I have recently fixed > > https://bugs.openjdk.java.net/browse/JDK-8038975 . > > Which is a difference in access enforcement for inner classes depending > on if an enhanced-for is used or not. > > However, now the reviewers and I are having doubts that this is a bug. > Perhaps javac is correctly handling the enhanced-for and the > "diminished" for is not handled correctly. > > Can anyone help clarify the spec in regard to this issue? > > Thanks, > Paul From maurizio.cimadamore at oracle.com Wed Jun 4 09:10:40 2014 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 04 Jun 2014 10:10:40 +0100 Subject: Clarification on JDK-8038975 In-Reply-To: <538E52E8.7030300@oracle.com> References: <538E317E.9050405@oracle.com> <538E52E8.7030300@oracle.com> Message-ID: <538EE290.8030203@oracle.com> On 03/06/14 23:57, Alex Buckley wrote: > I believe the code should compile. The body of OuterImpl certainly has > access to the protected member class Inner. Nothing is accessed via > qualified names that would cause additional protected rules to kick > in. The fact that 'Inner' is an accessible type for the formal > parameter 'inner' indicates everything should be well with > 'inner.iterator()'. I believe this might be another instance of [1, 2]. Vicente and I did some rework [3] of the enhanced for loop logic sometime ago (as that was causing duplicate CP entries in the resulting bytecode) and this work has bitten back with few accessibility related regressions. This might well be another one. [1] - https://bugs.openjdk.java.net/browse/JDK-8013394 [2] - https://bugs.openjdk.java.net/browse/JDK-8011432 [3] - https://bugs.openjdk.java.net/browse/JDK-5053846 Maurizio > > Alex > > On 6/3/2014 1:35 PM, Paul Govereau wrote: >> Hello, >> >> I have recently fixed >> >> https://bugs.openjdk.java.net/browse/JDK-8038975 . >> >> Which is a difference in access enforcement for inner classes depending >> on if an enhanced-for is used or not. >> >> However, now the reviewers and I are having doubts that this is a bug. >> Perhaps javac is correctly handling the enhanced-for and the >> "diminished" for is not handled correctly. >> >> Can anyone help clarify the spec in regard to this issue? >> >> Thanks, >> Paul From andreas.lundblad at oracle.com Thu Jun 5 11:34:29 2014 From: andreas.lundblad at oracle.com (Andreas Lundblad) Date: Thu, 5 Jun 2014 13:34:29 +0200 Subject: RFR: timestamp oddities -sourcepath vs zip/jar In-Reply-To: References: <52408F2F.10806@oracle.com> <5241A1B6.8020200@oracle.com> <5243F37A.5070102@oracle.com> Message-ID: <20140605113428.GE21950@e6430> On Tue, Nov 12, 2013 at 10:54:18AM +0100, Fredrik ?hrstr?m wrote: > I have now created the bug JDK-8028196 "Javac allows timestamps inside > rt.jar to affect compilation when using -sourcepath." to track the problem. > > I also found that Erik Joelsson had already reported JDK-8025702, which has > a good description of the kind of mysterious and difficult to track down > error messages that you get when javac starts preferring rt.jar classes to > your own sources. Picking up this old thread just to report that this has been resolved [1]. By providing -XXuserPathsFirst sourcepaths and classpaths are scanned before boot classpath. [1] http://hg.openjdk.java.net/jdk9/dev/langtools/rev/baf35a88504b -- Andreas From laszlo.hornyak at gmail.com Thu Jun 5 19:27:33 2014 From: laszlo.hornyak at gmail.com (Laszlo Hornyak) Date: Thu, 5 Jun 2014 21:27:33 +0200 Subject: StringBuilder buffer allocation support in compiler Message-ID: Hi, Given this sample code public static String sayHello(String name, int age) { return "Hello " + name + ", this is your " + age + "th birthday"; } The compiler will generate this bytecode: 0: new #11 // class java/lang/StringBuilder 3: dup 4: invokespecial #12 // Method java/lang/StringBuilder."":()V 7: ldc #19 // String Hello 9: invokevirtual #15 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 12: aload_0 13: invokevirtual #15 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 16: ldc #20 // String , this is your 18: invokevirtual #15 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 21: iload_1 22: invokevirtual #13 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 25: ldc #21 // String th birthday 27: invokevirtual #15 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 30: invokevirtual #17 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 33: areturn The most interesting line is: 4: invokespecial #12 // Method java/lang/StringBuilder."":()V Since all the string literals are given for the compiler, it could give an estimation on the required buffer size to the StringBuilder constructor. In this example the string literals already take 32 characters, plus a string representation of an integer takes up to 12 characters. The String size is 0 to Integer.MAX_VALUE, but 16 might be a good default. In this case a constructor call could be generated to allocate a buffer with 50 characters and some (possibly all) buffer re-allocation could be saved in the subsequent append calls. The performance gain seems to be significant since the subsequent buffer allocations can take up to 30-40 percent of the execution time. Is there a specific reason for the java compiler not to support pre-allocation of StringBuilder buffer based on string literals and parameters? Thank you, Laszlo -- EOF -------------- next part -------------- An HTML attachment was scrubbed... URL: From vicente.romero at oracle.com Thu Jun 5 19:33:01 2014 From: vicente.romero at oracle.com (Vicente-Arturo Romero-Zaldivar) Date: Thu, 05 Jun 2014 20:33:01 +0100 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: References: Message-ID: <5390C5ED.9040200@oracle.com> Hi Laszlo, On 05/06/14 20:27, Laszlo Hornyak wrote: > Hi, > > Given this sample code > > public static String sayHello(String name, int age) { > return "Hello " + name + ", this is your " + age + "th birthday"; > } > > The compiler will generate this bytecode: > 0: new #11 // class > java/lang/StringBuilder > 3: dup > 4: invokespecial #12 // Method > java/lang/StringBuilder."":()V > 7: ldc #19 // String Hello > 9: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 12: aload_0 > 13: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 16: ldc #20 // String , this is your > 18: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 21: iload_1 > 22: invokevirtual #13 // Method > java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; > 25: ldc #21 // String th birthday > 27: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 30: invokevirtual #17 // Method > java/lang/StringBuilder.toString:()Ljava/lang/String; > 33: areturn > > The most interesting line is: > 4: invokespecial #12 // Method > java/lang/StringBuilder."":()V > > > Since all the string literals are given for the compiler, it could > give an estimation on the required buffer size to the StringBuilder > constructor. In this example the string literals already take 32 > characters, plus a string representation of an integer takes up to 12 > characters. The String size is 0 to Integer.MAX_VALUE, but 16 might be > a good default. In this case a constructor call could be generated to > allocate a buffer with 50 characters and some (possibly all) buffer > re-allocation could be saved in the subsequent append calls. > The performance gain seems to be significant since the subsequent > buffer allocations can take up to 30-40 percent of the execution time. Just curious, do you have a proof for this? > Is there a specific reason for the java compiler not to support > pre-allocation of StringBuilder buffer based on string literals and > parameters? > > Thank you, > Laszlo > > > -- > > EOF Thanks, Vicente From vicente.romero at oracle.com Thu Jun 5 19:38:18 2014 From: vicente.romero at oracle.com (Vicente-Arturo Romero-Zaldivar) Date: Thu, 05 Jun 2014 20:38:18 +0100 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: References: Message-ID: <5390C72A.3070102@oracle.com> There is a related bug entry: https://bugs.openjdk.java.net/browse/JDK-4059189. I have added a link to your mail. Vicente On 05/06/14 20:27, Laszlo Hornyak wrote: > Hi, > > Given this sample code > > public static String sayHello(String name, int age) { > return "Hello " + name + ", this is your " + age + "th birthday"; > } > > The compiler will generate this bytecode: > 0: new #11 // class > java/lang/StringBuilder > 3: dup > 4: invokespecial #12 // Method > java/lang/StringBuilder."":()V > 7: ldc #19 // String Hello > 9: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 12: aload_0 > 13: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 16: ldc #20 // String , this is your > 18: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 21: iload_1 > 22: invokevirtual #13 // Method > java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; > 25: ldc #21 // String th birthday > 27: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 30: invokevirtual #17 // Method > java/lang/StringBuilder.toString:()Ljava/lang/String; > 33: areturn > > The most interesting line is: > 4: invokespecial #12 // Method > java/lang/StringBuilder."":()V > > > Since all the string literals are given for the compiler, it could > give an estimation on the required buffer size to the StringBuilder > constructor. In this example the string literals already take 32 > characters, plus a string representation of an integer takes up to 12 > characters. The String size is 0 to Integer.MAX_VALUE, but 16 might be > a good default. In this case a constructor call could be generated to > allocate a buffer with 50 characters and some (possibly all) buffer > re-allocation could be saved in the subsequent append calls. > The performance gain seems to be significant since the subsequent > buffer allocations can take up to 30-40 percent of the execution time. > Is there a specific reason for the java compiler not to support > pre-allocation of StringBuilder buffer based on string literals and > parameters? > > Thank you, > Laszlo > > > -- > > EOF From vitalyd at gmail.com Thu Jun 5 19:43:38 2014 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Thu, 5 Jun 2014 15:43:38 -0400 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: References: Message-ID: Hi Laszlo, I believe server jit compiler has an optimization pass that will attempt at fusing this type of pattern into one string allocation -- see src/share/vm/opto/stringopts.[h|c]pp in the sources. Have you tried benchmarking this after jit compiler gets a crack at it? On Thu, Jun 5, 2014 at 3:27 PM, Laszlo Hornyak wrote: > Hi, > > Given this sample code > > public static String sayHello(String name, int age) { > return "Hello " + name + ", this is your " + age + "th birthday"; > } > > The compiler will generate this bytecode: > 0: new #11 // class > java/lang/StringBuilder > 3: dup > 4: invokespecial #12 // Method > java/lang/StringBuilder."":()V > 7: ldc #19 // String Hello > 9: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 12: aload_0 > 13: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 16: ldc #20 // String , this is your > 18: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 21: iload_1 > 22: invokevirtual #13 // Method > java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; > 25: ldc #21 // String th birthday > 27: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 30: invokevirtual #17 // Method > java/lang/StringBuilder.toString:()Ljava/lang/String; > 33: areturn > > The most interesting line is: > 4: invokespecial #12 // Method > java/lang/StringBuilder."":()V > > > Since all the string literals are given for the compiler, it could give an > estimation on the required buffer size to the StringBuilder constructor. In > this example the string literals already take 32 characters, plus a string > representation of an integer takes up to 12 characters. The String size is > 0 to Integer.MAX_VALUE, but 16 might be a good default. In this case a > constructor call could be generated to allocate a buffer with 50 characters > and some (possibly all) buffer re-allocation could be saved in the > subsequent append calls. > The performance gain seems to be significant since the subsequent buffer > allocations can take up to 30-40 percent of the execution time. > Is there a specific reason for the java compiler not to support > pre-allocation of StringBuilder buffer based on string literals and > parameters? > > Thank you, > Laszlo > > > -- > > EOF > -------------- next part -------------- An HTML attachment was scrubbed... URL: From laszlo.hornyak at gmail.com Thu Jun 5 20:11:41 2014 From: laszlo.hornyak at gmail.com (Laszlo Hornyak) Date: Thu, 5 Jun 2014 22:11:41 +0200 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: <5390C5ED.9040200@oracle.com> References: <5390C5ED.9040200@oracle.com> Message-ID: Hi Vincent, I built my estimation on a a small benchmark, the results are here: https://docs.google.com/spreadsheets/d/1fpDkmTrO7SJNvVZGGnt1b6NiErHqLuyzIPuISOXPktg/edit?usp=sharing Source code: http://ur1.ca/hgkrl This benchmark actually does the estimation during runtime, but that calculation should not be significant compared to buffer allocation. On Thu, Jun 5, 2014 at 9:33 PM, Vicente-Arturo Romero-Zaldivar < vicente.romero at oracle.com> wrote: > Hi Laszlo, > > > On 05/06/14 20:27, Laszlo Hornyak wrote: > >> Hi, >> >> Given this sample code >> >> public static String sayHello(String name, int age) { >> return "Hello " + name + ", this is your " + age + "th birthday"; >> } >> >> The compiler will generate this bytecode: >> 0: new #11 // class >> java/lang/StringBuilder >> 3: dup >> 4: invokespecial #12 // Method >> java/lang/StringBuilder."":()V >> 7: ldc #19 // String Hello >> 9: invokevirtual #15 // Method >> java/lang/StringBuilder.append:(Ljava/lang/String;) >> Ljava/lang/StringBuilder; >> 12: aload_0 >> 13: invokevirtual #15 // Method >> java/lang/StringBuilder.append:(Ljava/lang/String;) >> Ljava/lang/StringBuilder; >> 16: ldc #20 // String , this is your >> 18: invokevirtual #15 // Method >> java/lang/StringBuilder.append:(Ljava/lang/String;) >> Ljava/lang/StringBuilder; >> 21: iload_1 >> 22: invokevirtual #13 // Method >> java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; >> 25: ldc #21 // String th birthday >> 27: invokevirtual #15 // Method >> java/lang/StringBuilder.append:(Ljava/lang/String;) >> Ljava/lang/StringBuilder; >> 30: invokevirtual #17 // Method >> java/lang/StringBuilder.toString:()Ljava/lang/String; >> 33: areturn >> >> The most interesting line is: >> 4: invokespecial #12 // Method >> java/lang/StringBuilder."":()V >> >> >> Since all the string literals are given for the compiler, it could give >> an estimation on the required buffer size to the StringBuilder constructor. >> In this example the string literals already take 32 characters, plus a >> string representation of an integer takes up to 12 characters. The String >> size is 0 to Integer.MAX_VALUE, but 16 might be a good default. In this >> case a constructor call could be generated to allocate a buffer with 50 >> characters and some (possibly all) buffer re-allocation could be saved in >> the subsequent append calls. >> The performance gain seems to be significant since the subsequent buffer >> allocations can take up to 30-40 percent of the execution time. >> > > Just curious, do you have a proof for this? > > > Is there a specific reason for the java compiler not to support >> pre-allocation of StringBuilder buffer based on string literals and >> parameters? >> >> Thank you, >> Laszlo >> >> >> -- >> >> EOF >> > Thanks, > Vicente > -- EOF -------------- next part -------------- An HTML attachment was scrubbed... URL: From jonathan.gibbons at oracle.com Thu Jun 5 20:21:48 2014 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Thu, 05 Jun 2014 13:21:48 -0700 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: References: Message-ID: <5390D15C.7040500@oracle.com> It could be done, but all the compiler could do would be to estimate a lower bound for the length. I'm not sure it is reasonable to estimate a length of 16 for the .toString of all objects, so it makes you wonder how effective the extra step might be. -- Jon On 06/05/2014 12:27 PM, Laszlo Hornyak wrote: > Hi, > > Given this sample code > > public static String sayHello(String name, int age) { > return "Hello " + name + ", this is your " + age + "th birthday"; > } > > The compiler will generate this bytecode: > 0: new #11 // class > java/lang/StringBuilder > 3: dup > 4: invokespecial #12 // Method > java/lang/StringBuilder."":()V > 7: ldc #19 // String Hello > 9: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 12: aload_0 > 13: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 16: ldc #20 // String , this is your > 18: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 21: iload_1 > 22: invokevirtual #13 // Method > java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; > 25: ldc #21 // String th birthday > 27: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 30: invokevirtual #17 // Method > java/lang/StringBuilder.toString:()Ljava/lang/String; > 33: areturn > > The most interesting line is: > 4: invokespecial #12 // Method > java/lang/StringBuilder."":()V > > > Since all the string literals are given for the compiler, it could > give an estimation on the required buffer size to the StringBuilder > constructor. In this example the string literals already take 32 > characters, plus a string representation of an integer takes up to 12 > characters. The String size is 0 to Integer.MAX_VALUE, but 16 might be > a good default. In this case a constructor call could be generated to > allocate a buffer with 50 characters and some (possibly all) buffer > re-allocation could be saved in the subsequent append calls. > The performance gain seems to be significant since the subsequent > buffer allocations can take up to 30-40 percent of the execution time. > Is there a specific reason for the java compiler not to support > pre-allocation of StringBuilder buffer based on string literals and > parameters? > > Thank you, > Laszlo > > > -- > > EOF From laszlo.hornyak at gmail.com Thu Jun 5 20:33:57 2014 From: laszlo.hornyak at gmail.com (Laszlo Hornyak) Date: Thu, 5 Jun 2014 22:33:57 +0200 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: <5390D15C.7040500@oracle.com> References: <5390D15C.7040500@oracle.com> Message-ID: Hi Jon, As a first step I think we can agree to the lower bound, that is better than a hardcoded default and should avoid some re-allocation. On Thu, Jun 5, 2014 at 10:21 PM, Jonathan Gibbons < jonathan.gibbons at oracle.com> wrote: > It could be done, but all the compiler could do would be to estimate a > lower bound for the length. I'm not sure it is reasonable to estimate a > length of 16 for the .toString of all objects, so it makes you wonder how > effective the extra step might be. > > -- Jon > > > On 06/05/2014 12:27 PM, Laszlo Hornyak wrote: > >> Hi, >> >> Given this sample code >> >> public static String sayHello(String name, int age) { >> return "Hello " + name + ", this is your " + age + "th birthday"; >> } >> >> The compiler will generate this bytecode: >> 0: new #11 // class >> java/lang/StringBuilder >> 3: dup >> 4: invokespecial #12 // Method >> java/lang/StringBuilder."":()V >> 7: ldc #19 // String Hello >> 9: invokevirtual #15 // Method >> java/lang/StringBuilder.append:(Ljava/lang/String;) >> Ljava/lang/StringBuilder; >> 12: aload_0 >> 13: invokevirtual #15 // Method >> java/lang/StringBuilder.append:(Ljava/lang/String;) >> Ljava/lang/StringBuilder; >> 16: ldc #20 // String , this is your >> 18: invokevirtual #15 // Method >> java/lang/StringBuilder.append:(Ljava/lang/String;) >> Ljava/lang/StringBuilder; >> 21: iload_1 >> 22: invokevirtual #13 // Method >> java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; >> 25: ldc #21 // String th birthday >> 27: invokevirtual #15 // Method >> java/lang/StringBuilder.append:(Ljava/lang/String;) >> Ljava/lang/StringBuilder; >> 30: invokevirtual #17 // Method >> java/lang/StringBuilder.toString:()Ljava/lang/String; >> 33: areturn >> >> The most interesting line is: >> 4: invokespecial #12 // Method >> java/lang/StringBuilder."":()V >> >> >> Since all the string literals are given for the compiler, it could give >> an estimation on the required buffer size to the StringBuilder constructor. >> In this example the string literals already take 32 characters, plus a >> string representation of an integer takes up to 12 characters. The String >> size is 0 to Integer.MAX_VALUE, but 16 might be a good default. In this >> case a constructor call could be generated to allocate a buffer with 50 >> characters and some (possibly all) buffer re-allocation could be saved in >> the subsequent append calls. >> The performance gain seems to be significant since the subsequent buffer >> allocations can take up to 30-40 percent of the execution time. >> Is there a specific reason for the java compiler not to support >> pre-allocation of StringBuilder buffer based on string literals and >> parameters? >> >> Thank you, >> Laszlo >> >> >> -- >> >> EOF >> > > -- EOF -------------- next part -------------- An HTML attachment was scrubbed... URL: From laszlo.hornyak at gmail.com Thu Jun 5 20:39:48 2014 From: laszlo.hornyak at gmail.com (Laszlo Hornyak) Date: Thu, 5 Jun 2014 22:39:48 +0200 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: References: Message-ID: Hi Vitaly, I tested with server VM and the test code has some warmup so that the JIT should have enough time to kick in, but I will check stringopts if it should do some relevant optimization. On Thu, Jun 5, 2014 at 9:43 PM, Vitaly Davidovich wrote: > Hi Laszlo, > > I believe server jit compiler has an optimization pass that will attempt > at fusing this type of pattern into one string allocation -- see > src/share/vm/opto/stringopts.[h|c]pp in the sources. Have you tried > benchmarking this after jit compiler gets a crack at it? > > > On Thu, Jun 5, 2014 at 3:27 PM, Laszlo Hornyak > wrote: > >> Hi, >> >> Given this sample code >> >> public static String sayHello(String name, int age) { >> return "Hello " + name + ", this is your " + age + "th birthday"; >> } >> >> The compiler will generate this bytecode: >> 0: new #11 // class >> java/lang/StringBuilder >> 3: dup >> 4: invokespecial #12 // Method >> java/lang/StringBuilder."":()V >> 7: ldc #19 // String Hello >> 9: invokevirtual #15 // Method >> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >> 12: aload_0 >> 13: invokevirtual #15 // Method >> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >> 16: ldc #20 // String , this is your >> 18: invokevirtual #15 // Method >> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >> 21: iload_1 >> 22: invokevirtual #13 // Method >> java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; >> 25: ldc #21 // String th birthday >> 27: invokevirtual #15 // Method >> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >> 30: invokevirtual #17 // Method >> java/lang/StringBuilder.toString:()Ljava/lang/String; >> 33: areturn >> >> The most interesting line is: >> 4: invokespecial #12 // Method >> java/lang/StringBuilder."":()V >> >> >> Since all the string literals are given for the compiler, it could give >> an estimation on the required buffer size to the StringBuilder constructor. >> In this example the string literals already take 32 characters, plus a >> string representation of an integer takes up to 12 characters. The String >> size is 0 to Integer.MAX_VALUE, but 16 might be a good default. In this >> case a constructor call could be generated to allocate a buffer with 50 >> characters and some (possibly all) buffer re-allocation could be saved in >> the subsequent append calls. >> The performance gain seems to be significant since the subsequent buffer >> allocations can take up to 30-40 percent of the execution time. >> Is there a specific reason for the java compiler not to support >> pre-allocation of StringBuilder buffer based on string literals and >> parameters? >> >> Thank you, >> Laszlo >> >> >> -- >> >> EOF >> > > -- EOF -------------- next part -------------- An HTML attachment was scrubbed... URL: From vitalyd at gmail.com Thu Jun 5 21:01:11 2014 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Thu, 5 Jun 2014 17:01:11 -0400 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: References: Message-ID: I think your benchmark is testing something else though, which is cost of resizing during appends. To test the issue at hand, try writing two methods, one which does string appends manually to a pre allocated SB of the right size (which is what you want javac to do) and one that does the string concat. Sent from my phone On Jun 5, 2014 4:39 PM, "Laszlo Hornyak" wrote: > Hi Vitaly, > > I tested with server VM and the test code has some warmup so that the JIT > should have enough time to kick in, but I will check stringopts if it > should do some relevant optimization. > > > > On Thu, Jun 5, 2014 at 9:43 PM, Vitaly Davidovich > wrote: > >> Hi Laszlo, >> >> I believe server jit compiler has an optimization pass that will attempt >> at fusing this type of pattern into one string allocation -- see >> src/share/vm/opto/stringopts.[h|c]pp in the sources. Have you tried >> benchmarking this after jit compiler gets a crack at it? >> >> >> On Thu, Jun 5, 2014 at 3:27 PM, Laszlo Hornyak >> wrote: >> >>> Hi, >>> >>> Given this sample code >>> >>> public static String sayHello(String name, int age) { >>> return "Hello " + name + ", this is your " + age + "th birthday"; >>> } >>> >>> The compiler will generate this bytecode: >>> 0: new #11 // class >>> java/lang/StringBuilder >>> 3: dup >>> 4: invokespecial #12 // Method >>> java/lang/StringBuilder."":()V >>> 7: ldc #19 // String Hello >>> 9: invokevirtual #15 // Method >>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>> 12: aload_0 >>> 13: invokevirtual #15 // Method >>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>> 16: ldc #20 // String , this is your >>> 18: invokevirtual #15 // Method >>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>> 21: iload_1 >>> 22: invokevirtual #13 // Method >>> java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; >>> 25: ldc #21 // String th birthday >>> 27: invokevirtual #15 // Method >>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>> 30: invokevirtual #17 // Method >>> java/lang/StringBuilder.toString:()Ljava/lang/String; >>> 33: areturn >>> >>> The most interesting line is: >>> 4: invokespecial #12 // Method >>> java/lang/StringBuilder."":()V >>> >>> >>> Since all the string literals are given for the compiler, it could give >>> an estimation on the required buffer size to the StringBuilder constructor. >>> In this example the string literals already take 32 characters, plus a >>> string representation of an integer takes up to 12 characters. The String >>> size is 0 to Integer.MAX_VALUE, but 16 might be a good default. In this >>> case a constructor call could be generated to allocate a buffer with 50 >>> characters and some (possibly all) buffer re-allocation could be saved in >>> the subsequent append calls. >>> The performance gain seems to be significant since the subsequent buffer >>> allocations can take up to 30-40 percent of the execution time. >>> Is there a specific reason for the java compiler not to support >>> pre-allocation of StringBuilder buffer based on string literals and >>> parameters? >>> >>> Thank you, >>> Laszlo >>> >>> >>> -- >>> >>> EOF >>> >> >> > > > -- > > EOF > -------------- next part -------------- An HTML attachment was scrubbed... URL: From john.r.rose at oracle.com Thu Jun 5 21:16:11 2014 From: john.r.rose at oracle.com (John Rose) Date: Thu, 5 Jun 2014 14:16:11 -0700 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: References: Message-ID: <41480E11-83F4-4976-A898-32B6573FEC56@oracle.com> On Jun 5, 2014, at 12:27 PM, Laszlo Hornyak wrote: > public static String sayHello(String name, int age) { > return "Hello " + name + ", this is your " + age + "th birthday"; > } Try this example (suitably wrapped) with -XX:-OptimizeStringConcat and -XX:+OptimizeStringConcat. You should see a substantial difference. I saw 3x. Pre-optimizing bytecode shapes (in javac) is usually a bad idea. Bytecodes are best thought of as a portable representation of programmer intention, not a vehicle for optimization. ? John -------------- next part -------------- An HTML attachment was scrubbed... URL: From laszlo.hornyak at gmail.com Fri Jun 6 16:07:04 2014 From: laszlo.hornyak at gmail.com (Laszlo Hornyak) Date: Fri, 6 Jun 2014 18:07:04 +0200 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: References: Message-ID: I think that is in sync with the subject of this email thread. On Thu, Jun 5, 2014 at 11:01 PM, Vitaly Davidovich wrote: > I think your benchmark is testing something else though, which is cost of > resizing during appends. > > To test the issue at hand, try writing two methods, one which does string > appends manually to a pre allocated SB of the right size (which is what you > want javac to do) and one that does the string concat. > > Sent from my phone > On Jun 5, 2014 4:39 PM, "Laszlo Hornyak" wrote: > >> Hi Vitaly, >> >> I tested with server VM and the test code has some warmup so that the JIT >> should have enough time to kick in, but I will check stringopts if it >> should do some relevant optimization. >> >> >> >> On Thu, Jun 5, 2014 at 9:43 PM, Vitaly Davidovich >> wrote: >> >>> Hi Laszlo, >>> >>> I believe server jit compiler has an optimization pass that will attempt >>> at fusing this type of pattern into one string allocation -- see >>> src/share/vm/opto/stringopts.[h|c]pp in the sources. Have you tried >>> benchmarking this after jit compiler gets a crack at it? >>> >>> >>> On Thu, Jun 5, 2014 at 3:27 PM, Laszlo Hornyak >> > wrote: >>> >>>> Hi, >>>> >>>> Given this sample code >>>> >>>> public static String sayHello(String name, int age) { >>>> return "Hello " + name + ", this is your " + age + "th >>>> birthday"; >>>> } >>>> >>>> The compiler will generate this bytecode: >>>> 0: new #11 // class >>>> java/lang/StringBuilder >>>> 3: dup >>>> 4: invokespecial #12 // Method >>>> java/lang/StringBuilder."":()V >>>> 7: ldc #19 // String Hello >>>> 9: invokevirtual #15 // Method >>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>>> 12: aload_0 >>>> 13: invokevirtual #15 // Method >>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>>> 16: ldc #20 // String , this is your >>>> 18: invokevirtual #15 // Method >>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>>> 21: iload_1 >>>> 22: invokevirtual #13 // Method >>>> java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; >>>> 25: ldc #21 // String th birthday >>>> 27: invokevirtual #15 // Method >>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>>> 30: invokevirtual #17 // Method >>>> java/lang/StringBuilder.toString:()Ljava/lang/String; >>>> 33: areturn >>>> >>>> The most interesting line is: >>>> 4: invokespecial #12 // Method >>>> java/lang/StringBuilder."":()V >>>> >>>> >>>> Since all the string literals are given for the compiler, it could give >>>> an estimation on the required buffer size to the StringBuilder constructor. >>>> In this example the string literals already take 32 characters, plus a >>>> string representation of an integer takes up to 12 characters. The String >>>> size is 0 to Integer.MAX_VALUE, but 16 might be a good default. In this >>>> case a constructor call could be generated to allocate a buffer with 50 >>>> characters and some (possibly all) buffer re-allocation could be saved in >>>> the subsequent append calls. >>>> The performance gain seems to be significant since the subsequent >>>> buffer allocations can take up to 30-40 percent of the execution time. >>>> Is there a specific reason for the java compiler not to support >>>> pre-allocation of StringBuilder buffer based on string literals and >>>> parameters? >>>> >>>> Thank you, >>>> Laszlo >>>> >>>> >>>> -- >>>> >>>> EOF >>>> >>> >>> >> >> >> -- >> >> EOF >> > -- EOF -------------- next part -------------- An HTML attachment was scrubbed... URL: From vitalyd at gmail.com Fri Jun 6 16:20:49 2014 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Fri, 6 Jun 2014 12:20:49 -0400 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: References: Message-ID: I don't see how it's in sync; you're testing appending in a loop (with non-constant trip count, at least unless JIT completely devirtualizes and inlines everything). I thought the topic of this thread was difference in performance between effectively: public static String sayHello(String name, int age) { //return "Hello " + name + ", this is your " + age + "th birthday"; StringBuilder sb = new StringBuilder(); return sb.append("Hello ").append(name).append(...) ... .toString(); } vs public static String sayHello(String name, int age) { StringBuilder sb = new StringBuilder(); return sb.append("Hello ").append(name).append(...) ... .toString(); } There's no loop here and each invocation of this is a separate StringBuilder instance, so even if you were to call sayHello() from a loop, the semantics are different from your benchmark. On Fri, Jun 6, 2014 at 12:07 PM, Laszlo Hornyak wrote: > I think that is in sync with the subject of this email thread. > > > On Thu, Jun 5, 2014 at 11:01 PM, Vitaly Davidovich > wrote: > >> I think your benchmark is testing something else though, which is cost of >> resizing during appends. >> >> To test the issue at hand, try writing two methods, one which does string >> appends manually to a pre allocated SB of the right size (which is what you >> want javac to do) and one that does the string concat. >> >> Sent from my phone >> On Jun 5, 2014 4:39 PM, "Laszlo Hornyak" >> wrote: >> >>> Hi Vitaly, >>> >>> I tested with server VM and the test code has some warmup so that the >>> JIT should have enough time to kick in, but I will check stringopts if it >>> should do some relevant optimization. >>> >>> >>> >>> On Thu, Jun 5, 2014 at 9:43 PM, Vitaly Davidovich >>> wrote: >>> >>>> Hi Laszlo, >>>> >>>> I believe server jit compiler has an optimization pass that will >>>> attempt at fusing this type of pattern into one string allocation -- see >>>> src/share/vm/opto/stringopts.[h|c]pp in the sources. Have you tried >>>> benchmarking this after jit compiler gets a crack at it? >>>> >>>> >>>> On Thu, Jun 5, 2014 at 3:27 PM, Laszlo Hornyak < >>>> laszlo.hornyak at gmail.com> wrote: >>>> >>>>> Hi, >>>>> >>>>> Given this sample code >>>>> >>>>> public static String sayHello(String name, int age) { >>>>> return "Hello " + name + ", this is your " + age + "th >>>>> birthday"; >>>>> } >>>>> >>>>> The compiler will generate this bytecode: >>>>> 0: new #11 // class >>>>> java/lang/StringBuilder >>>>> 3: dup >>>>> 4: invokespecial #12 // Method >>>>> java/lang/StringBuilder."":()V >>>>> 7: ldc #19 // String Hello >>>>> 9: invokevirtual #15 // Method >>>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>>>> 12: aload_0 >>>>> 13: invokevirtual #15 // Method >>>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>>>> 16: ldc #20 // String , this is your >>>>> 18: invokevirtual #15 // Method >>>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>>>> 21: iload_1 >>>>> 22: invokevirtual #13 // Method >>>>> java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; >>>>> 25: ldc #21 // String th birthday >>>>> 27: invokevirtual #15 // Method >>>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>>>> 30: invokevirtual #17 // Method >>>>> java/lang/StringBuilder.toString:()Ljava/lang/String; >>>>> 33: areturn >>>>> >>>>> The most interesting line is: >>>>> 4: invokespecial #12 // Method >>>>> java/lang/StringBuilder."":()V >>>>> >>>>> >>>>> Since all the string literals are given for the compiler, it could >>>>> give an estimation on the required buffer size to the StringBuilder >>>>> constructor. In this example the string literals already take 32 >>>>> characters, plus a string representation of an integer takes up to 12 >>>>> characters. The String size is 0 to Integer.MAX_VALUE, but 16 might be a >>>>> good default. In this case a constructor call could be generated to >>>>> allocate a buffer with 50 characters and some (possibly all) buffer >>>>> re-allocation could be saved in the subsequent append calls. >>>>> The performance gain seems to be significant since the subsequent >>>>> buffer allocations can take up to 30-40 percent of the execution time. >>>>> Is there a specific reason for the java compiler not to support >>>>> pre-allocation of StringBuilder buffer based on string literals and >>>>> parameters? >>>>> >>>>> Thank you, >>>>> Laszlo >>>>> >>>>> >>>>> -- >>>>> >>>>> EOF >>>>> >>>> >>>> >>> >>> >>> -- >>> >>> EOF >>> >> > > > -- > > EOF > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vitalyd at gmail.com Fri Jun 6 16:21:56 2014 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Fri, 6 Jun 2014 12:21:56 -0400 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: References: Message-ID: Sorry, hit Send too early. The first version of sayHello in my previous email should be: public static String sayHello(String name, int age) { StringBuilder sb = new StringBuilder(); return sb.append("Hello ").append(name).append(...) ... .toString(); } On Fri, Jun 6, 2014 at 12:20 PM, Vitaly Davidovich wrote: > I don't see how it's in sync; you're testing appending in a loop (with > non-constant trip count, at least unless JIT completely devirtualizes and > inlines everything). I thought the topic of this thread was difference in > performance between effectively: > > public static String sayHello(String name, int age) { > //return "Hello " + name + ", this is your " + age + "th birthday"; > StringBuilder sb = new StringBuilder(); > > return sb.append("Hello ").append(name).append(...) ... > .toString(); > > } > vs > public static String sayHello(String name, int age) { > StringBuilder sb = new StringBuilder(); > return sb.append("Hello ").append(name).append(...) ... > .toString(); > } > > There's no loop here and each invocation of this is a separate > StringBuilder instance, so even if you were to call sayHello() from a loop, > the semantics are different from your benchmark. > > > > > On Fri, Jun 6, 2014 at 12:07 PM, Laszlo Hornyak > wrote: > >> I think that is in sync with the subject of this email thread. >> >> >> On Thu, Jun 5, 2014 at 11:01 PM, Vitaly Davidovich >> wrote: >> >>> I think your benchmark is testing something else though, which is cost >>> of resizing during appends. >>> >>> To test the issue at hand, try writing two methods, one which does >>> string appends manually to a pre allocated SB of the right size (which is >>> what you want javac to do) and one that does the string concat. >>> >>> Sent from my phone >>> On Jun 5, 2014 4:39 PM, "Laszlo Hornyak" >>> wrote: >>> >>>> Hi Vitaly, >>>> >>>> I tested with server VM and the test code has some warmup so that the >>>> JIT should have enough time to kick in, but I will check stringopts if it >>>> should do some relevant optimization. >>>> >>>> >>>> >>>> On Thu, Jun 5, 2014 at 9:43 PM, Vitaly Davidovich >>>> wrote: >>>> >>>>> Hi Laszlo, >>>>> >>>>> I believe server jit compiler has an optimization pass that will >>>>> attempt at fusing this type of pattern into one string allocation -- see >>>>> src/share/vm/opto/stringopts.[h|c]pp in the sources. Have you tried >>>>> benchmarking this after jit compiler gets a crack at it? >>>>> >>>>> >>>>> On Thu, Jun 5, 2014 at 3:27 PM, Laszlo Hornyak < >>>>> laszlo.hornyak at gmail.com> wrote: >>>>> >>>>>> Hi, >>>>>> >>>>>> Given this sample code >>>>>> >>>>>> public static String sayHello(String name, int age) { >>>>>> return "Hello " + name + ", this is your " + age + "th >>>>>> birthday"; >>>>>> } >>>>>> >>>>>> The compiler will generate this bytecode: >>>>>> 0: new #11 // class >>>>>> java/lang/StringBuilder >>>>>> 3: dup >>>>>> 4: invokespecial #12 // Method >>>>>> java/lang/StringBuilder."":()V >>>>>> 7: ldc #19 // String Hello >>>>>> 9: invokevirtual #15 // Method >>>>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>>>>> 12: aload_0 >>>>>> 13: invokevirtual #15 // Method >>>>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>>>>> 16: ldc #20 // String , this is your >>>>>> 18: invokevirtual #15 // Method >>>>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>>>>> 21: iload_1 >>>>>> 22: invokevirtual #13 // Method >>>>>> java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; >>>>>> 25: ldc #21 // String th birthday >>>>>> 27: invokevirtual #15 // Method >>>>>> java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; >>>>>> 30: invokevirtual #17 // Method >>>>>> java/lang/StringBuilder.toString:()Ljava/lang/String; >>>>>> 33: areturn >>>>>> >>>>>> The most interesting line is: >>>>>> 4: invokespecial #12 // Method >>>>>> java/lang/StringBuilder."":()V >>>>>> >>>>>> >>>>>> Since all the string literals are given for the compiler, it could >>>>>> give an estimation on the required buffer size to the StringBuilder >>>>>> constructor. In this example the string literals already take 32 >>>>>> characters, plus a string representation of an integer takes up to 12 >>>>>> characters. The String size is 0 to Integer.MAX_VALUE, but 16 might be a >>>>>> good default. In this case a constructor call could be generated to >>>>>> allocate a buffer with 50 characters and some (possibly all) buffer >>>>>> re-allocation could be saved in the subsequent append calls. >>>>>> The performance gain seems to be significant since the subsequent >>>>>> buffer allocations can take up to 30-40 percent of the execution time. >>>>>> Is there a specific reason for the java compiler not to support >>>>>> pre-allocation of StringBuilder buffer based on string literals and >>>>>> parameters? >>>>>> >>>>>> Thank you, >>>>>> Laszlo >>>>>> >>>>>> >>>>>> -- >>>>>> >>>>>> EOF >>>>>> >>>>> >>>>> >>>> >>>> >>>> -- >>>> >>>> EOF >>>> >>> >> >> >> -- >> >> EOF >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From robert.field at oracle.com Fri Jun 6 16:25:53 2014 From: robert.field at oracle.com (Robert Field) Date: Fri, 06 Jun 2014 09:25:53 -0700 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: References: Message-ID: <5391EB91.2060602@oracle.com> Notes from the peanut gallery: If this is an important case to optimize, then a set of constructors which take N Strings seems it would give you much more. -Robert On 06/05/14 12:27, Laszlo Hornyak wrote: > Hi, > > Given this sample code > > public static String sayHello(String name, int age) { > return "Hello " + name + ", this is your " + age + "th birthday"; > } > > The compiler will generate this bytecode: > 0: new #11 // class > java/lang/StringBuilder > 3: dup > 4: invokespecial #12 // Method > java/lang/StringBuilder."":()V > 7: ldc #19 // String Hello > 9: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 12: aload_0 > 13: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 16: ldc #20 // String , this is your > 18: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 21: iload_1 > 22: invokevirtual #13 // Method > java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; > 25: ldc #21 // String th birthday > 27: invokevirtual #15 // Method > java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; > 30: invokevirtual #17 // Method > java/lang/StringBuilder.toString:()Ljava/lang/String; > 33: areturn > > The most interesting line is: > 4: invokespecial #12 // Method > java/lang/StringBuilder."":()V > > > Since all the string literals are given for the compiler, it could > give an estimation on the required buffer size to the StringBuilder > constructor. In this example the string literals already take 32 > characters, plus a string representation of an integer takes up to 12 > characters. The String size is 0 to Integer.MAX_VALUE, but 16 might be > a good default. In this case a constructor call could be generated to > allocate a buffer with 50 characters and some (possibly all) buffer > re-allocation could be saved in the subsequent append calls. > The performance gain seems to be significant since the subsequent > buffer allocations can take up to 30-40 percent of the execution time. > Is there a specific reason for the java compiler not to support > pre-allocation of StringBuilder buffer based on string literals and > parameters? > > Thank you, > Laszlo > > > -- > > EOF From oehrstroem at gmail.com Mon Jun 9 22:39:58 2014 From: oehrstroem at gmail.com (=?UTF-8?B?RnJlZHJpayDDlmhyc3Ryw7Zt?=) Date: Tue, 10 Jun 2014 00:39:58 +0200 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: <41480E11-83F4-4976-A898-32B6573FEC56@oracle.com> References: <41480E11-83F4-4976-A898-32B6573FEC56@oracle.com> Message-ID: I do not know how Hotspot optimizes string concatenations, but JRockit did some fun things as well, like replacing StringBuilder (at runtime) with an internal JRockit specific StringMaker, that merely stored references to the constant strings in an array. Thus the .append(x) did very little work, all the concatenation work then happened in toString() where it first scanned the appended strings length and could calculate the final length of the concatenated string. Thus only a single allocation was necessary and there was no superfluous copying. 2014-06-05 23:16 GMT+02:00 John Rose : > On Jun 5, 2014, at 12:27 PM, Laszlo Hornyak > wrote: > > public static String sayHello(String name, int age) { > return "Hello " + name + ", this is your " + age + "th birthday"; > } > > > Try this example (suitably wrapped) with -XX:-OptimizeStringConcat and > -XX:+OptimizeStringConcat. > > You should see a substantial difference. I saw 3x. > > Pre-optimizing bytecode shapes (in javac) is usually a bad idea. > Bytecodes are best thought of as a portable representation of programmer > intention, not a vehicle for optimization. > > ? John > -------------- next part -------------- An HTML attachment was scrubbed... URL: From john.r.rose at oracle.com Mon Jun 9 22:57:06 2014 From: john.r.rose at oracle.com (John Rose) Date: Mon, 9 Jun 2014 15:57:06 -0700 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: References: <41480E11-83F4-4976-A898-32B6573FEC56@oracle.com> Message-ID: <90F339FF-81B5-4705-9AB6-62317B38783B@oracle.com> On Jun 9, 2014, at 3:39 PM, Fredrik ?hrstr?m wrote: > I do not know how Hotspot optimizes string concatenations, but JRockit did some fun things as well, like replacing StringBuilder (at runtime) with an internal JRockit specific StringMaker, that merely stored references to the constant strings in an array. But could JRockit EA-away the array, unroll the loops, and turn everything into custom code? Come to think of it, JRockit could. Nice trick. Hmm, I wonder if we have any other types that set up with cumulative method-call chains but need to boil down to custom code. There was this thing called "Streams", wasn't there? :-) My bottom line: The JVM needs to get a better handle on these builder patterns. > Thus the .append(x) did very little work, all the concatenation work then happened in toString() where it first scanned the appended strings length and could calculate the final length of the concatenated string. Thus only a single allocation was necessary and there was no superfluous copying. On Jun 6, 2014, at 9:25 AM, Robert Field wrote: > Notes from the peanut gallery: If this is an important case to optimize, then a set of constructors which take N Strings seems it would give you much more. For built-in stuff like string formatting expressions, lambda expressions, and (eventually) object constructor expressions ("enhanced literals"), a very good trick, IMO, is coding the form of the result into an invokedynamic, and letting a system metafactory figure out the optimal implementation. As you know, Robert, with a MF you can pretend you have an infinite family of object constructors, each with exactly the right signature required at the point of use. This would work fine for string formatting expressions. It would be about as compact (or slightly more so) than the current StringBuilder code shapes, but would allow the JVM the option to generate exactly customized code for each combination of constant and variable formatting components. ? John -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Mon Jun 9 23:16:20 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 10 Jun 2014 01:16:20 +0200 Subject: StringBuilder buffer allocation support in compiler In-Reply-To: <90F339FF-81B5-4705-9AB6-62317B38783B@oracle.com> References: <41480E11-83F4-4976-A898-32B6573FEC56@oracle.com> <90F339FF-81B5-4705-9AB6-62317B38783B@oracle.com> Message-ID: <53964044.2080007@univ-mlv.fr> On 06/10/2014 12:57 AM, John Rose wrote: > On Jun 9, 2014, at 3:39 PM, Fredrik ?hrstr?m > wrote: > >> I do not know how Hotspot optimizes string concatenations, but >> JRockit did some fun things as well, like replacing StringBuilder (at >> runtime) with an internal JRockit specific StringMaker, that merely >> stored references to the constant strings in an array. > > But could JRockit EA-away the array, unroll the loops, and turn > everything into custom code? > > Come to think of it, JRockit could. Nice trick. > > Hmm, I wonder if we have any other types that set up with cumulative > method-call chains but need to boil down to custom code. There was > this thing called "Streams", wasn't there? :-) > > My bottom line: The JVM needs to get a better handle on these builder > patterns. > >> Thus the .append(x) did very little work, all the concatenation work >> then happened in toString() where it first scanned the appended >> strings length and could calculate the final length of the >> concatenated string. Thus only a single allocation was necessary and >> there was no superfluous copying. > > On Jun 6, 2014, at 9:25 AM, Robert Field > wrote: > >> Notes from the peanut gallery: If this is an important case to >> optimize, then a set of constructors which take N Strings seems it >> would give you much more. > > For built-in stuff like string formatting expressions, lambda > expressions, and (eventually) object constructor expressions > ("enhanced literals"), a very good trick, IMO, is coding the form of > the result into an invokedynamic, and letting a system metafactory > figure out the optimal implementation. As you know, Robert, with a MF > you can pretend you have an infinite family of object constructors, > each with exactly the right signature required at the point of use. > This would work fine for string formatting expressions. It would be > about as compact (or slightly more so) than the current StringBuilder > code shapes, but would allow the JVM the option to generate exactly > customized code for each combination of constant and variable > formatting components. > > ? John and the real question is how to let API developers to specify their own meta-factory (a meta protocol ?) R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From wdietl at gmail.com Wed Jun 11 00:10:20 2014 From: wdietl at gmail.com (Werner Dietl) Date: Tue, 10 Jun 2014 20:10:20 -0400 Subject: Public review of rearchitected front-end type annotations pipeline In-Reply-To: <538DDAB6.9060804@oracle.com> References: <536D3130.2010500@oracle.com> <5374EE10.5060500@oracle.com> <538DDAB6.9060804@oracle.com> Message-ID: Hi Eric, thanks for integrating this huge refactoring! I've worked on adapting the Checker Framework to this; there are only small code changes I needed to perform, but a few tests started failing. I do notice that test case test/tools/javac/processing/model/type/BasicAnnoTests.java is now failing for even the simple examples that previously worked. That is, the Type for a Tree is apparently not set correctly. To further show the problem, run javadoc on this example: === import java.lang.annotation.*; public class JavaDoc { public @TA Object foo(); } @Documented @Target(ElementType.TYPE_USE) @interface TA { } === Before the refactoring and with JDK 8, @TA was visible on the return type. It is now no longer present. What do you make of this changed behavior? Best regards, cu, WMD. On Tue, Jun 3, 2014 at 10:24 AM, Eric McCorkle wrote: > Since I last posted a revision, there has been a significant amount of > review activity by the javac team. > > I have, at this point, merged what I had intended to be the third patch > in the series, and created a combined patch. I have also fixed a few > issues that were found in our review. > > The current revision can be found here: > http://cr.openjdk.java.net/~emc/8027262/webrev.02/ > > Note that since this incorporates what was to be the third patch in the > series, there will not be a third patch anymore. It should be possible > to test Checkers at this point. It is also likely that this will be > integrated very shortly. > > At this point, I will begin evaluating this entire body of work for > inclusion in the upcoming 8u20 update release. One thing I would like > to do is a "before/after" evaluation with as many "real-world" uses of > type annotations as possible. To facilitate this, I will shortly post a > large patch which combines all of my work thus far, which should be > applied against the 8-update repo. When that patch is published, I > would very much appreciate if anyone who is actually using type > annotations at this point could evaluate and report on the correctness > of the 8-update repo with and without the patch. > > As a final note, we are currently putting plans together for 8u40 work. > My tentative plans at this point focus on the javax.lang.model API and > internal javac API's, with particular focus on ensuring that Type's > always have the annotations they should, and on using that to facilitate > cleaning up some code in the backend (mainly Gen), though that is not > set in stone at this point. > > On 05/15/14 12:40, Eric McCorkle wrote: >> I have integrated a number of edits to the patch, from both the public >> and internal reviews, and I have fixed a few issues I found. A new >> version has been posted here: >> >> http://cr.openjdk.java.net/~emc/8027262/webrev.01/ >> >> It is likely that this change will be integrated later today, or >> tomorrow. At that point, I will post the third and final patch in the >> series. >> >> On 05/09/14 15:49, Eric McCorkle wrote: >>> Hello, >>> >>> This is the public review of the second in my series of patches dealing >>> with type annotations. >>> >>> http://cr.openjdk.java.net/~emc/8027262/ >>> >>> This patch rearchitects the type annotations pipeline, integrating >>> handling of type annotations directly into the javac >>> MemberEnter/Annotate/Attr pipeline. It represents the majority of the >>> work I have been doing regarding type annotations for 8u20. >>> >>> The handling of type annotations is now dispatched by the MemberEnter or >>> Attr visitors and uses information from those visitors. Most of the >>> actual functionality is now implemented in Annotate. >>> >>> The new test Stress.java is the test for this patch. Stress.java will >>> cause 8-release javac to fail with an assertion failure. Its addition >>> to the test suite demonstrates that this change fixes those cases. >>> >>> This patch addresses a number of JBS issues: >>> https://bugs.openjdk.java.net/browse/JDK-8027262 >>> https://bugs.openjdk.java.net/browse/JDK-8027261 >>> https://bugs.openjdk.java.net/browse/JDK-8027258 >>> https://bugs.openjdk.java.net/browse/JDK-8027182 >>> and possibly others as well. >>> >>> Note: this patch does not attempt to remove code made obsolete; however, >>> any such code is very clearly marked as deprecated. Removal of dead >>> code will be done in the last of the series. This patch also does not >>> attempt to re-enable tests which were previously disabled. That will be >>> done as a separate patch as well. >>> -- http://www.google.com/profiles/wdietl From andreas.lundblad at oracle.com Thu Jun 12 11:03:52 2014 From: andreas.lundblad at oracle.com (Andreas Lundblad) Date: Thu, 12 Jun 2014 13:03:52 +0200 Subject: RFR: 8044131: Restructure sjavac client / server protocol code Message-ID: <20140612110351.GK17197@e6430> Hi compiler-dev, Please review this patch which addresses part of JDK-8044131. - Description: The protocol code needs to be cleaned up. Currently the protocol code is entangled with the code that invokes javac (see CompilerThread.java). In order to replace the protocol code with something better it has to be factored out and separated from the compilation code. This is precisely what this patch does. It also hides the compilation logic behind a new interface (see JavacService.java) which will make the code more flexible. We will for instance be able to easily choose between an in-VM and a server/client implementation based on the background={true,fase} setting. Be aware that this patch is part 1 of 2. Further cleanups ahead. CompilerThread and CompilerPool seems to dissapear for instance. - Link to webrev: http://cr.openjdk.java.net/~alundblad/8044131 - Links to bug report: https://bugs.openjdk.java.net/browse/JDK-8044131 -- Andreas From eric.mccorkle at oracle.com Thu Jun 12 11:31:00 2014 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Thu, 12 Jun 2014 07:31:00 -0400 Subject: Public review of rearchitected front-end type annotations pipeline In-Reply-To: References: <536D3130.2010500@oracle.com> <5374EE10.5060500@oracle.com> <538DDAB6.9060804@oracle.com> Message-ID: <53998F74.3090007@oracle.com> In general, making sure that Type's have the annotations they need is a goal for the next wave of work. Of course, I don't want to introduce regressions, so I'm looking into this issue today and tomorrow. It's quite possible that with the new pipeline, the fix will be very simple, in which case I will roll it into the group of patches we are trying to publish in the upcoming 8 update release. On 06/10/14 20:10, Werner Dietl wrote: > Hi Eric, > > thanks for integrating this huge refactoring! > I've worked on adapting the Checker Framework to this; there are only > small code changes I needed to perform, but a few tests started > failing. > > I do notice that test case > > test/tools/javac/processing/model/type/BasicAnnoTests.java > > is now failing for even the simple examples that previously worked. > That is, the Type for a Tree is apparently not set correctly. > > To further show the problem, run javadoc on this example: > > === > import java.lang.annotation.*; > > public class JavaDoc { > public @TA Object foo(); > } > > @Documented > @Target(ElementType.TYPE_USE) > @interface TA { } > === > > Before the refactoring and with JDK 8, @TA was visible on the return > type. It is now no longer present. > What do you make of this changed behavior? > > Best regards, > cu, WMD. > > > > On Tue, Jun 3, 2014 at 10:24 AM, Eric McCorkle wrote: >> Since I last posted a revision, there has been a significant amount of >> review activity by the javac team. >> >> I have, at this point, merged what I had intended to be the third patch >> in the series, and created a combined patch. I have also fixed a few >> issues that were found in our review. >> >> The current revision can be found here: >> http://cr.openjdk.java.net/~emc/8027262/webrev.02/ >> >> Note that since this incorporates what was to be the third patch in the >> series, there will not be a third patch anymore. It should be possible >> to test Checkers at this point. It is also likely that this will be >> integrated very shortly. >> >> At this point, I will begin evaluating this entire body of work for >> inclusion in the upcoming 8u20 update release. One thing I would like >> to do is a "before/after" evaluation with as many "real-world" uses of >> type annotations as possible. To facilitate this, I will shortly post a >> large patch which combines all of my work thus far, which should be >> applied against the 8-update repo. When that patch is published, I >> would very much appreciate if anyone who is actually using type >> annotations at this point could evaluate and report on the correctness >> of the 8-update repo with and without the patch. >> >> As a final note, we are currently putting plans together for 8u40 work. >> My tentative plans at this point focus on the javax.lang.model API and >> internal javac API's, with particular focus on ensuring that Type's >> always have the annotations they should, and on using that to facilitate >> cleaning up some code in the backend (mainly Gen), though that is not >> set in stone at this point. >> >> On 05/15/14 12:40, Eric McCorkle wrote: >>> I have integrated a number of edits to the patch, from both the public >>> and internal reviews, and I have fixed a few issues I found. A new >>> version has been posted here: >>> >>> http://cr.openjdk.java.net/~emc/8027262/webrev.01/ >>> >>> It is likely that this change will be integrated later today, or >>> tomorrow. At that point, I will post the third and final patch in the >>> series. >>> >>> On 05/09/14 15:49, Eric McCorkle wrote: >>>> Hello, >>>> >>>> This is the public review of the second in my series of patches dealing >>>> with type annotations. >>>> >>>> http://cr.openjdk.java.net/~emc/8027262/ >>>> >>>> This patch rearchitects the type annotations pipeline, integrating >>>> handling of type annotations directly into the javac >>>> MemberEnter/Annotate/Attr pipeline. It represents the majority of the >>>> work I have been doing regarding type annotations for 8u20. >>>> >>>> The handling of type annotations is now dispatched by the MemberEnter or >>>> Attr visitors and uses information from those visitors. Most of the >>>> actual functionality is now implemented in Annotate. >>>> >>>> The new test Stress.java is the test for this patch. Stress.java will >>>> cause 8-release javac to fail with an assertion failure. Its addition >>>> to the test suite demonstrates that this change fixes those cases. >>>> >>>> This patch addresses a number of JBS issues: >>>> https://bugs.openjdk.java.net/browse/JDK-8027262 >>>> https://bugs.openjdk.java.net/browse/JDK-8027261 >>>> https://bugs.openjdk.java.net/browse/JDK-8027258 >>>> https://bugs.openjdk.java.net/browse/JDK-8027182 >>>> and possibly others as well. >>>> >>>> Note: this patch does not attempt to remove code made obsolete; however, >>>> any such code is very clearly marked as deprecated. Removal of dead >>>> code will be done in the last of the series. This patch also does not >>>> attempt to re-enable tests which were previously disabled. That will be >>>> done as a separate patch as well. >>>> > > > -------------- next part -------------- A non-text attachment was scrubbed... Name: eric_mccorkle.vcf Type: text/x-vcard Size: 303 bytes Desc: not available URL: From eric.mccorkle at oracle.com Thu Jun 12 12:05:57 2014 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Thu, 12 Jun 2014 08:05:57 -0400 Subject: Type Annotations: The next steps Message-ID: <539997A5.3020900@oracle.com> The first major wave of type annotations refactorings is now checked in to the jdk9-dev repositories. The javac compiler group is currently evaluating the pros and cons of including this work in the 8u20 update release (if anyone has information relevant to this decision process, please let me know). The objectives of the first wave of type annotations work were as follows: * Integrate the type annotation frontend logic with the javac pipelines * Clean up and modularize the code * Ensure that an Attribute.Compound has the correct type annotation position (with respect to position type, type path, and some of the offsets) from the moment it is created, and that it does not change after that. * Permit a single source annotation to generate multiple bytecode annotations. * Unify the codepaths for handling declaration annotations and type annotations * Get rid of AnnotatedType As of last Friday, these have been accomplished; however, we are far from finished. I am currently planning another wave of work (which should be smaller in scope). Here is a brief overview of the objectives: 1) Every Type should be guaranteed to have the correct annotations, in the same way that every Attribute.Compound is now guaranteed to have the correct type annotation position. Specifically, after Attr it should be possible to read off the type annotations on any particular Type with getAnnotationMirrors() (for Type's on a declaration, this should be possible after MemberEnter). Another part of this work is making sure that the functions on Type's (erasure, superType, etc.) behave as they ought to. 2) Investigate options for cleaning up some of the backend code (in Gen) that are enabled by the ability to read annotations directly off the Type. I looked into a more direct implementation of some of the logic in Gen. As I recall, the problem was that Lower had stripped out the AnnotatedType's, effectively erasing annotations. It would be nice if the logic in Gen could operate directly on the tree and its Type, as opposed to the roundabout method of comparing source positions to figure out if it should set the bytecode index for a type annotation. 3) Cleanup of the existing code. We still aren't where I want to be in terms of code cleanliness in the frontend pipeline. I think the frontend pipeline is in much better shape overall, but it still has a very "construction site" feel to it. We need to spend some time polishing it up and tightening down the bolts, so to speak. 4) The javac compiler group is currently discussing doing some extensive work on the general annotations pipeline. There are several aspects of the existing system that have become a liability, and we are considering ways to rework the pipeline to eliminate those difficulties. 5) Currently, the enforcement of semantic rules is rather disorganized and ad-hoc. I would like it to be more centralized and maintainable, though I don't have a clear roadmap for accomplishing that at this time. -------------- next part -------------- A non-text attachment was scrubbed... Name: eric_mccorkle.vcf Type: text/x-vcard Size: 303 bytes Desc: not available URL: From daniel.smith at oracle.com Fri Jun 13 17:23:14 2014 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 13 Jun 2014 11:23:14 -0600 Subject: RFR: JDK-8046762, Revert some inference fixes in JDK-8033718 Message-ID: <56181A9E-E9BA-4D75-8AD8-81680D93F35A@oracle.com> This is a 8u20 patch to get type inference in a stable state. It rolls back some changes in JDK-8033718 (and accompanying tests), rather than pushing forward with JDK-8039214 (which is the fix for 9). All existing tests pass, including the test added for related bug JDK-8042656 (IntersectionSubVar.java). ?Dan # HG changeset patch # Parent e6d1e9f29132e71bd5d7095241e5fdb0223980bc diff -r e6d1e9f29132 src/share/classes/com/sun/tools/javac/code/Type.java --- a/src/share/classes/com/sun/tools/javac/code/Type.java Tue Jun 10 15:25:01 2014 -0600 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java Fri Jun 13 11:02:45 2014 -0600 @@ -1658,9 +1658,6 @@ //only change bounds if request comes from substBounds super.addBound(ib, bound, types, update); } - else if (bound.hasTag(UNDETVAR) && !((UndetVar) bound).isCaptured()) { - ((UndetVar) bound).addBound(ib.complement(), this, types, false); - } } @Override diff -r e6d1e9f29132 src/share/classes/com/sun/tools/javac/code/Types.java --- a/src/share/classes/com/sun/tools/javac/code/Types.java Tue Jun 10 15:25:01 2014 -0600 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Fri Jun 13 11:02:45 2014 -0600 @@ -1396,7 +1396,7 @@ // debugContainsType(t, s); return isSameWildcard(t, s) || isCaptureOf(s, t) - || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))) && + || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), cvarLowerBound(wildLowerBound(s)))) && // TODO: JDK-8039214, cvarUpperBound call here is incorrect (t.isSuperBound() || isSubtypeNoCapture(cvarUpperBound(wildUpperBound(s)), wildUpperBound(t)))); } diff -r e6d1e9f29132 test/tools/javac/generics/inference/7086586/T7086586.out --- a/test/tools/javac/generics/inference/7086586/T7086586.out Tue Jun 10 15:25:01 2014 -0600 +++ b/test/tools/javac/generics/inference/7086586/T7086586.out Fri Jun 13 11:02:45 2014 -0600 @@ -1,5 +1,5 @@ -T7086586.java:14:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.captureof: 1, ?, java.lang.String) -T7086586.java:15:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.captureof: 1, ?, java.lang.Number) -T7086586.java:16:31: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.captureof: 1, ?, java.lang.Exception) -T7086586.java:17:13: compiler.err.cant.resolve.location.args: kindname.method, nonExistentMethod, , , (compiler.misc.location: kindname.interface, java.util.List, null) +T7086586.java:14:20: compiler.err.cant.apply.symbol: kindname.method, m, java.util.List, java.util.List, kindname.class, T7086586, (compiler.misc.infer.no.conforming.assignment.exists: T, (compiler.misc.inconvertible.types: java.util.List, java.util.List)) +T7086586.java:15:20: compiler.err.cant.apply.symbol: kindname.method, m, java.util.List, java.util.List, kindname.class, T7086586, (compiler.misc.infer.no.conforming.assignment.exists: T, (compiler.misc.inconvertible.types: java.util.List, java.util.List)) +T7086586.java:16:23: compiler.err.cant.apply.symbol: kindname.method, m, java.util.List, java.util.List, kindname.class, T7086586, (compiler.misc.infer.no.conforming.assignment.exists: T, (compiler.misc.inconvertible.types: java.util.List, java.util.List)) +T7086586.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, java.util.List, java.util.List, kindname.class, T7086586, (compiler.misc.infer.no.conforming.assignment.exists: T, (compiler.misc.inconvertible.types: java.util.List, java.util.List)) 4 errors diff -r e6d1e9f29132 test/tools/javac/generics/inference/7086586/T7086586b.java --- a/test/tools/javac/generics/inference/7086586/T7086586b.java Tue Jun 10 15:25:01 2014 -0600 +++ b/test/tools/javac/generics/inference/7086586/T7086586b.java Fri Jun 13 11:02:45 2014 -0600 @@ -23,10 +23,9 @@ /* * @test - * @bug 7086586 8033718 + * @bug 7086586 * - * @summary Inference producing null type argument; inference ignores capture - * variable as upper bound + * @summary Inference producing null type argument */ import java.util.List; @@ -41,8 +40,8 @@ assertionCount++; } - void m(List dummy) { assertTrue(true); } - void m(Object dummy) { assertTrue(false); } + void m(List dummy) { assertTrue(false); } + void m(Object dummy) { assertTrue(true); } void test(List l) { m(l); diff -r e6d1e9f29132 test/tools/javac/generics/inference/NestedWildcards.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/inference/NestedWildcards.java Fri Jun 13 11:02:45 2014 -0600 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046762 + * @summary Nested generic methods that work on wildcard-parameterized types + * @compile NestedWildcards.java + */ + +public class NestedWildcards { + + public static void test(Box b) { + foo(bar(b)); + } + private static Box foo(Box ts) { + return null; + } + public static Box bar(Box language) { + return null; + } + + interface Box {} +} From maurizio.cimadamore at oracle.com Fri Jun 13 17:49:18 2014 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 13 Jun 2014 18:49:18 +0100 Subject: RFR: JDK-8046762, Revert some inference fixes in JDK-8033718 In-Reply-To: <56181A9E-E9BA-4D75-8AD8-81680D93F35A@oracle.com> References: <56181A9E-E9BA-4D75-8AD8-81680D93F35A@oracle.com> Message-ID: <539B399E.8090803@oracle.com> Looks good Maurizio On 13/06/14 18:23, Dan Smith wrote: > This is a 8u20 patch to get type inference in a stable state. It rolls back some changes in JDK-8033718 (and accompanying tests), rather than pushing forward with JDK-8039214 (which is the fix for 9). > > All existing tests pass, including the test added for related bug JDK-8042656 (IntersectionSubVar.java). > > ?Dan > > # HG changeset patch > # Parent e6d1e9f29132e71bd5d7095241e5fdb0223980bc > > diff -r e6d1e9f29132 src/share/classes/com/sun/tools/javac/code/Type.java > --- a/src/share/classes/com/sun/tools/javac/code/Type.java Tue Jun 10 15:25:01 2014 -0600 > +++ b/src/share/classes/com/sun/tools/javac/code/Type.java Fri Jun 13 11:02:45 2014 -0600 > @@ -1658,9 +1658,6 @@ > //only change bounds if request comes from substBounds > super.addBound(ib, bound, types, update); > } > - else if (bound.hasTag(UNDETVAR) && !((UndetVar) bound).isCaptured()) { > - ((UndetVar) bound).addBound(ib.complement(), this, types, false); > - } > } > > @Override > diff -r e6d1e9f29132 src/share/classes/com/sun/tools/javac/code/Types.java > --- a/src/share/classes/com/sun/tools/javac/code/Types.java Tue Jun 10 15:25:01 2014 -0600 > +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Fri Jun 13 11:02:45 2014 -0600 > @@ -1396,7 +1396,7 @@ > // debugContainsType(t, s); > return isSameWildcard(t, s) > || isCaptureOf(s, t) > - || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))) && > + || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), cvarLowerBound(wildLowerBound(s)))) && > // TODO: JDK-8039214, cvarUpperBound call here is incorrect > (t.isSuperBound() || isSubtypeNoCapture(cvarUpperBound(wildUpperBound(s)), wildUpperBound(t)))); > } > diff -r e6d1e9f29132 test/tools/javac/generics/inference/7086586/T7086586.out > --- a/test/tools/javac/generics/inference/7086586/T7086586.out Tue Jun 10 15:25:01 2014 -0600 > +++ b/test/tools/javac/generics/inference/7086586/T7086586.out Fri Jun 13 11:02:45 2014 -0600 > @@ -1,5 +1,5 @@ > -T7086586.java:14:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.captureof: 1, ?, java.lang.String) > -T7086586.java:15:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.captureof: 1, ?, java.lang.Number) > -T7086586.java:16:31: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.captureof: 1, ?, java.lang.Exception) > -T7086586.java:17:13: compiler.err.cant.resolve.location.args: kindname.method, nonExistentMethod, , , (compiler.misc.location: kindname.interface, java.util.List, null) > +T7086586.java:14:20: compiler.err.cant.apply.symbol: kindname.method, m, java.util.List, java.util.List, kindname.class, T7086586, (compiler.misc.infer.no.conforming.assignment.exists: T, (compiler.misc.inconvertible.types: java.util.List, java.util.List)) > +T7086586.java:15:20: compiler.err.cant.apply.symbol: kindname.method, m, java.util.List, java.util.List, kindname.class, T7086586, (compiler.misc.infer.no.conforming.assignment.exists: T, (compiler.misc.inconvertible.types: java.util.List, java.util.List)) > +T7086586.java:16:23: compiler.err.cant.apply.symbol: kindname.method, m, java.util.List, java.util.List, kindname.class, T7086586, (compiler.misc.infer.no.conforming.assignment.exists: T, (compiler.misc.inconvertible.types: java.util.List, java.util.List)) > +T7086586.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, java.util.List, java.util.List, kindname.class, T7086586, (compiler.misc.infer.no.conforming.assignment.exists: T, (compiler.misc.inconvertible.types: java.util.List, java.util.List)) > 4 errors > diff -r e6d1e9f29132 test/tools/javac/generics/inference/7086586/T7086586b.java > --- a/test/tools/javac/generics/inference/7086586/T7086586b.java Tue Jun 10 15:25:01 2014 -0600 > +++ b/test/tools/javac/generics/inference/7086586/T7086586b.java Fri Jun 13 11:02:45 2014 -0600 > @@ -23,10 +23,9 @@ > > /* > * @test > - * @bug 7086586 8033718 > + * @bug 7086586 > * > - * @summary Inference producing null type argument; inference ignores capture > - * variable as upper bound > + * @summary Inference producing null type argument > */ > import java.util.List; > > @@ -41,8 +40,8 @@ > assertionCount++; > } > > - void m(List dummy) { assertTrue(true); } > - void m(Object dummy) { assertTrue(false); } > + void m(List dummy) { assertTrue(false); } > + void m(Object dummy) { assertTrue(true); } > > void test(List l) { > m(l); > diff -r e6d1e9f29132 test/tools/javac/generics/inference/NestedWildcards.java > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/test/tools/javac/generics/inference/NestedWildcards.java Fri Jun 13 11:02:45 2014 -0600 > @@ -0,0 +1,44 @@ > +/* > + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. > + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. > + * > + * This code is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License version 2 only, as > + * published by the Free Software Foundation. > + * > + * This code is distributed in the hope that it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > + * version 2 for more details (a copy is included in the LICENSE file that > + * accompanied this code). > + * > + * You should have received a copy of the GNU General Public License version > + * 2 along with this work; if not, write to the Free Software Foundation, > + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. > + * > + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA > + * or visit www.oracle.com if you need additional information or have any > + * questions. > + */ > + > +/* > + * @test > + * @bug 8046762 > + * @summary Nested generic methods that work on wildcard-parameterized types > + * @compile NestedWildcards.java > + */ > + > +public class NestedWildcards { > + > + public static void test(Box b) { > + foo(bar(b)); > + } > + private static Box foo(Box ts) { > + return null; > + } > + public static Box bar(Box language) { > + return null; > + } > + > + interface Box {} > +} > From oehrstroem at gmail.com Sat Jun 14 19:35:30 2014 From: oehrstroem at gmail.com (=?UTF-8?B?RnJlZHJpayDDlmhyc3Ryw7Zt?=) Date: Sat, 14 Jun 2014 21:35:30 +0200 Subject: RFR: 8044131: Restructure sjavac client / server protocol code In-Reply-To: <20140612110351.GK17197@e6430> References: <20140612110351.GK17197@e6430> Message-ID: Great cleanup! 2014-06-12 13:03 GMT+02:00 Andreas Lundblad : > Hi compiler-dev, > > Please review this patch which addresses part of JDK-8044131. > > - Description: > The protocol code needs to be cleaned up. Currently the protocol code is > entangled with the code that invokes javac (see CompilerThread.java). In > order to replace the protocol code with something better it has to be > factored out and separated from the compilation code. This is precisely > what this patch does. It also hides the compilation logic behind a new > interface (see JavacService.java) which will make the code more flexible. > We will for instance be able to easily choose between an in-VM and a > server/client implementation based on the background={true,fase} setting. > > Be aware that this patch is part 1 of 2. Further cleanups ahead. > CompilerThread and CompilerPool seems to dissapear for instance. > > - Link to webrev: > http://cr.openjdk.java.net/~alundblad/8044131 > > - Links to bug report: > https://bugs.openjdk.java.net/browse/JDK-8044131 > > -- Andreas > -------------- next part -------------- An HTML attachment was scrubbed... URL: From joe.darcy at oracle.com Tue Jun 17 05:46:17 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Mon, 16 Jun 2014 22:46:17 -0700 Subject: JDK 9 RFR of JDK-7196160: Project Coin: allow @SafeVarargs on private methods Message-ID: <539FD629.4070907@oracle.com> Hello, Please review my draft fix for JDK-7196160: Project Coin: allow @SafeVarargs on private methods http://cr.openjdk.java.net/~darcy/7196160.0/ (This is one of the possible refinements to Project Coin described in JEP JDK-8042880: Milling Project Coin: softening some rough edges.) The changes are pretty straightforward. If an @SafeVarargs annotation is applied inappropriately, a source-level dependent message is produced. This could be enhanced slightly to recognize @SafeVarargs on a private method output a "use -source 9 or higher for @SafeVarargs ..." message. All regression tests pass after this change. Thanks, -Joe From eric.mccorkle at oracle.com Tue Jun 17 15:59:22 2014 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Tue, 17 Jun 2014 11:59:22 -0400 Subject: Type Annotations Backport and 8u20 Message-ID: <53A065DA.7090100@oracle.com> After meeting last week and considering various options, the javac team has decided not to go ahead with backporting the recent type annotations work for the 8u20 update release. While there is clear and convincing evidence that the work recently contributed to jdk9 does improve the functioning of javac with regard to compiling source containing type annotations and generating the correct classfile attributes, we have determined that issues with the language model implementation run too great a risk of adversely affecting existing projects that use type annotations. Therefore, we have decided to delay the backport to the 8-update forest until the language model issues have been resolved. Despite this delay, the javac team remains committed to improving the quality of the type annotations feature, and will be continuing our work towards that end. -------------- next part -------------- A non-text attachment was scrubbed... Name: eric_mccorkle.vcf Type: text/x-vcard Size: 303 bytes Desc: not available URL: From daniel.smith at oracle.com Tue Jun 17 19:32:49 2014 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 17 Jun 2014 13:32:49 -0600 Subject: RFR: JDK-8042803 Types.wildLowerBound and cvarLowerBound should call unannotatedType() Message-ID: This is a small patch to properly handle AnnotatedTypes in 8u20 in some code of mine from a previous bug fix. No patch for 9, because AnnotatedTypes have been removed there. ?Dan diff -r b060e7c2f5cc src/share/classes/com/sun/tools/javac/code/Types.java --- a/src/share/classes/com/sun/tools/javac/code/Types.java Mon Jun 16 11:19:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Tue Jun 17 13:32:35 2014 -0600 @@ -135,7 +135,7 @@ else return wildUpperBound(w.type); } - else return t; + else return t.unannotatedType(); } /** @@ -147,7 +147,7 @@ TypeVar v = (TypeVar) t.unannotatedType(); return v.isCaptured() ? cvarUpperBound(v.bound) : v; } - else return t; + else return t.unannotatedType(); } /** @@ -156,10 +156,10 @@ */ public Type wildLowerBound(Type t) { if (t.hasTag(WILDCARD)) { - WildcardType w = (WildcardType) t; + WildcardType w = (WildcardType) t.unannotatedType(); return w.isExtendsBound() ? syms.botType : wildLowerBound(w.type); } - else return t; + else return t.unannotatedType(); } /** @@ -167,10 +167,11 @@ * @param t a type */ public Type cvarLowerBound(Type t) { - if (t.hasTag(TYPEVAR) && ((TypeVar) t).isCaptured()) { - return cvarLowerBound(t.getLowerBound()); + if (t.hasTag(TYPEVAR)) { + TypeVar v = (TypeVar) t.unannotatedType(); + return v.isCaptured() ? cvarLowerBound(v.getLowerBound()) : v; } - else return t; + else return t.unannotatedType(); } // From vicente.romero at oracle.com Tue Jun 17 19:40:46 2014 From: vicente.romero at oracle.com (Vicente-Arturo Romero-Zaldivar) Date: Tue, 17 Jun 2014 20:40:46 +0100 Subject: RFR: JDK-8042803 Types.wildLowerBound and cvarLowerBound should call unannotatedType() In-Reply-To: References: Message-ID: <53A099BE.4040609@oracle.com> On 17/06/14 20:32, Dan Smith wrote: > This is a small patch to properly handle AnnotatedTypes in 8u20 in some code of mine from a previous bug fix. No patch for 9, because AnnotatedTypes have been removed there. looks good, Vicente > > ?Dan > > diff -r b060e7c2f5cc src/share/classes/com/sun/tools/javac/code/Types.java > --- a/src/share/classes/com/sun/tools/javac/code/Types.java Mon Jun 16 11:19:22 2014 -0700 > +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Tue Jun 17 13:32:35 2014 -0600 > @@ -135,7 +135,7 @@ > else > return wildUpperBound(w.type); > } > - else return t; > + else return t.unannotatedType(); > } > > /** > @@ -147,7 +147,7 @@ > TypeVar v = (TypeVar) t.unannotatedType(); > return v.isCaptured() ? cvarUpperBound(v.bound) : v; > } > - else return t; > + else return t.unannotatedType(); > } > > /** > @@ -156,10 +156,10 @@ > */ > public Type wildLowerBound(Type t) { > if (t.hasTag(WILDCARD)) { > - WildcardType w = (WildcardType) t; > + WildcardType w = (WildcardType) t.unannotatedType(); > return w.isExtendsBound() ? syms.botType : wildLowerBound(w.type); > } > - else return t; > + else return t.unannotatedType(); > } > > /** > @@ -167,10 +167,11 @@ > * @param t a type > */ > public Type cvarLowerBound(Type t) { > - if (t.hasTag(TYPEVAR) && ((TypeVar) t).isCaptured()) { > - return cvarLowerBound(t.getLowerBound()); > + if (t.hasTag(TYPEVAR)) { > + TypeVar v = (TypeVar) t.unannotatedType(); > + return v.isCaptured() ? cvarLowerBound(v.getLowerBound()) : v; > } > - else return t; > + else return t.unannotatedType(); > } > // > From forax at univ-mlv.fr Thu Jun 19 12:53:09 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 19 Jun 2014 14:53:09 +0200 Subject: lambda reference to inner class in base class causes LambdaConversionException Message-ID: <53A2DD35.8020608@univ-mlv.fr> I've just take a look to bug 8047341 [1] and I think it's a javac bug and not a bug in the lambda meta-factory, moreover, Eclipse generates a code which doesn't throw an exception at runtime. In list.stream().forEach(TestString::new), TestString::new reference the constructor of TestString which is an inner class (non static) of FooBase, so the constructor takes a hidden FooBase parameter so the method reference should refer to TestString(FooBase, String). The code generated by javac is: 14: aload_0 15: invokedynamic #5, 0 // InvokeDynamic #0:accept:(LFoo;)Ljava/util/function/Consumer; 20: invokeinterface #6, 2 // InterfaceMethod java/util/stream/Stream.forEach:(Ljava/util/function/Consumer;)V while Eclipse ecj generates: 14: aload_0 15: invokedynamic #27, 0 // InvokeDynamic #0:accept:(LFooBase;)Ljava/util/function/Consumer; 20: invokeinterface #28, 2 // InterfaceMethod java/util/stream/Stream.forEach:(Ljava/util/function/Consumer;)V as you can see, javac generate an invokedynamic call with a Foo instead of a FooBase which I think is the correct behavior. So for me, it's a bug in javac, not in the meta-factory. cheers, R?mi [1] https://bugs.openjdk.java.net/browse/JDK-8047341 From maurizio.cimadamore at oracle.com Thu Jun 19 13:00:41 2014 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 19 Jun 2014 14:00:41 +0100 Subject: lambda reference to inner class in base class causes LambdaConversionException In-Reply-To: <53A2DD35.8020608@univ-mlv.fr> References: <53A2DD35.8020608@univ-mlv.fr> Message-ID: <53A2DEF9.8040804@oracle.com> On 19/06/14 13:53, Remi Forax wrote: > as you can see, javac generate an invokedynamic call with a Foo > instead of a FooBase which I think is the correct behavior. You mean the other way around? Maurizio From forax at univ-mlv.fr Thu Jun 19 13:05:36 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 19 Jun 2014 15:05:36 +0200 Subject: lambda reference to inner class in base class causes LambdaConversionException In-Reply-To: <53A2DEF9.8040804@oracle.com> References: <53A2DD35.8020608@univ-mlv.fr> <53A2DEF9.8040804@oracle.com> Message-ID: <53A2E020.8070802@univ-mlv.fr> On 06/19/2014 03:00 PM, Maurizio Cimadamore wrote: > > On 19/06/14 13:53, Remi Forax wrote: >> as you can see, javac generate an invokedynamic call with a Foo >> instead of a FooBase which I think is the correct behavior. > You mean the other way around? oops, s/the correct/not the correct > > Maurizio R?mi From joel.franck at oracle.com Thu Jun 19 14:43:30 2014 From: joel.franck at oracle.com (=?iso-8859-1?Q?Joel_Borggr=E9n-Franck?=) Date: Thu, 19 Jun 2014 16:43:30 +0200 Subject: RFR: 8044131: Restructure sjavac client / server protocol code In-Reply-To: <20140612110351.GK17197@e6430> References: <20140612110351.GK17197@e6430> Message-ID: <545F9689-D804-4249-B6D0-029B424AB85A@oracle.com> Looks good. cheers /Joel On 12 jun 2014, at 13:03, Andreas Lundblad wrote: > Hi compiler-dev, > > Please review this patch which addresses part of JDK-8044131. > > - Description: > The protocol code needs to be cleaned up. Currently the protocol code is entangled with the code that invokes javac (see CompilerThread.java). In order to replace the protocol code with something better it has to be factored out and separated from the compilation code. This is precisely what this patch does. It also hides the compilation logic behind a new interface (see JavacService.java) which will make the code more flexible. We will for instance be able to easily choose between an in-VM and a server/client implementation based on the background={true,fase} setting. > > Be aware that this patch is part 1 of 2. Further cleanups ahead. CompilerThread and CompilerPool seems to dissapear for instance. > > - Link to webrev: > http://cr.openjdk.java.net/~alundblad/8044131 > > - Links to bug report: > https://bugs.openjdk.java.net/browse/JDK-8044131 > > -- Andreas From robert.field at oracle.com Thu Jun 19 18:28:05 2014 From: robert.field at oracle.com (Robert Field) Date: Thu, 19 Jun 2014 11:28:05 -0700 Subject: lambda reference to inner class in base class causes LambdaConversionException In-Reply-To: <53A2DD35.8020608@univ-mlv.fr> References: <53A2DD35.8020608@univ-mlv.fr> Message-ID: <53A32BB5.8010906@oracle.com> Hi Remi, I have a fix in-process to fix this issue -- currently awaiting review. It will go into JDK9, since it is too extensive to go into an update release. I have confirmed that it fixes this issue too and will mark as a duplicate. Thanks, Robert On 06/19/14 05:53, Remi Forax wrote: > I've just take a look to bug 8047341 [1] and I think it's a javac bug > and not a bug in the lambda meta-factory, > moreover, Eclipse generates a code which doesn't throw an exception at > runtime. > > In list.stream().forEach(TestString::new), TestString::new reference > the constructor of TestString > which is an inner class (non static) of FooBase, so the constructor > takes a hidden FooBase parameter > so the method reference should refer to TestString(FooBase, String). > > The code generated by javac is: > 14: aload_0 > 15: invokedynamic #5, 0 // InvokeDynamic > #0:accept:(LFoo;)Ljava/util/function/Consumer; > 20: invokeinterface #6, 2 // InterfaceMethod > java/util/stream/Stream.forEach:(Ljava/util/function/Consumer;)V > > while Eclipse ecj generates: > 14: aload_0 > 15: invokedynamic #27, 0 // InvokeDynamic > #0:accept:(LFooBase;)Ljava/util/function/Consumer; > 20: invokeinterface #28, 2 // InterfaceMethod > java/util/stream/Stream.forEach:(Ljava/util/function/Consumer;)V > > as you can see, javac generate an invokedynamic call with a Foo > instead of a FooBase which I think is the correct behavior. > > So for me, it's a bug in javac, not in the meta-factory. > > cheers, > R?mi > > [1] https://bugs.openjdk.java.net/browse/JDK-8047341 > > From jonathan.gibbons at oracle.com Fri Jun 20 23:02:38 2014 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Fri, 20 Jun 2014 16:02:38 -0700 Subject: JDK 9 RFR of JDK-7196160: Project Coin: allow @SafeVarargs on private methods In-Reply-To: <539FD629.4070907@oracle.com> References: <539FD629.4070907@oracle.com> Message-ID: <53A4BD8E.8040407@oracle.com> Looks good to me. -- Jon On 06/16/2014 10:46 PM, Joe Darcy wrote: > Hello, > > Please review my draft fix for > > JDK-7196160: Project Coin: allow @SafeVarargs on private methods > http://cr.openjdk.java.net/~darcy/7196160.0/ > > (This is one of the possible refinements to Project Coin described in > JEP JDK-8042880: Milling Project Coin: softening some rough edges.) > > The changes are pretty straightforward. If an @SafeVarargs annotation > is applied inappropriately, a source-level dependent message is > produced. This could be enhanced slightly to recognize @SafeVarargs on > a private method output a "use -source 9 or higher for @SafeVarargs > ..." message. > > All regression tests pass after this change. > > Thanks, > > -Joe From nkweteyimdaisy at gmail.com Sun Jun 22 04:53:26 2014 From: nkweteyimdaisy at gmail.com (Daisy Nkweteyim) Date: Sun, 22 Jun 2014 05:53:26 +0100 Subject: Generate Bytecode from an AST Message-ID: Heelo everyone, I saw a blog post on Generating Byte Code by Building AST's which describes how bytecode can be generated from an AST. It involves changing the javac source code to bypass the parsing phase and generate bytecode which is produced when one passes his/her own AST. But I would ike to do this in a better way. Is it possible to actually generate a .class file from an AST using javac without changing the javac source code and without using a framework? Thanks for your time. Any help is greatly appreciated. Regards, -- *Daisy Nkweteyim Cameroon* -------------- next part -------------- An HTML attachment was scrubbed... URL: From martinrb at google.com Mon Jun 23 19:55:32 2014 From: martinrb at google.com (Martin Buchholz) Date: Mon, 23 Jun 2014 12:55:32 -0700 Subject: JSR-308 and @SuppressWarnings Message-ID: For years, those of us maintaining low-level libraries have been writing code like this: @SuppressWarnings("unchecked") E itemE = (E) item; return itemE; hoping that JSR-308 might someday allow us to write something like: return (@SuppressWarnings("unchecked") E) item; which is clearer, more compact, and generates slightly better bytecode. This article: http://www.oracle.com/technetwork/articles/java/ma14-architect-annotations-2177655.html suggests that @SuppressWarnings should work "out of the box", but I don't see that with jdk8 javac. Are my hopes dashed? -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Mon Jun 23 20:35:24 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 23 Jun 2014 22:35:24 +0200 Subject: JSR-308 and @SuppressWarnings In-Reply-To: References: Message-ID: <53A88F8C.6070706@univ-mlv.fr> On 06/23/2014 09:55 PM, Martin Buchholz wrote: > For years, those of us maintaining low-level libraries have been > writing code like this: > > @SuppressWarnings("unchecked") E itemE = (E) item; > return itemE; > > hoping that JSR-308 might someday allow us to write something like: > return (@SuppressWarnings("unchecked") E) item; > > which is clearer, more compact, and generates slightly better bytecode. > This article: > http://www.oracle.com/technetwork/articles/java/ma14-architect-annotations-2177655.html > suggests that @SuppressWarnings should work "out of the box", but I > don't see that with jdk8 javac. > > Are my hopes dashed? that's a great idea ! R?mi From alex.buckley at oracle.com Mon Jun 23 21:01:08 2014 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 23 Jun 2014 14:01:08 -0700 Subject: JSR-308 and @SuppressWarnings In-Reply-To: References: Message-ID: <53A89594.2070208@oracle.com> @SuppressWarnings was not changed in Java SE 8. It continues to apply to declarations, not types. A JEP would be needed to make @SuppressWarnings suitable for types inside cast expressions. Reviewing where @SuppressWarnings appears in the JLS, another opportunity is to give it meaning when applied to the declaration of a variable arity parameter of non-reifiable type. Currently, you have the choice of applying @SafeVarargs to the method declaration (for certain kinds of method) or applying @SuppressWarnings("unchecked") to the method declaration (works for all kinds of method, but is a blunt tool). Alex On 6/23/2014 12:55 PM, Martin Buchholz wrote: > For years, those of us maintaining low-level libraries have been writing > code like this: > > @SuppressWarnings("unchecked") E itemE = (E) item; > return itemE; > > hoping that JSR-308 might someday allow us to write something like: > return (@SuppressWarnings("unchecked") E) item; > > which is clearer, more compact, and generates slightly better bytecode. > This article: > http://www.oracle.com/technetwork/articles/java/ma14-architect-annotations-2177655.html > suggests that @SuppressWarnings should work "out of the box", but I > don't see that with jdk8 javac. > > Are my hopes dashed? From jonathan.gibbons at oracle.com Tue Jun 24 17:56:39 2014 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Tue, 24 Jun 2014 10:56:39 -0700 Subject: Generate Bytecode from an AST In-Reply-To: References: Message-ID: <53A9BBD7.1050908@oracle.com> On 06/21/2014 09:53 PM, Daisy Nkweteyim wrote: > Heelo everyone, > > I saw a blog post on Generating Byte Code by Building AST's > which > describes how bytecode can be generated from an AST. It involves > changing the javac source code to bypass the parsing phase and > generate bytecode which is produced when one passes his/her own AST. > But I would ike to do this in a better way. > > Is it possible to actually generate a .class file from an AST using > javac without changing the javac source code and without using a > framework? > > Thanks for your time. Any help is greatly appreciated. > > Regards, > > -- > /Daisy Nkweteyim > Cameroon/ > Right now, the recommended solution is to print the AST to a string and to compile the string. This can all be done in memory -- there is no need to write the text to the filesystem as an interim step. Currently, there is no way to compile an arbitrary tree created by the user using arbitrary implementions of com.sun.source.tree.*. -- Jon -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Sat Jun 28 00:02:07 2014 From: brian.goetz at oracle.com (Brian Goetz) Date: Fri, 27 Jun 2014 20:02:07 -0400 Subject: RFR: JDK-8032188 (remove dead code in TransTypes) Message-ID: <53AE05FF.3040905@oracle.com> This is a jdk9 patch to remove some dead code in TransTypes. About 10% of this file had to do with support for an older bridging strategy ("override bridges"), which we no longer use and have no plans to use in the future. This patch removes that code. -------------- next part -------------- # HG changeset patch # Parent 220bfc92607e48057048e5fe24d3250be43ceac9 diff --git a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java old mode 100644 new mode 100755 --- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java +++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java @@ -866,90 +866,6 @@ return types.erasure(t); } - private boolean boundsRestricted(ClassSymbol c) { - Type st = types.supertype(c.type); - if (st.isParameterized()) { - List actuals = st.allparams(); - List formals = st.tsym.type.allparams(); - while (!actuals.isEmpty() && !formals.isEmpty()) { - Type actual = actuals.head; - Type formal = formals.head; - - if (!types.isSameType(types.erasure(actual), - types.erasure(formal))) - return true; - - actuals = actuals.tail; - formals = formals.tail; - } - } - return false; - } - - private List addOverrideBridgesIfNeeded(DiagnosticPosition pos, - final ClassSymbol c) { - ListBuffer buf = new ListBuffer<>(); - if (c.isInterface() || !boundsRestricted(c)) - return buf.toList(); - Type t = types.supertype(c.type); - Scope s = t.tsym.members(); - if (s.elems != null) { - for (Symbol sym : s.getElements(new NeedsOverridBridgeFilter(c))) { - - MethodSymbol m = (MethodSymbol)sym; - MethodSymbol member = (MethodSymbol)m.asMemberOf(c.type, types); - MethodSymbol impl = m.implementation(c, types, false); - - if ((impl == null || impl.owner != c) && - !types.isSameType(member.erasure(types), m.erasure(types))) { - addOverrideBridges(pos, m, member, c, buf); - } - } - } - return buf.toList(); - } - // where - class NeedsOverridBridgeFilter implements Filter { - - ClassSymbol c; - - NeedsOverridBridgeFilter(ClassSymbol c) { - this.c = c; - } - public boolean accepts(Symbol s) { - return s.kind == MTH && - !s.isConstructor() && - s.isInheritedIn(c, types) && - (s.flags() & FINAL) == 0 && - (s.flags() & (SYNTHETIC | OVERRIDE_BRIDGE)) != SYNTHETIC; - } - } - - private void addOverrideBridges(DiagnosticPosition pos, - MethodSymbol impl, - MethodSymbol member, - ClassSymbol c, - ListBuffer bridges) { - Type implErasure = impl.erasure(types); - long flags = (impl.flags() & AccessFlags) | SYNTHETIC | BRIDGE | OVERRIDE_BRIDGE; - member = new MethodSymbol(flags, member.name, member.type, c); - JCMethodDecl md = make.MethodDef(member, null); - JCExpression receiver = make.Super(types.supertype(c.type).tsym.erasure(types), c); - Type calltype = erasure(impl.type.getReturnType()); - JCExpression call = - make.Apply(null, - make.Select(receiver, impl).setType(calltype), - translateArgs(make.Idents(md.params), - implErasure.getParameterTypes(), null)) - .setType(calltype); - JCStatement stat = (member.getReturnType().hasTag(VOID)) - ? make.Exec(call) - : make.Return(coerce(call, member.erasure(types).getReturnType())); - md.body = make.Block(0, List.of(stat)); - c.members().enter(member); - bridges.append(md); - } - /************************************************************************** * main method *************************************************************************/ @@ -1006,8 +922,8 @@ make.at(tree.pos); if (addBridges) { ListBuffer bridges = new ListBuffer<>(); - if (false) //see CR: 6996415 - bridges.appendList(addOverrideBridgesIfNeeded(tree, c)); + // At some point, there was override bridging here to handle + // infinite bridge loops (JDK-6996415); no longer needed if (allowInterfaceBridges || (tree.sym.flags() & INTERFACE) == 0) { addBridges(tree.pos(), c, bridges); } From jonathan.gibbons at oracle.com Sat Jun 28 00:08:19 2014 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Fri, 27 Jun 2014 17:08:19 -0700 Subject: RFR: JDK-8032188 (remove dead code in TransTypes) In-Reply-To: <53AE05FF.3040905@oracle.com> References: <53AE05FF.3040905@oracle.com> Message-ID: <53AE0773.9020809@oracle.com> Brian, Posting a webrev on cr.openjdk.java.net is preferable to expecting folk to cope directly with a patch. -- Jon On 06/27/2014 05:02 PM, Brian Goetz wrote: > This is a jdk9 patch to remove some dead code in TransTypes. About > 10% of this file had to do with support for an older bridging strategy > ("override bridges"), which we no longer use and have no plans to use > in the future. This patch removes that code. > From joe.darcy at oracle.com Mon Jun 30 23:38:55 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Mon, 30 Jun 2014 16:38:55 -0700 Subject: RFR: JDK-8032188 (remove dead code in TransTypes) In-Reply-To: <53AE05FF.3040905@oracle.com> References: <53AE05FF.3040905@oracle.com> Message-ID: <53B1F50F.1010408@oracle.com> On 06/27/2014 05:02 PM, Brian Goetz wrote: > This is a jdk9 patch to remove some dead code in TransTypes. About > 10% of this file had to do with support for an older bridging strategy > ("override bridges"), which we no longer use and have no plans to use > in the future. This patch removes that code. > Hi Brian, Nuking the dead method looks fine. However, for the comments - if (false) //see CR: 6996415 - bridges.appendList(addOverrideBridgesIfNeeded(tree, c)); + // At some point, there was override bridging here to handle + // infinite bridge loops (JDK-6996415); no longer needed if (allowInterfaceBridges || (tree.sym.flags() & INTERFACE) == 0) { I recommend just removing the if(false) code and *not* adding in the comments above. That sort of history can be determined from the change logs if it is needed. Cheers, -Joe