From jonathan.gibbons at oracle.com Fri May 1 00:21:55 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Thu, 30 Apr 2015 17:21:55 -0700 Subject: RFR: 8079191 remove remaining references to "cp -p" from langtools/test Message-ID: <5542C723.6030906@oracle.com> Two remaining uses of "cp -p" in the few remaining langtools shell tests. In both cases, the files being copied are not being used in situations where it is important to preserve file attributes, and so it is safe to remove -p without affecting the test. In particular, typically the most important reason to use "cp -p" in a javac shell test is to preserve file modification times, when testing the choice between source and class files, and that is not the case here. Bug: https://bugs.openjdk.java.net/browse/JDK-8079191 Review: http://cr.openjdk.java.net/~jjg/8079191/webrev.00/index.html -- Jon From vicente.romero at oracle.com Fri May 1 00:26:38 2015 From: vicente.romero at oracle.com (Vicente-Arturo Romero-Zaldivar) Date: Thu, 30 Apr 2015 17:26:38 -0700 Subject: RFR: 8079191 remove remaining references to "cp -p" from langtools/test In-Reply-To: <5542C723.6030906@oracle.com> References: <5542C723.6030906@oracle.com> Message-ID: <5542C83E.2000601@oracle.com> accepted, Vicente On 04/30/2015 05:21 PM, Jonathan Gibbons wrote: > Two remaining uses of "cp -p" in the few remaining langtools shell tests. > > In both cases, the files being copied are not being used in situations > where it is important to preserve file attributes, and so it is safe > to remove -p without affecting the test. In particular, typically the > most important reason to use "cp -p" in a javac shell test is to > preserve file modification times, when testing the choice between > source and class files, and that is not the case here. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8079191 > Review: http://cr.openjdk.java.net/~jjg/8079191/webrev.00/index.html > > -- Jon From forax at univ-mlv.fr Sat May 2 14:02:58 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 02 May 2015 16:02:58 +0200 Subject: JEP 247: Compile for Older Platform Versions In-Reply-To: <20150423223046.D40E557B97@eggemoggin.niobe.net> References: <20150423223046.D40E557B97@eggemoggin.niobe.net> Message-ID: <5544D912.2040805@univ-mlv.fr> On 04/24/2015 12:30 AM, mark.reinhold at oracle.com wrote: > New JEP Candidate: http://openjdk.java.net/jeps/247 > > - Mark Hi all, while i think the goal of this JEP is fine, i don't like the fact that the solution is based on ct.sym. We already have a format which is able to describe the public API of a class, it's the class file format, this format is already specified, well understood by existing tools, which is compact (pack200 ?), the only missing information is the version that add and/or remove a member (since and deleted since) that can be added as class file attribute. regards, R?mi From jan.lahoda at oracle.com Mon May 4 10:39:57 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Mon, 04 May 2015 12:39:57 +0200 Subject: JEP 247: Compile for Older Platform Versions In-Reply-To: <5544D912.2040805@univ-mlv.fr> References: <20150423223046.D40E557B97@eggemoggin.niobe.net> <5544D912.2040805@univ-mlv.fr> Message-ID: <55474C7D.6060307@oracle.com> Hi Remi, Thanks for the comment. On 2.5.2015 16:02, Remi Forax wrote: > > On 04/24/2015 12:30 AM, mark.reinhold at oracle.com wrote: >> New JEP Candidate: http://openjdk.java.net/jeps/247 >> >> - Mark > > Hi all, > while i think the goal of this JEP is fine, > i don't like the fact that the solution is based on ct.sym. In JDK 8, the ct.sym was a jar file containing almost classfiles (almost, because the classfiles did not have the Code attribute for methods that require it). In the -platform prototype(*), the ct.sym is also a jar file (albeit the internal structure is different), and it also contains almost classfiles similar to the JDK 8's ct.sym. To avoid confusion, the files use .sig extension rather than the .class extension. > > We already have a format which is able to describe the public API of a > class, it's the class file format, this format is already specified, > well understood by existing tools, which is compact (pack200 ?), the > only missing information is the version that add and/or remove a member > (since and deleted since) that can be added as class file attribute. Older versions of the prototype used an annotation to specify JDK versions for which given element (field or method) was valid. Eventually, this got replaced by a system, where, if a sigfile is the same for versions M and N, the same sigfile is used for both, and when they differ, there are two sigfiles. This is a simpler system, and the resulting ct.sym is not much bigger. Currently, the content of the ct.sym is very simple, and looks like this (for ct.sym containing data for 7 and 8): 7/ //sigfiles for 7 78/ //sigfiles shared for 7 and 8 8/ //sigfiles for 8 Each for these directories contains sigfiles in their package structure. To get the bootclasspath for version N, all directories that contain "N" are used. (*) The current -platform prototype is in branch "JDK-8058150-branch" in the jdk9/sandbox forest. What do you think? Thanks, Jan > > regards, > R?mi > From joe.darcy at oracle.com Mon May 4 16:55:17 2015 From: joe.darcy at oracle.com (joe darcy) Date: Mon, 04 May 2015 09:55:17 -0700 Subject: JEP 247: Compile for Older Platform Versions In-Reply-To: <55474C7D.6060307@oracle.com> References: <20150423223046.D40E557B97@eggemoggin.niobe.net> <5544D912.2040805@univ-mlv.fr> <55474C7D.6060307@oracle.com> Message-ID: <5547A475.2080009@oracle.com> Hello, On 5/4/2015 3:39 AM, Jan Lahoda wrote: > Hi Remi, > > Thanks for the comment. > > On 2.5.2015 16:02, Remi Forax wrote: >> >> On 04/24/2015 12:30 AM, mark.reinhold at oracle.com wrote: >>> New JEP Candidate: http://openjdk.java.net/jeps/247 >>> >>> - Mark >> >> Hi all, >> while i think the goal of this JEP is fine, >> i don't like the fact that the solution is based on ct.sym. > > In JDK 8, the ct.sym was a jar file containing almost classfiles > (almost, because the classfiles did not have the Code attribute for > methods that require it). > > In the -platform prototype(*), the ct.sym is also a jar file (albeit > the internal structure is different), and it also contains almost > classfiles similar to the JDK 8's ct.sym. To avoid confusion, the > files use .sig extension rather than the .class extension. > >> >> We already have a format which is able to describe the public API of a >> class, it's the class file format, this format is already specified, >> well understood by existing tools, which is compact (pack200 ?), the >> only missing information is the version that add and/or remove a member >> (since and deleted since) that can be added as class file attribute. > > Older versions of the prototype used an annotation to specify JDK > versions for which given element (field or method) was valid. > Eventually, this got replaced by a system, where, if a sigfile is the > same for versions M and N, the same sigfile is used for both, and when > they differ, there are two sigfiles. This is a simpler system, and the > resulting ct.sym is not much bigger. The simplest way to implement -platform would be to shove ct.sym/rt.jar files for each supported release into the JDK. For space reasons, both in the installed image and in our source code repository, that was not the chosen approach. Note that a simple annotation-based system cannot easily represent all the possible version-specific information about a type. Consider: * In JDK 9, a class introduced in JDK 7 is retrofitted to implement an interface from JDK 8. (This sort of transformation has happened.) * Annotations which impact compilation, like @Deprecreated, are added or removed. It is a non-goal of this effort to create yet-another big interface for Java programmers to rely on beyond the API which is being supported. -Joe From georgiy.rakov at oracle.com Wed May 6 14:06:23 2015 From: georgiy.rakov at oracle.com (Georgiy Rakov) Date: Wed, 06 May 2015 17:06:23 +0300 Subject: "Chained" qualified instance creation expressions (diamond in qualifiers) Message-ID: <554A1FDF.60509@oracle.com> Hello, let's consider following example: classD {} classOuter2 { classOuter1 { classFoo { } } } public classTest69 { public static voidtest(String argv[]) { Outer2.Outer1.Foo f20 =newOuter2<>().newOuter1<>().newFoo<>() { privateOuter2.Outer1.Foo simpleMethod1() {return this; }//compiles Ok //private Outer2.Outer1.Foo simpleMethod2() { return this; } //causes compilation error }; } } JDK9b60 causes Q and W to be inferred as Object. This can be seen: - from the fact that code above compiles successfully; - from the fact that uncommenting the method above causes compilation failure. So what we actually have is: - Q is inferred as Object; - W is inferred as Object; - T is inferred as D. However according to intuition it seems that Q and W should have been inferred as D as it happens to T. I believe this corresponds to spec, the reasons presented below seem to cause this: 1. Following assertion from JLS 18.5.2 is not applied when JLS 15.9.3 is applied to new Outer2<>() and new Outer1<>(): Otherwise, the constraint formula ?R??T? is reduced and incorporated with B_2 . So for outer classes inference proceeds with no constraint formula actually causing inference variable in question to be inferred as D. 2. JLS 15.9.3 doesn't use type parameters from outer classes when processing new Foo<>(). Namely following assertion from JLS 15.9.3 doesn't mention type parameters from possible outer classes: Let F_1 ...F_p be the type parameters of C, and let G_1 ...G_q be the type parameters (if any) of |c_j |. So constraint formula created by JLS 18.5.2 assertion presented above engages just inference variable from Foo, i. e. T. However I believe more broad change of spec will be required to implement this "intuition" than just modifying spec according to two points above. So: 1. Could you please tell if I understand correctly that the fact that Q is inferred as Object, W is inferred as Object really corresponds to spec and it's not a JDK issue. 2. As for me it looks reasonable to enhance specification so that Q and W would be inferred as D too. Could you please tell if you agree. If you do would it be worth creating spec enhancement in Jira? Thanks, Georgiy. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- class D {} class Outer2 { class Outer1 { class Foo { } } } public class Test69 { public static void test(String argv[]) { Outer2.Outer1.Foo f20 = new Outer2<>().new Outer1<>().new Foo<>() { private Outer2.Outer1.Foo simpleMethod1() { return this; } //compiles Ok //private Outer2.Outer1.Foo simpleMethod2() { return this; } //causes compilation error }; } } From konstantin.barzilovich at oracle.com Wed May 6 15:27:33 2015 From: konstantin.barzilovich at oracle.com (konstantin barzilovich) Date: Wed, 06 May 2015 18:27:33 +0300 Subject: jls overridding description Message-ID: <554A32E5.9080304@oracle.com> Hello, In Chapter 8 of jls there is assertion jls-8.4.8.1-100 "An instance method mc, declared in or inherited by class C, overrides from C another method ma, declared in class A, iff all of the following are true: " which describe conditions of overriding of classes methods. As I understand, one of jls-8.4.8.1-100-B "C doesn't inherit ma" and jls-8.4.8.1-100-C "The signature of mc is a subsignature of the signature of ma" is redundant because if we omit, for example, jls-8.4.8.1-100-C, no cases will be missed. The same situation takes place in jls-9.4.1.1-100 afterJDK-8071453 Allow interface methods to be private is solved. Am I missing anything? Thanks, Konstantin. -------------- next part -------------- An HTML attachment was scrubbed... URL: From srikanth.adayapalam at oracle.com Thu May 7 12:40:53 2015 From: srikanth.adayapalam at oracle.com (Srikanth) Date: Thu, 07 May 2015 18:10:53 +0530 Subject: "Chained" qualified instance creation expressions (diamond in qualifiers) In-Reply-To: <554A1FDF.60509@oracle.com> References: <554A1FDF.60509@oracle.com> Message-ID: <554B5D55.7020404@oracle.com> I'll wait for Dan to chime in with chapter and verse, but I believe the specification does not mandate/require/sanction/allow a qualified instance creation expression to propagate the target type or any part thereof to any enclosing instance creation expression (qualified or otherwise). Srikanth On Wednesday 06 May 2015 07:36 PM, Georgiy Rakov wrote: > Hello, > > let's consider following example: > > classD {} > > classOuter2 { > classOuter1 { > classFoo { } > } > } > > public classTest69 { > > public static voidtest(String argv[]) { > Outer2.Outer1.Foo f20 =newOuter2<>().newOuter1<>().newFoo<>() { > privateOuter2.Outer1.Foo simpleMethod1() {return this; }//compiles Ok > //private Outer2.Outer1.Foo simpleMethod2() { return this; } //causes compilation error > }; > } > } > > > JDK9b60 causes Q and W to be inferred as Object. This can be seen: > - from the fact that code above compiles successfully; > - from the fact that uncommenting the method above causes compilation > failure. > > So what we actually have is: > - Q is inferred as Object; > - W is inferred as Object; > - T is inferred as D. > > However according to intuition it seems that Q and W should have been > inferred as D as it happens to T. > > I believe this corresponds to spec, the reasons presented below seem > to cause this: > > 1. Following assertion from JLS 18.5.2 is not applied when JLS 15.9.3 > is applied to new Outer2<>() and new Outer1<>(): > > Otherwise, the constraint formula ?R??T? is reduced and > incorporated with B_2 . > > So for outer classes inference proceeds with no constraint formula > actually causing inference variable in question to be inferred as D. > > 2. JLS 15.9.3 doesn't use type parameters from outer classes when > processing new Foo<>(). Namely following assertion from JLS 15.9.3 > doesn't mention type parameters from possible outer classes: > > Let F_1 ...F_p be the type parameters of C, and let G_1 ...G_q be > the type parameters (if any) of |c_j |. > > So constraint formula created by JLS 18.5.2 assertion presented above > engages just inference variable from Foo, i. e. T. > > However I believe more broad change of spec will be required to > implement this "intuition" than just modifying spec according to two > points above. > > So: > 1. Could you please tell if I understand correctly that the fact that > Q is inferred as Object, W is inferred as Object really corresponds to > spec and it's not a JDK issue. > 2. As for me it looks reasonable to enhance specification so that Q > and W would be inferred as D too. Could you please tell if you agree. > If you do would it be worth creating spec enhancement in Jira? > > Thanks, > Georgiy. -------------- next part -------------- An HTML attachment was scrubbed... URL: From srikanth.adayapalam at oracle.com Thu May 7 12:51:04 2015 From: srikanth.adayapalam at oracle.com (Srikanth) Date: Thu, 07 May 2015 18:21:04 +0530 Subject: "Chained" qualified instance creation expressions (diamond in qualifiers) In-Reply-To: <554B5D55.7020404@oracle.com> References: <554A1FDF.60509@oracle.com> <554B5D55.7020404@oracle.com> Message-ID: <554B5FB8.2040006@oracle.com> On Thursday 07 May 2015 06:10 PM, Srikanth wrote: > I'll wait for Dan to chime in with chapter and verse, but I believe > the specification does not > mandate/require/sanction/allow a qualified instance creation > expression to propagate > the target type or any part thereof to any enclosing instance creation > expression (qualified > or otherwise). Sorry, upon rereading your mail, I see that this is something you are acknowledging and your question is broader. I'll study this in more detail tomorrow. Srikanth > > Srikanth > > > On Wednesday 06 May 2015 07:36 PM, Georgiy Rakov wrote: >> Hello, >> >> let's consider following example: >> >> classD {} >> >> classOuter2 { >> classOuter1 { >> classFoo { } >> } >> } >> >> public classTest69 { >> >> public static voidtest(String argv[]) { >> Outer2.Outer1.Foo f20 =newOuter2<>().newOuter1<>().newFoo<>() { >> privateOuter2.Outer1.Foo simpleMethod1() {return this; }//compiles Ok >> //private Outer2.Outer1.Foo simpleMethod2() { return this; } //causes compilation error >> }; >> } >> } >> >> >> JDK9b60 causes Q and W to be inferred as Object. This can be seen: >> - from the fact that code above compiles successfully; >> - from the fact that uncommenting the method above causes compilation >> failure. >> >> So what we actually have is: >> - Q is inferred as Object; >> - W is inferred as Object; >> - T is inferred as D. >> >> However according to intuition it seems that Q and W should have been >> inferred as D as it happens to T. >> >> I believe this corresponds to spec, the reasons presented below seem >> to cause this: >> >> 1. Following assertion from JLS 18.5.2 is not applied when JLS 15.9.3 >> is applied to new Outer2<>() and new Outer1<>(): >> >> Otherwise, the constraint formula ?R??T? is reduced and >> incorporated with B_2 . >> >> So for outer classes inference proceeds with no constraint formula >> actually causing inference variable in question to be inferred as D. >> >> 2. JLS 15.9.3 doesn't use type parameters from outer classes when >> processing new Foo<>(). Namely following assertion from JLS 15.9.3 >> doesn't mention type parameters from possible outer classes: >> >> Let F_1 ...F_p be the type parameters of C, and let G_1 ...G_q be >> the type parameters (if any) of |c_j |. >> >> So constraint formula created by JLS 18.5.2 assertion presented above >> engages just inference variable from Foo, i. e. T. >> >> However I believe more broad change of spec will be required to >> implement this "intuition" than just modifying spec according to two >> points above. >> >> So: >> 1. Could you please tell if I understand correctly that the fact that >> Q is inferred as Object, W is inferred as Object really corresponds >> to spec and it's not a JDK issue. >> 2. As for me it looks reasonable to enhance specification so that Q >> and W would be inferred as D too. Could you please tell if you agree. >> If you do would it be worth creating spec enhancement in Jira? >> >> Thanks, >> Georgiy. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From srikanth.adayapalam at oracle.com Fri May 8 10:52:17 2015 From: srikanth.adayapalam at oracle.com (Srikanth) Date: Fri, 08 May 2015 16:22:17 +0530 Subject: "Chained" qualified instance creation expressions (diamond in qualifiers) In-Reply-To: <554A1FDF.60509@oracle.com> References: <554A1FDF.60509@oracle.com> Message-ID: <554C9561.4020908@oracle.com> On Wednesday 06 May 2015 07:36 PM, Georgiy Rakov wrote: > Hello, > > let's consider following example: > > classD {} > > classOuter2 { > classOuter1 { > classFoo { } > } > } > > public classTest69 { > > public static voidtest(String argv[]) { > Outer2.Outer1.Foo f20 =newOuter2<>().newOuter1<>().newFoo<>() { > privateOuter2.Outer1.Foo simpleMethod1() {return this; }//compiles Ok > //private Outer2.Outer1.Foo simpleMethod2() { return this; } //causes compilation error > }; > } > } > > > JDK9b60 causes Q and W to be inferred as Object. This can be seen: > - from the fact that code above compiles successfully; > - from the fact that uncommenting the method above causes compilation > failure. > > So what we actually have is: > - Q is inferred as Object; > - W is inferred as Object; > - T is inferred as D. > > However according to intuition it seems that Q and W should have been > inferred as D as it happens to T. > > I believe this corresponds to spec, the reasons presented below seem > to cause this: > > 1. Following assertion from JLS 18.5.2 is not applied when JLS 15.9.3 > is applied to new Outer2<>() and new Outer1<>(): > > Otherwise, the constraint formula ?R??T? is reduced and > incorporated with B_2 . > > So for outer classes inference proceeds with no constraint formula > actually causing inference variable in question to be inferred as D. > > 2. JLS 15.9.3 doesn't use type parameters from outer classes when > processing new Foo<>(). Namely following assertion from JLS 15.9.3 > doesn't mention type parameters from possible outer classes: > > Let F_1 ...F_p be the type parameters of C, and let G_1 ...G_q be > the type parameters (if any) of |c_j |. > > So constraint formula created by JLS 18.5.2 assertion presented above > engages just inference variable from Foo, i. e. T. > > However I believe more broad change of spec will be required to > implement this "intuition" than just modifying spec according to two > points above. > > So: > 1. Could you please tell if I understand correctly that the fact that > Q is inferred as Object, W is inferred as Object really corresponds to > spec and it's not a JDK issue. Hi Georgiy, My original response is good enough for this part - The target type from the LHS i.e Outer2.Outer1.Foo gets imposed on newFoo<>() { ... } and the specification does not mandate/require/sanction/allow a qualified instance creation expression to propagate the target type or any part thereof to any enclosing instance creation expression (qualified or otherwise). So Q and W being inferred as Object is the right behaviour per the current specification. > 2. As for me it looks reasonable to enhance specification so that Q > and W would be inferred as D too. Could you please tell if you agree. > If you do would it be worth creating spec enhancement in Jira? This part which have you described as being "intuitive", I'll request Dan Smith to answer the reasons for the state of the art - I don't readily know what canons of type system theory would require it to be the way it is - i.e why would we not allow the qualified allocation expression to propagate suitable target types to the enclosing expressions - and whether this is something amenable to tinkering. Thanks! Srikanth -------------- next part -------------- An HTML attachment was scrubbed... URL: From boxzou at gmail.com Sat May 9 22:36:00 2015 From: boxzou at gmail.com (Bo Zou) Date: Sat, 9 May 2015 18:36:00 -0400 Subject: KSL: expand catch to catch code Message-ID: This is a proposal to expand the catch keyword to catch code as follows: } catch (*CodedException ex, "code1"*) { // only code1 is caught } catch (*CodedException ex, "code2", "code3"*) { // both code2 and code3 are caught } catch (*CodedException* | IOException ex*, "code4", "code5"*) { // catches code4, code5 and IOException } catch (CodedException ex) { // all codes are caught Details: http://tri-katch.blogspot.com/2015/05/catch-code-proposal-to-expand-catch-in.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsrbnd at gmail.com Mon May 11 13:52:46 2015 From: bsrbnd at gmail.com (bsrbnd) Date: Mon, 11 May 2015 15:52:46 +0200 Subject: [PATCH] 8071433: private static method in outer class shadowed by inherited public method Message-ID: Hi, As described in case 8071433, the following code doesn't compile because public method shadow() inherited from StaticFail hides private static method shadow(boolean) defined in the same class (but not inherited). public class StaticFail { private static void shadow(boolean b) {System.out.println(b);} public void shadow() {} public static class FailImpl extends StaticFail { public void a() { shadow(false); } } public static void main(String[] args) { new FailImpl().a(); } } It should be possible to correct the problem by keeping on searching in outer class if method shadow() is found in class FailImpl but inapplicable. The following patch for the jdk9 shows a possible solution: diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -1822,7 +1822,8 @@ Symbol sym = findMethod( env1, env1.enclClass.sym.type, name, argtypes, typeargtypes, allowBoxing, useVarargs); - if (sym.exists()) { + // Keep on searching in outer environment if symbol is found but inapplicable. + if (sym.exists() && !(sym instanceof Resolve.InapplicableSymbolError)) { if (staticOnly && sym.kind == MTH && sym.owner.kind == TYP && I hope this could help. Regards, bsrbnd From maurizio.cimadamore at oracle.com Mon May 11 14:47:39 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 11 May 2015 15:47:39 +0100 Subject: [PATCH] 8071433: private static method in outer class shadowed by inherited public method In-Reply-To: References: Message-ID: <5550C10B.3010403@oracle.com> Is this even an issue? See JLS 15.12.1: "If the form is MethodName, that is, just an Identifier, then: If the Identifier appears in the scope of a visible method declaration with that name (?6.3, ?6.4.1), then: *If there is an enclosing type declaration of which that method is a member, let T be the innermost such type declaration. The class or interface to search is T*. This search policy is called the "comb rule". It effectively looks for methods in a nested class's superclass hierarchy before looking for methods in an enclosing class and its superclass hierarchy. See ?6.5.7.1 for an example." Here we have that FailImpl has an inherited member 'shadow()' - which means FailImpl is the class to search. This will give you the type error. Maurizio On 11/05/15 14:52, bsrbnd wrote: > Hi, > > As described in case 8071433, the following code doesn't compile > because public method shadow() inherited from StaticFail hides private > static method shadow(boolean) defined in the same class (but not > inherited). > > public class StaticFail { > private static void shadow(boolean b) {System.out.println(b);} > public void shadow() {} > > public static class FailImpl extends StaticFail { > public void a() { > shadow(false); > } > } > > public static void main(String[] args) { > new FailImpl().a(); > } > } > > It should be possible to correct the problem by keeping on searching > in outer class if method shadow() is found in class FailImpl but > inapplicable. > The following patch for the jdk9 shows a possible solution: > > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java > b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java > @@ -1822,7 +1822,8 @@ > Symbol sym = findMethod( > env1, env1.enclClass.sym.type, name, argtypes, typeargtypes, > allowBoxing, useVarargs); > - if (sym.exists()) { > + // Keep on searching in outer environment if symbol is > found but inapplicable. > + if (sym.exists() && !(sym instanceof > Resolve.InapplicableSymbolError)) { > if (staticOnly && > sym.kind == MTH && > sym.owner.kind == TYP && > > I hope this could help. > > Regards, > > bsrbnd -------------- next part -------------- An HTML attachment was scrubbed... URL: From joe.darcy at oracle.com Mon May 11 22:58:42 2015 From: joe.darcy at oracle.com (joe darcy) Date: Mon, 11 May 2015 15:58:42 -0700 Subject: JDK 9 RFR of JDK-8053918: make the spec for @Documented comprehensible Message-ID: <55513422.70902@oracle.com> Hello, Some are of the opinion that the specification for the Documented meta-annotation type could be clarified. JDK-8053918: make the spec for @Documented comprehensible http://cr.openjdk.java.net/~darcy/8053918.0/ Please review the patch below which aims to accomplish this. Thanks, -Joe --- old/src/java.base/share/classes/java/lang/annotation/Documented.java 2015-05-11 15:54:37.273033243 -0700 +++ new/src/java.base/share/classes/java/lang/annotation/Documented.java 2015-05-11 15:54:37.153033240 -0700 @@ -26,12 +26,20 @@ package java.lang.annotation; /** - * Indicates that annotations with a type are to be documented by javadoc - * and similar tools by default. This type should be used to annotate the - * declarations of types whose annotations affect the use of annotated - * elements by their clients. If a type declaration is annotated with - * Documented, its annotations become part of the public API - * of the annotated elements. + * When an annotation type A is annotated with {@code + * Documented}, the presence and value of annotations of type A + * are a part of the public contract of the elements A + * annotates. + * + * Conversely, if an annotation type B is not + * annotated with {@code Documented}, the presence and value of + * Bannotations are not part of the public contract of + * the elements B annotates. + * + * Concretely, if an annotation type is annotated with {@code + * Documented}, by default a tool like javadoc will display + * annotations of that type in its output while annotations of + * annotation types without {@code Documented} will not be displayed. * * @author Joshua Bloch * @since 1.5 From jonathan.gibbons at oracle.com Mon May 11 23:07:24 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 11 May 2015 16:07:24 -0700 Subject: JDK 9 RFR of JDK-8053918: make the spec for @Documented comprehensible In-Reply-To: <55513422.70902@oracle.com> References: <55513422.70902@oracle.com> Message-ID: <5551362C.9040102@oracle.com> Although the original "first sentence" is somewhat hard to parse, at least there is a single "first sentence" The rewrite doesn't seem to have such a succint first sentence. If I were to change just one word in the original first sentence, I would change "with" to "on": - * Indicates that annotations with a type are to be documented by javadoc - * and similar tools by default. + * Indicates that annotations on a type are to be documented by javadoc +* and similar tools by default. -- Jon On 05/11/2015 03:58 PM, joe darcy wrote: > Hello, > > Some are of the opinion that the specification for the Documented > meta-annotation type could be clarified. > > JDK-8053918: make the spec for @Documented comprehensible > http://cr.openjdk.java.net/~darcy/8053918.0/ > > Please review the patch below which aims to accomplish this. > > Thanks, > > -Joe > > --- > old/src/java.base/share/classes/java/lang/annotation/Documented.java > 2015-05-11 15:54:37.273033243 -0700 > +++ > new/src/java.base/share/classes/java/lang/annotation/Documented.java > 2015-05-11 15:54:37.153033240 -0700 > @@ -26,12 +26,20 @@ > package java.lang.annotation; > > /** > - * Indicates that annotations with a type are to be documented by > javadoc > - * and similar tools by default. This type should be used to > annotate the > - * declarations of types whose annotations affect the use of annotated > - * elements by their clients. If a type declaration is annotated with > - * Documented, its annotations become part of the public API > - * of the annotated elements. > + * When an annotation type A is annotated with {@code > + * Documented}, the presence and value of annotations of type A > + * are a part of the public contract of the elements A > + * annotates. > + * > + * Conversely, if an annotation type B is not > + * annotated with {@code Documented}, the presence and value of > + * Bannotations are not part of the public contract of > + * the elements B annotates. > + * > + * Concretely, if an annotation type is annotated with {@code > + * Documented}, by default a tool like javadoc will display > + * annotations of that type in its output while annotations of > + * annotation types without {@code Documented} will not be displayed. > * > * @author Joshua Bloch > * @since 1.5 > From joe.darcy at oracle.com Mon May 11 23:16:25 2015 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Mon, 11 May 2015 16:16:25 -0700 Subject: JDK 9 RFR of JDK-8053918: make the spec for @Documented comprehensible In-Reply-To: <5551362C.9040102@oracle.com> References: <55513422.70902@oracle.com> <5551362C.9040102@oracle.com> Message-ID: <55513849.5000505@oracle.com> How about as a first sentence "The Documented meta-annotation indicates whether or not annotations of the annotation types it annotates are considered part of the public contract of the elements they in turn annotate." (Admittedly still a bit convoluted.) -Joe On 5/11/2015 4:07 PM, Jonathan Gibbons wrote: > Although the original "first sentence" is somewhat hard to parse, at > least there is a single "first sentence" The rewrite doesn't seem to > have such a succint first sentence. > > If I were to change just one word in the original first sentence, I > would change "with" to "on": > > - * Indicates that annotations with a type are to be documented by > javadoc > - * and similar tools by default. > + * Indicates that annotations on a type are to be documented by javadoc > +* and similar tools by default. > > -- Jon > > On 05/11/2015 03:58 PM, joe darcy wrote: >> Hello, >> >> Some are of the opinion that the specification for the Documented >> meta-annotation type could be clarified. >> >> JDK-8053918: make the spec for @Documented comprehensible >> http://cr.openjdk.java.net/~darcy/8053918.0/ >> >> Please review the patch below which aims to accomplish this. >> >> Thanks, >> >> -Joe >> >> --- >> old/src/java.base/share/classes/java/lang/annotation/Documented.java >> 2015-05-11 15:54:37.273033243 -0700 >> +++ >> new/src/java.base/share/classes/java/lang/annotation/Documented.java >> 2015-05-11 15:54:37.153033240 -0700 >> @@ -26,12 +26,20 @@ >> package java.lang.annotation; >> >> /** >> - * Indicates that annotations with a type are to be documented by >> javadoc >> - * and similar tools by default. This type should be used to >> annotate the >> - * declarations of types whose annotations affect the use of annotated >> - * elements by their clients. If a type declaration is annotated with >> - * Documented, its annotations become part of the public API >> - * of the annotated elements. >> + * When an annotation type A is annotated with {@code >> + * Documented}, the presence and value of annotations of type A >> + * are a part of the public contract of the elements A >> + * annotates. >> + * >> + * Conversely, if an annotation type B is not >> + * annotated with {@code Documented}, the presence and value of >> + * Bannotations are not part of the public contract of >> + * the elements B annotates. >> + * >> + * Concretely, if an annotation type is annotated with {@code >> + * Documented}, by default a tool like javadoc will display >> + * annotations of that type in its output while annotations of >> + * annotation types without {@code Documented} will not be displayed. >> * >> * @author Joshua Bloch >> * @since 1.5 >> > From jonathan.gibbons at oracle.com Mon May 11 23:35:46 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 11 May 2015 16:35:46 -0700 Subject: JDK 9 RFR of JDK-8053918: make the spec for @Documented comprehensible In-Reply-To: <55513849.5000505@oracle.com> References: <55513422.70902@oracle.com> <5551362C.9040102@oracle.com> <55513849.5000505@oracle.com> Message-ID: <55513CD2.3050106@oracle.com> Still a bit convoluted, but the mean time to comprehension is significant less than that of the original. -- Jon On 05/11/2015 04:16 PM, Joseph D. Darcy wrote: > How about as a first sentence > > "The Documented meta-annotation indicates whether or not annotations > of the annotation types it annotates are considered part of the public > contract of the elements they in turn annotate." > > (Admittedly still a bit convoluted.) > > -Joe > > > On 5/11/2015 4:07 PM, Jonathan Gibbons wrote: >> Although the original "first sentence" is somewhat hard to parse, at >> least there is a single "first sentence" The rewrite doesn't seem to >> have such a succint first sentence. >> >> If I were to change just one word in the original first sentence, I >> would change "with" to "on": >> >> - * Indicates that annotations with a type are to be documented by >> javadoc >> - * and similar tools by default. >> + * Indicates that annotations on a type are to be documented by javadoc >> +* and similar tools by default. >> >> -- Jon >> >> On 05/11/2015 03:58 PM, joe darcy wrote: >>> Hello, >>> >>> Some are of the opinion that the specification for the Documented >>> meta-annotation type could be clarified. >>> >>> JDK-8053918: make the spec for @Documented comprehensible >>> http://cr.openjdk.java.net/~darcy/8053918.0/ >>> >>> Please review the patch below which aims to accomplish this. >>> >>> Thanks, >>> >>> -Joe >>> >>> --- >>> old/src/java.base/share/classes/java/lang/annotation/Documented.java >>> 2015-05-11 15:54:37.273033243 -0700 >>> +++ >>> new/src/java.base/share/classes/java/lang/annotation/Documented.java >>> 2015-05-11 15:54:37.153033240 -0700 >>> @@ -26,12 +26,20 @@ >>> package java.lang.annotation; >>> >>> /** >>> - * Indicates that annotations with a type are to be documented by >>> javadoc >>> - * and similar tools by default. This type should be used to >>> annotate the >>> - * declarations of types whose annotations affect the use of annotated >>> - * elements by their clients. If a type declaration is annotated with >>> - * Documented, its annotations become part of the public API >>> - * of the annotated elements. >>> + * When an annotation type A is annotated with {@code >>> + * Documented}, the presence and value of annotations of type A >>> + * are a part of the public contract of the elements A >>> + * annotates. >>> + * >>> + * Conversely, if an annotation type B is not >>> + * annotated with {@code Documented}, the presence and value of >>> + * Bannotations are not part of the public contract of >>> + * the elements B annotates. >>> + * >>> + * Concretely, if an annotation type is annotated with {@code >>> + * Documented}, by default a tool like javadoc will display >>> + * annotations of that type in its output while annotations of >>> + * annotation types without {@code Documented} will not be displayed. >>> * >>> * @author Joshua Bloch >>> * @since 1.5 >>> >> > From alex.buckley at oracle.com Mon May 11 23:44:49 2015 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 11 May 2015 16:44:49 -0700 Subject: JDK 9 RFR of JDK-8053918: make the spec for @Documented comprehensible In-Reply-To: <55513849.5000505@oracle.com> References: <55513422.70902@oracle.com> <5551362C.9040102@oracle.com> <55513849.5000505@oracle.com> Message-ID: <55513EF1.3050602@oracle.com> Option A: If the annotation @Documented is present on the declaration of an annotation type T, then any @T annotation on an element is considered part of the element's public contract. Option B: The annotation type Documented is used to indicate that annotations of a given annotation type (namely, the type meta-annotated with @Documented) are considered part of the public contract of the elements they annotate. On 5/11/2015 4:16 PM, Joseph D. Darcy wrote: > How about as a first sentence > > "The Documented meta-annotation indicates whether or not annotations of > the annotation types it annotates are considered part of the public > contract of the elements they in turn annotate." > > (Admittedly still a bit convoluted.) > > -Joe > > > On 5/11/2015 4:07 PM, Jonathan Gibbons wrote: >> Although the original "first sentence" is somewhat hard to parse, at >> least there is a single "first sentence" The rewrite doesn't seem to >> have such a succint first sentence. >> >> If I were to change just one word in the original first sentence, I >> would change "with" to "on": >> >> - * Indicates that annotations with a type are to be documented by >> javadoc >> - * and similar tools by default. >> + * Indicates that annotations on a type are to be documented by javadoc >> +* and similar tools by default. >> >> -- Jon >> >> On 05/11/2015 03:58 PM, joe darcy wrote: >>> Hello, >>> >>> Some are of the opinion that the specification for the Documented >>> meta-annotation type could be clarified. >>> >>> JDK-8053918: make the spec for @Documented comprehensible >>> http://cr.openjdk.java.net/~darcy/8053918.0/ >>> >>> Please review the patch below which aims to accomplish this. >>> >>> Thanks, >>> >>> -Joe >>> >>> --- >>> old/src/java.base/share/classes/java/lang/annotation/Documented.java >>> 2015-05-11 15:54:37.273033243 -0700 >>> +++ >>> new/src/java.base/share/classes/java/lang/annotation/Documented.java >>> 2015-05-11 15:54:37.153033240 -0700 >>> @@ -26,12 +26,20 @@ >>> package java.lang.annotation; >>> >>> /** >>> - * Indicates that annotations with a type are to be documented by >>> javadoc >>> - * and similar tools by default. This type should be used to >>> annotate the >>> - * declarations of types whose annotations affect the use of annotated >>> - * elements by their clients. If a type declaration is annotated with >>> - * Documented, its annotations become part of the public API >>> - * of the annotated elements. >>> + * When an annotation type A is annotated with {@code >>> + * Documented}, the presence and value of annotations of type A >>> + * are a part of the public contract of the elements A >>> + * annotates. >>> + * >>> + * Conversely, if an annotation type B is not >>> + * annotated with {@code Documented}, the presence and value of >>> + * Bannotations are not part of the public contract of >>> + * the elements B annotates. >>> + * >>> + * Concretely, if an annotation type is annotated with {@code >>> + * Documented}, by default a tool like javadoc will display >>> + * annotations of that type in its output while annotations of >>> + * annotation types without {@code Documented} will not be displayed. >>> * >>> * @author Joshua Bloch >>> * @since 1.5 >>> >> > From georgiy.rakov at oracle.com Tue May 12 13:23:10 2015 From: georgiy.rakov at oracle.com (Georgiy Rakov) Date: Tue, 12 May 2015 16:23:10 +0300 Subject: Field of wildcard parameterized class is passed to anonymous class created with diamond; JDK bug? Message-ID: <5551FEBE.7000908@oracle.com> Hello, let's consider following example: classPar { Uf; } classCls { Cls(Tt) {} } public classTest70 { public static voidtest() { Par a =newPar<>(); newCls<>(a.f) { }; } } JDK9b60 compiles it successfully however according to my understanding compilation should have failed because: 1. The type of 'a' local variable is a parameterized type Par. 2. According to following assertion from JLS 4.5.2 the type of the field "f" of Par is a fresh capture variable: null-type <: CAP <: Object: If any of the type arguments in the parameterization of Care wildcards, then: o The types of the fields, methods, and constructors in C|<|T_1 ,...,T_n |>|are the types of the fields, methods, and constructors in the capture conversion of C|<|T_1 ,...,T_n |>|(?5.1.10 ). 3. 'new Cls<>(a.f) { }' causes T to be inferred as capture variable CAP presented in step 2. 4. According to following new assertion presented in JDK-8073593 issue comment compilation error should occur because superclass of the anonymous class is inferred as a type parameterized by type variable that was not declared as a type parameter (the capture variable CAP). ***/_*It is a compile-time error*_/ if the superclass or superinterface type of the anonymous class, T, or any subexpression of T, has one of the following forms: - A /_*type variable (4.4) that was not declared as a type parameter*_/ (such as /_*a type variable produced by capture conversion*_/ (5.1.10)) - An intersection type (4.9) - A class or interface type, where the class or interface declaration is not accessible from the class or interface in which the expression appears.*** The term "subexpression" includes type arguments of parameterized types (4.5), bounds of wildcards (4.5.1), and element types of array types (10.1). It excludes bounds of type variables.*** Could you please tell if you agree that this is really a JDK bug. Thank you, Georgiy. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- class Par { U f; } class Cls { Cls(T t) {} } public class Test70 { public static void test() { Par a = new Par<>(); new Cls<>(a.f) { }; } } From srikanth.adayapalam at oracle.com Wed May 13 03:54:12 2015 From: srikanth.adayapalam at oracle.com (Srikanth) Date: Wed, 13 May 2015 09:24:12 +0530 Subject: Field of wildcard parameterized class is passed to anonymous class created with diamond; JDK bug? In-Reply-To: <5551FEBE.7000908@oracle.com> References: <5551FEBE.7000908@oracle.com> Message-ID: <5552CAE4.4050003@oracle.com> Hi Georgiy, Thanks for the test case. This seems to be long standing behaviour in javac inference that surfaces with <> only when combined with anonymous classes. With diamond and with or without anonymous classes, i.e in both newCls<>(a.f); newCls<>(a.f) {} the elided type is inferred to be jlO and hence we don't report an error. I will double check whether inference is doing the right thing here. I see that ECJ infers the elided type to be Cls I'll either post a concluding clarification or raise a suitable JBS ticket to follow up. Thanks! Srikanth On Tuesday 12 May 2015 06:53 PM, Georgiy Rakov wrote: > Hello, > > let's consider following example: > > classPar { > Uf; > } > > classCls { > Cls(Tt) {} > } > > public classTest70 { > public static voidtest() { > Par a =newPar<>(); > newCls<>(a.f) { }; > } > } > > JDK9b60 compiles it successfully however according to my understanding > compilation should have failed because: > > 1. The type of 'a' local variable is a parameterized type Par. > 2. According to following assertion from JLS 4.5.2 the type of the > field "f" of Par is a fresh capture variable: null-type <: CAP <: > Object: > > If any of the type arguments in the parameterization of Care > wildcards, then: > > o > > The types of the fields, methods, and constructors in C|<|T_1 > ,...,T_n |>|are the types of the fields, methods, and > constructors in the capture conversion of C|<|T_1 ,...,T_n > |>|(?5.1.10 > ). > > > 3. 'new Cls<>(a.f) { }' causes T to be inferred as capture variable > CAP presented in step 2. > 4. According to following new assertion presented in JDK-8073593 issue > comment > compilation > error should occur because superclass of the anonymous class is > inferred as a type parameterized by type variable that was not > declared as a type parameter (the capture variable CAP). > > ***/_*It is a compile-time error*_/ if the superclass or > superinterface type of the anonymous class, T, or any > subexpression of T, has one of the following forms: > - A /_*type variable (4.4) that was not declared as a type > parameter*_/ (such as /_*a type variable produced by capture > conversion*_/ (5.1.10)) > - An intersection type (4.9) > - A class or interface type, where the class or interface > declaration is not accessible from the class or interface in which > the expression appears.*** > The term "subexpression" includes type arguments of parameterized > types (4.5), bounds of wildcards (4.5.1), and element types of > array types (10.1). It excludes bounds of type variables.*** > > Could you please tell if you agree that this is really a JDK bug. > > Thank you, > Georgiy. -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Wed May 13 10:07:15 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 13 May 2015 11:07:15 +0100 Subject: Field of wildcard parameterized class is passed to anonymous class created with diamond; JDK bug? In-Reply-To: <5552CAE4.4050003@oracle.com> References: <5551FEBE.7000908@oracle.com> <5552CAE4.4050003@oracle.com> Message-ID: <55532253.8050907@oracle.com> This is indeed long-standing javac behavior - also commented in the code: /** * javac has a long-standing 'simplification' (see 6391995): * given an actual argument type, the method check is performed * on its upper bound. This leads to inconsistencies when an * argument type is checked against itself. For example, given * a type-variable T, it is not true that {@codeU(T)<: T}, * so we need to guard against that. */ At some point this should be cleaned up - but there could be non-trivial compatibility concerns there. Maurizio On 13/05/15 04:54, Srikanth wrote: > Hi Georgiy, > > Thanks for the test case. > > This seems to be long standing behaviour in javac inference that > surfaces with <> only when combined with anonymous classes. > > With diamond and with or without anonymous classes, > > i.e in both > > newCls<>(a.f); > newCls<>(a.f) {} > > > the elided type is inferred to be jlO and hence we don't report an error. > > I will double check whether inference is doing the right thing here. I see > that ECJ infers the elided type to be Cls > > I'll either post a concluding clarification or raise a suitable JBS ticket to > follow up. > > Thanks! > Srikanth > On Tuesday 12 May 2015 06:53 PM, Georgiy Rakov wrote: >> Hello, >> >> let's consider following example: >> >> classPar { >> Uf; >> } >> >> classCls { >> Cls(Tt) {} >> } >> >> public classTest70 { >> public static voidtest() { >> Par a =newPar<>(); >> newCls<>(a.f) { }; >> } >> } >> >> JDK9b60 compiles it successfully however according to my >> understanding compilation should have failed because: >> >> 1. The type of 'a' local variable is a parameterized type Par. >> 2. According to following assertion from JLS 4.5.2 the type of the >> field "f" of Par is a fresh capture variable: null-type <: CAP <: >> Object: >> >> If any of the type arguments in the parameterization of Care >> wildcards, then: >> >> o >> >> The types of the fields, methods, and constructors in C|<|T_1 >> ,...,T_n |>|are the types of the fields, methods, and >> constructors in the capture conversion of C|<|T_1 ,...,T_n >> |>|(?5.1.10 >> ). >> >> >> 3. 'new Cls<>(a.f) { }' causes T to be inferred as capture variable >> CAP presented in step 2. >> 4. According to following new assertion presented in JDK-8073593 >> issue comment >> compilation >> error should occur because superclass of the anonymous class is >> inferred as a type parameterized by type variable that was not >> declared as a type parameter (the capture variable CAP). >> >> ***/_*It is a compile-time error*_/ if the superclass or >> superinterface type of the anonymous class, T, or any >> subexpression of T, has one of the following forms: >> - A /_*type variable (4.4) that was not declared as a type >> parameter*_/ (such as /_*a type variable produced by capture >> conversion*_/ (5.1.10)) >> - An intersection type (4.9) >> - A class or interface type, where the class or interface >> declaration is not accessible from the class or interface in >> which the expression appears.*** >> The term "subexpression" includes type arguments of parameterized >> types (4.5), bounds of wildcards (4.5.1), and element types of >> array types (10.1). It excludes bounds of type variables.*** >> >> Could you please tell if you agree that this is really a JDK bug. >> >> Thank you, >> Georgiy. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsrbnd at gmail.com Thu May 14 10:36:47 2015 From: bsrbnd at gmail.com (bsrbnd) Date: Thu, 14 May 2015 12:36:47 +0200 Subject: [PATCH] 8071433: private static method in outer class shadowed by inherited public method In-Reply-To: <5550C10B.3010403@oracle.com> References: <5550C10B.3010403@oracle.com> Message-ID: Hi, Thanks for your answer. You're right. Referring to JLS 15.12.1, method shadow(boolean) should be called from class FailImpl the following way: public void a() { StaticFail.shadow(false); ((StaticFail)this).shadow(false); super.shadow(false); } Issue 8071433 should be closed? Regards, bsrbnd 2015-05-11 16:47 GMT+02:00 Maurizio Cimadamore : > Is this even an issue? > > See JLS 15.12.1: > > "If the form is MethodName, that is, just an Identifier, then: > > If the Identifier appears in the scope of a visible method declaration with > that name (?6.3, ?6.4.1), then: > > If there is an enclosing type declaration of which that method is a > member, let T be the innermost such type declaration. The class or interface > to search is T. > > This search policy is called the "comb rule". It effectively looks for > methods in a nested class's superclass hierarchy before looking for methods > in an enclosing class and its superclass hierarchy. See ?6.5.7.1 for an > example." > > Here we have that FailImpl has an inherited member 'shadow()' - which means > FailImpl is the class to search. This will give you the type error. > > Maurizio > > > On 11/05/15 14:52, bsrbnd wrote: > > Hi, > > As described in case 8071433, the following code doesn't compile > because public method shadow() inherited from StaticFail hides private > static method shadow(boolean) defined in the same class (but not > inherited). > > public class StaticFail { > private static void shadow(boolean b) {System.out.println(b);} > public void shadow() {} > > public static class FailImpl extends StaticFail { > public void a() { > shadow(false); > } > } > > public static void main(String[] args) { > new FailImpl().a(); > } > } > > It should be possible to correct the problem by keeping on searching > in outer class if method shadow() is found in class FailImpl but > inapplicable. > The following patch for the jdk9 shows a possible solution: > > diff --git > a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java > b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java > @@ -1822,7 +1822,8 @@ > Symbol sym = findMethod( > env1, env1.enclClass.sym.type, name, argtypes, > typeargtypes, > allowBoxing, useVarargs); > - if (sym.exists()) { > + // Keep on searching in outer environment if symbol is > found but inapplicable. > + if (sym.exists() && !(sym instanceof > Resolve.InapplicableSymbolError)) { > if (staticOnly && > sym.kind == MTH && > sym.owner.kind == TYP && > > I hope this could help. > > Regards, > > bsrbnd > > From aleksey.shipilev at oracle.com Thu May 14 22:06:39 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Fri, 15 May 2015 01:06:39 +0300 Subject: String concatenation tweaks In-Reply-To: References: <55014F7C.20201@oracle.com> <553139FA.20601@oracle.com> <55313D3A.10008@univ-mlv.fr> Message-ID: <55551C6F.4000704@oracle.com> (finally found a slot to try this) On 17.04.2015 20:11, Louis Wasserman wrote: > I would be thrilled to see that level of magic, though that's probably > beyond my personal abilities to implement or contribute as a patch. It actually does not seem that scary. javac changes seem minimal, because they basically mirror [1] what is already done for current String concat and lambda desugaring. JDK side of changes is not too scary as well [2], and it readily lends itself to different implementation strategies, including precomputing the argument lengths. I realized too late it does not check for argument nullity properly, but this is a proof-of-concept patch anyway. The real upside is that you can spell out the optimized implementation in more familiar ASM, rather than in javac AST/IR. Since the indy bootstrap runs once during the linkage, and we know a lot about the callsite, we can even specialize for the cases Louis described originally (i.e. two Strings). I have also collected the notes here [3], and it seems precomputing the lengths indeed supplements OptoStringConcat nicely (i.e. catches up when OptoStringConcat fails). Although the benchmarking was very, very light. Opinions, suggestions, pitchforks are welcome. We would probably need to submit JEP at some point... volunteers? Thanks, -Aleksey. [1] http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/patch-langtools-1.patch [2] http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/patch-jdk-1.patch [3] http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/notes.txt -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From daniel.smith at oracle.com Tue May 19 20:37:21 2015 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 19 May 2015 14:37:21 -0600 Subject: [PATCH] 8071433: private static method in outer class shadowed by inherited public method In-Reply-To: References: <5550C10B.3010403@oracle.com> Message-ID: > On May 14, 2015, at 4:36 AM, bsrbnd wrote: > > Hi, > > Thanks for your answer. > You're right. > Referring to JLS 15.12.1, method shadow(boolean) should be called from > class FailImpl the following way: > > public void a() { > StaticFail.shadow(false); > ((StaticFail)this).shadow(false); > super.shadow(false); > } > > Issue 8071433 should be closed? Yep. It's also a duplicate. See (at least): https://bugs.openjdk.java.net/browse/JDK-6998594 (I swear I've seen this 2 or 3 other times, but it took me awhile to finally find that one.) ?Dan From daniel.smith at oracle.com Tue May 19 20:57:34 2015 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 19 May 2015 14:57:34 -0600 Subject: "Chained" qualified instance creation expressions (diamond in qualifiers) In-Reply-To: <554C9561.4020908@oracle.com> References: <554A1FDF.60509@oracle.com> <554C9561.4020908@oracle.com> Message-ID: > On May 8, 2015, at 4:52 AM, Srikanth wrote: > > On Wednesday 06 May 2015 07:36 PM, Georgiy Rakov wrote: >> Hello, >> >> let's consider following example: >> class D {} >> >> class Outer2 { >> class Outer1 { >> class Foo { } >> } >> } >> >> public class Test69 { >> >> public static void test(String argv[]) { >> Outer2.Outer1.Foo f20 = new Outer2<>().new Outer1<>().new Foo<>() { >> private Outer2.Outer1.Foo simpleMethod1() { return this; } >> //compiles Ok >> >> //private Outer2.Outer1.Foo simpleMethod2() { return this; } //causes compilation error >> >> }; >> } >> } >> >> JDK9b60 causes Q and W to be inferred as Object. This can be seen: >> - from the fact that code above compiles successfully; >> - from the fact that uncommenting the method above causes compilation failure. >> >> So what we actually have is: >> - Q is inferred as Object; >> - W is inferred as Object; >> - T is inferred as D. >> >> However according to intuition it seems that Q and W should have been inferred as D as it happens to T. >> >> I believe this corresponds to spec, the reasons presented below seem to cause this: >> >> 1. Following assertion from JLS 18.5.2 is not applied when JLS 15.9.3 is applied to new Outer2<>() and new Outer1<>(): >> Otherwise, the constraint formula ?R ? ? T? is reduced and incorporated with B2. >> So for outer classes inference proceeds with no constraint formula actually causing inference variable in question to be inferred as D. >> >> 2. JLS 15.9.3 doesn't use type parameters from outer classes when processing new Foo<>(). Namely following assertion from JLS 15.9.3 doesn't mention type parameters from possible outer classes: >> Let F1...Fp be the type parameters of C, and let G1...Gq be the type parameters (if any) of cj. >> So constraint formula created by JLS 18.5.2 assertion presented above engages just inference variable from Foo, i. e. T. >> >> However I believe more broad change of spec will be required to implement this "intuition" than just modifying spec according to two points above. >> >> So: >> 1. Could you please tell if I understand correctly that the fact that Q is inferred as Object, W is inferred as Object really corresponds to spec and it's not a JDK issue. > > Hi Georgiy, > > My original response is good enough for this part - The target type from the LHS i.e > Outer2.Outer1.Foo D> > > > gets imposed on > new Foo<>() { ... } > and the specification does not mandate/require/sanction/allow a qualified instance creation expression > to propagate the target type or any part thereof to any enclosing instance creation expression (qualified > or otherwise). > > So Q and W being inferred as Object is the right behaviour per the current specification. Yep, agreed. The qualifier of a ClassInstanceCreationExpression (15.9) is always a standalone expression (15.2) -- it is not in an assignment context or an invocation context (15.9, 15.12, etc.). (Note that the qualifier is an arbitrary expression, not necessarily another class instance creation.) >> 2. As for me it looks reasonable to enhance specification so that Q and W would be inferred as D too. Could you please tell if you agree. If you do would it be worth creating spec enhancement in Jira? > > This part which have you described as being "intuitive", I'll request Dan Smith to answer the reasons for the state of the art - I don't readily know what canons of type system theory would require it to be > the way it is - i.e why would we not allow the qualified allocation expression to propagate suitable target types to the enclosing expressions - and whether this is something amenable to tinkering. Allowing an arbitrary receiver expression to use context for inference is something we've looked at, but it's harder than it might seem when looking at this limited example. You might see references to "chained inference" in, e.g., Lambda documents. Maybe someday, but it's a full-fledged new feature, not a bug fix. ?Dan From daniel.smith at oracle.com Tue May 19 21:27:45 2015 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 19 May 2015 15:27:45 -0600 Subject: jls overridding description In-Reply-To: <554A32E5.9080304@oracle.com> References: <554A32E5.9080304@oracle.com> Message-ID: <9EC63542-0F62-4DFD-BCCB-BD8814DCB5D2@oracle.com> > On May 6, 2015, at 9:27 AM, konstantin barzilovich wrote: > > Hello, > > In Chapter 8 of jls there is assertion jls-8.4.8.1-100 > "An instance method mc, declared in or inherited by class C, overrides from C another method ma, declared in class A, iff all of the following are true: " > which describe conditions of overriding of classes methods. As I understand, one of jls-8.4.8.1-100-B > "C doesn't inherit ma" > and jls-8.4.8.1-100-C > "The signature of mc is a subsignature of the signature of ma" > is redundant because if we omit, for example, jls-8.4.8.1-100-C, > no cases will be missed. You're appealing to this (8.4.8): "A class C inherits from its direct superclass all concrete methods m (both static and instance) of the superclass for which ... no method declared in C has a signature that is a subsignature (?8.4.2) of the signature of m." and "A class C inherits from its direct superclass and direct superinterfaces all abstract and default (?9.4) methods m for which ... no method declared in C has a signature that is a subsignature (?8.4.2) of the signature of m, [and] no concrete method inherited by C from its direct superclass has a signature that is a subsignature of the signature of m" And, additionally, this (8.4.2): "It is a compile-time error to declare two methods with override-equivalent signatures in a class." So, how can 'mA' be inherited by C, yet 'mC' have a subsignature of the signature of 'mA'? First, 'mC' must not be declared in C. Second, the declaration of 'mC' must not be override equivalent with 'mA'. Typically, you get there with generics: abstract class A { abstract void m1(T arg); abstract void m2(String arg); } abstract class C extends A {} Now m1 and m2 are both inherited by C and have the same signature (in C). But we do not want to claim that one overrides the other -- they just coexist in the same class (see also 8.4.8.4 and 15.12.2.5). You could also get there with two concrete methods, although that would be an error. (BTW, sorry for not seeing this sooner. I don't always read every post to compiler-dev, so feel free to ping me if there's something like this you're waiting for a response on.) ?Dan From konstantin.barzilovich at oracle.com Wed May 20 13:24:30 2015 From: konstantin.barzilovich at oracle.com (konstantin barzilovich) Date: Wed, 20 May 2015 16:24:30 +0300 Subject: jls overridding description In-Reply-To: <9EC63542-0F62-4DFD-BCCB-BD8814DCB5D2@oracle.com> References: <554A32E5.9080304@oracle.com> <9EC63542-0F62-4DFD-BCCB-BD8814DCB5D2@oracle.com> Message-ID: <555C8B0E.7010609@oracle.com> Hello, Thank you for the answer. As I understand, you said that jls-8.4.8.1-100-B can be false while jls-8.4.8.1-100-C is true. But is it possible that jls-8.4.8.1-100-C is false while jls-8.4.8.1-100-B is true? (the opposite situation) I think, that the only reason to C doesn't inherit ma is that there is another method mc with subsignature of ma. Speaking in short I think that jls-8.4.8.1-100-B is more general, then jls-8.4.8.1-100-C. Thanks, Konstantin. On 20.05.2015 0:27, Dan Smith wrote: >> On May 6, 2015, at 9:27 AM, konstantin barzilovich wrote: >> >> Hello, >> >> In Chapter 8 of jls there is assertion jls-8.4.8.1-100 >> "An instance method mc, declared in or inherited by class C, overrides from C another method ma, declared in class A, iff all of the following are true:" >> which describe conditions of overriding of classes methods. As I understand, one of jls-8.4.8.1-100-B >> "C doesn't inherit ma" >> and jls-8.4.8.1-100-C >> "The signature of mc is a subsignature of the signature of ma" >> is redundant because if we omit, for example, jls-8.4.8.1-100-C, >> no cases will be missed. > You're appealing to this (8.4.8): > > "A class C inherits from its direct superclass all concrete methods m (both static and instance) of the superclass for which ... no method declared in C has a signature that is a subsignature (?8.4.2) of the signature of m." > > and > > "A class C inherits from its direct superclass and direct superinterfaces all abstract and default (?9.4) methods m for which ... no method declared in C has a signature that is a subsignature (?8.4.2) of the signature of m, [and] no concrete method inherited by C from its direct superclass has a signature that is a subsignature of the signature of m" > > And, additionally, this (8.4.2): > > "It is a compile-time error to declare two methods with override-equivalent signatures in a class." > > So, how can 'mA' be inherited by C, yet 'mC' have a subsignature of the signature of 'mA'? First, 'mC' must not be declared in C. Second, the declaration of 'mC' must not be override equivalent with 'mA'. > > Typically, you get there with generics: > > abstract class A { > abstract void m1(T arg); > abstract void m2(String arg); > } > > abstract class C extends A {} > > Now m1 and m2 are both inherited by C and have the same signature (in C). But we do not want to claim that one overrides the other -- they just coexist in the same class (see also 8.4.8.4 and 15.12.2.5). You could also get there with two concrete methods, although that would be an error. > > (BTW, sorry for not seeing this sooner. I don't always read every post to compiler-dev, so feel free to ping me if there's something like this you're waiting for a response on.) > > ?Dan From daniel.smith at oracle.com Wed May 20 15:50:15 2015 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 20 May 2015 09:50:15 -0600 Subject: jls overridding description In-Reply-To: <555C8B0E.7010609@oracle.com> References: <554A32E5.9080304@oracle.com> <9EC63542-0F62-4DFD-BCCB-BD8814DCB5D2@oracle.com> <555C8B0E.7010609@oracle.com> Message-ID: <7AD00602-116A-4831-A8E0-5B547B6B66B5@oracle.com> > On May 20, 2015, at 7:24 AM, konstantin barzilovich wrote: > > Hello, > > Thank you for the answer. > As I understand, you said that jls-8.4.8.1-100-B can be false while jls-8.4.8.1-100-C is true. Right: you can have mC with a subsignature of mA, but still inherit mA. > But is it possible that jls-8.4.8.1-100-C is false while jls-8.4.8.1-100-B is true? (the opposite situation) Can you not inherit mA, but choose an mC that does not have a subsignature of mA? Sure. Note that the selection of mA and mC is pretty unrestricted -- this subsignature clause it what limits the set of methods to things you'd intuitively expect to consider. So, for example: public class A { public void foo() {} // mA } public class B { public void bar(int arg) {} // mC public void foo() {} } Is A a superclass of C? Yep. Does C inherit mA? Nope -- the declaration of another 'foo' method prevents it. Is mA public? Yep. But mC definitely does not override mA. ?Dan From jan.lahoda at oracle.com Thu May 21 07:01:32 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Thu, 21 May 2015 09:01:32 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version Message-ID: <555D82CC.9070105@oracle.com> Hi, This is a patch adding a new option, -platform, to javac. Patch for the top-level repository is here: http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ Patch for the langtools repository is here: http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ These changes also require additional langtools changes as their prerequisite: http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ Overall, one can imagine '-platform N' to have the same effect as '-source N -target N -bootclasspath '. The possible values for 'N' are pluggable in a limited way, though (see langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). Note that this patch only introduces N=7 and N=8, which correspond to Open JDK 7 and 8 GA. A tricky problem to solve is where to get the APIs for platform N. The proposal is to include history data in the textual format inside the OpenJDK repositories (the input data), process them at build time and create a lib/ct.sym file holding the data in the JDK image. javac running with the -platform option then compiles against the lib/ct.sym file. The input history data are placed /make/data/symbols (the sym.txt files). This patches only includes data for OpenJDK 7 and 8, and only for public APIs (more or less Java SE and JDK @Exported APIs). The size of the history data is currently ~6MB in the JDK checkout and ~650kB inside the .hg directory (the size could change significantly if additional classes/elements, like non-public API classes, would need to be included). The lib/ct.sym file is currently ~4.5MB. The ct.sym file is a zip file containing signature files. The signature files are similar to classfiles (so javac can read them as classfiles), but are missing some attributes, most notably the Code attribute. On the top-level, the ct.sym contains directories named "7", "78" and "8". When compiling for version 'N', the bootclasspath for that version is obtained by using directories which have 'N' in their name. The sigfiles for ct.sym are created by /make/tools/symbolgenerator/CreateSymbols.java. The same file can also be used to construct the sym.txt files. Concise instructions are part of the CreateSymbols.java. I am sending this as one review, as the changes together make one feature, but the langtools and top-level changes are independent to a great degree: the langtools changes add the "-platform" javac; and the top-level changes add the history data and ability to build the ct.sym file. If desired, these could be pushed and/or reviewed independently. Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan Bateman and others who have provided advices and help on the matter before. Any insights/comments are wholeheartedly welcome. Thanks, Jan From erik.joelsson at oracle.com Thu May 21 09:42:36 2015 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Thu, 21 May 2015 11:42:36 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555D82CC.9070105@oracle.com> References: <555D82CC.9070105@oracle.com> Message-ID: <555DA88C.1080206@oracle.com> Hello Jan, On the build changes there are some things I would like to change. * The creation of the ct.sym file should be done in a separate file, with a separate top level target. The images target should just be about linking and pulling things together, not actual building/compiling of things. * The calls to MakeDir are not needed. * There are missing prerequisites in the rule for creating the symbols. * The jar file creation should use the SetupArchive macro. * Intermediate build files should be put into the $(SUPPORT_OUTPUTDIR). * I think it makes sense to have the ct.sym file be part of the exploded-image. Since this was quite a lot of changes, I took the liberty of implementing them. Here is a webrev with my suggestion for build changes: http://cr.openjdk.java.net/~erikj/8072480/webrev.01/ /Erik On 2015-05-21 09:01, Jan Lahoda wrote: > Hi, > > This is a patch adding a new option, -platform, to javac. > > Patch for the top-level repository is here: > http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ > > Patch for the langtools repository is here: > http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ > > These changes also require additional langtools changes as their > prerequisite: > http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ > > Overall, one can imagine '-platform N' to have the same effect as > '-source N -target N -bootclasspath '. The possible values > for 'N' are pluggable in a limited way, though (see > langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). > Note that this patch only introduces N=7 and N=8, which correspond to > Open JDK 7 and 8 GA. > > A tricky problem to solve is where to get the APIs for platform N. The > proposal is to include history data in the textual format inside the > OpenJDK repositories (the input data), process them at build time and > create a lib/ct.sym file holding the data in the JDK image. javac > running with the -platform option then compiles against the lib/ct.sym > file. The input history data are placed > /make/data/symbols (the sym.txt files). This > patches only includes data for OpenJDK 7 and 8, and only for public > APIs (more or less Java SE and JDK @Exported APIs). > > The size of the history data is currently ~6MB in the JDK checkout and > ~650kB inside the .hg directory (the size could change significantly > if additional classes/elements, like non-public API classes, would > need to be included). The lib/ct.sym file is currently ~4.5MB. > > The ct.sym file is a zip file containing signature files. The > signature files are similar to classfiles (so javac can read them as > classfiles), but are missing some attributes, most notably the Code > attribute. On the top-level, the ct.sym contains directories named > "7", "78" and "8". When compiling for version 'N', the bootclasspath > for that version is obtained by using directories which have 'N' in > their name. > > The sigfiles for ct.sym are created by > /make/tools/symbolgenerator/CreateSymbols.java. > The same file can also be used to construct the sym.txt files. Concise > instructions are part of the CreateSymbols.java. > > I am sending this as one review, as the changes together make one > feature, but the langtools and top-level changes are independent to a > great degree: the langtools changes add the "-platform" javac; and the > top-level changes add the history data and ability to build the ct.sym > file. If desired, these could be pushed and/or reviewed independently. > > Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan > Bateman and others who have provided advices and help on the matter > before. > > Any insights/comments are wholeheartedly welcome. > > Thanks, > Jan From jan.lahoda at oracle.com Thu May 21 10:19:20 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Thu, 21 May 2015 12:19:20 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555DA88C.1080206@oracle.com> References: <555D82CC.9070105@oracle.com> <555DA88C.1080206@oracle.com> Message-ID: <555DB128.2030609@oracle.com> Hello Eric, Thanks a lot for your feedback and changes! I'll fold them into the patch. Thanks, Jan On 21.5.2015 11:42, Erik Joelsson wrote: > Hello Jan, > > On the build changes there are some things I would like to change. > > * The creation of the ct.sym file should be done in a separate file, > with a separate top level target. The images target should just be about > linking and pulling things together, not actual building/compiling of > things. > * The calls to MakeDir are not needed. > * There are missing prerequisites in the rule for creating the symbols. > * The jar file creation should use the SetupArchive macro. > * Intermediate build files should be put into the $(SUPPORT_OUTPUTDIR). > * I think it makes sense to have the ct.sym file be part of the > exploded-image. > > Since this was quite a lot of changes, I took the liberty of > implementing them. Here is a webrev with my suggestion for build changes: > > http://cr.openjdk.java.net/~erikj/8072480/webrev.01/ > > /Erik > > On 2015-05-21 09:01, Jan Lahoda wrote: >> Hi, >> >> This is a patch adding a new option, -platform, to javac. >> >> Patch for the top-level repository is here: >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >> >> Patch for the langtools repository is here: >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >> >> These changes also require additional langtools changes as their >> prerequisite: >> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ >> >> Overall, one can imagine '-platform N' to have the same effect as >> '-source N -target N -bootclasspath '. The possible values >> for 'N' are pluggable in a limited way, though (see >> langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). >> Note that this patch only introduces N=7 and N=8, which correspond to >> Open JDK 7 and 8 GA. >> >> A tricky problem to solve is where to get the APIs for platform N. The >> proposal is to include history data in the textual format inside the >> OpenJDK repositories (the input data), process them at build time and >> create a lib/ct.sym file holding the data in the JDK image. javac >> running with the -platform option then compiles against the lib/ct.sym >> file. The input history data are placed >> /make/data/symbols (the sym.txt files). This >> patches only includes data for OpenJDK 7 and 8, and only for public >> APIs (more or less Java SE and JDK @Exported APIs). >> >> The size of the history data is currently ~6MB in the JDK checkout and >> ~650kB inside the .hg directory (the size could change significantly >> if additional classes/elements, like non-public API classes, would >> need to be included). The lib/ct.sym file is currently ~4.5MB. >> >> The ct.sym file is a zip file containing signature files. The >> signature files are similar to classfiles (so javac can read them as >> classfiles), but are missing some attributes, most notably the Code >> attribute. On the top-level, the ct.sym contains directories named >> "7", "78" and "8". When compiling for version 'N', the bootclasspath >> for that version is obtained by using directories which have 'N' in >> their name. >> >> The sigfiles for ct.sym are created by >> /make/tools/symbolgenerator/CreateSymbols.java. >> The same file can also be used to construct the sym.txt files. Concise >> instructions are part of the CreateSymbols.java. >> >> I am sending this as one review, as the changes together make one >> feature, but the langtools and top-level changes are independent to a >> great degree: the langtools changes add the "-platform" javac; and the >> top-level changes add the history data and ability to build the ct.sym >> file. If desired, these could be pushed and/or reviewed independently. >> >> Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan >> Bateman and others who have provided advices and help on the matter >> before. >> >> Any insights/comments are wholeheartedly welcome. >> >> Thanks, >> Jan > From maurizio.cimadamore at oracle.com Thu May 21 10:31:53 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 21 May 2015 11:31:53 +0100 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555D82CC.9070105@oracle.com> References: <555D82CC.9070105@oracle.com> Message-ID: <555DB419.6020301@oracle.com> Hi Jan, great work - couple of comments below: * it seems like some of the routines in Arguments can be simplified using lambdas - especially lookupPlatformProvider and checkOptionAllowed * Why JDKPlatformProvider is not called JDKPlatformProvider*Factory* ? * JavacProcessingEnvironment.JoiningIterator seems to have commonalities with CompoundScopeIterator - any chance that we might refactor this a bit? * What's the rationale for giving an error if -platform is specified and a non-StandardFileManager is provided? Can't we simply swallow that, ignore the platform settings and issue a Lint 'options' warning? * Would it make sense for some of the classfile generation logic in CreateSymbols to be moved under the classfile API ? * I had hard time reconciling some of the comments in CreateSymbols with how the files were laid out. I think in the end, what you mean is that if you have platforms 7, 8, 9 - you should pick one baseline (i.e. 8) and then generate diffs for 9 and 7 against the 8 one. If that's the use case, I think the command line can be simplified a bit in order to explicitly state which of the platform is the baseline one, and the remaining parameters can be inferred from the tool (as the seem to be typically all identical but one which is set to - the one for the baseline). Maybe the inference logic should be different (i.e. use 8 as a baseline for 7 and 7 as a baseline for 6) - but - whatever the logic, I think it should be chosen once and for all, and live implicitly in the tool? Or are there reasons as to why it might be handy to customize the baselines? Maurizio On 21/05/15 08:01, Jan Lahoda wrote: > Hi, > > This is a patch adding a new option, -platform, to javac. > > Patch for the top-level repository is here: > http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ > > Patch for the langtools repository is here: > http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ > > These changes also require additional langtools changes as their > prerequisite: > http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ > > Overall, one can imagine '-platform N' to have the same effect as > '-source N -target N -bootclasspath '. The possible values > for 'N' are pluggable in a limited way, though (see > langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). > Note that this patch only introduces N=7 and N=8, which correspond to > Open JDK 7 and 8 GA. > > A tricky problem to solve is where to get the APIs for platform N. The > proposal is to include history data in the textual format inside the > OpenJDK repositories (the input data), process them at build time and > create a lib/ct.sym file holding the data in the JDK image. javac > running with the -platform option then compiles against the lib/ct.sym > file. The input history data are placed > /make/data/symbols (the sym.txt files). This > patches only includes data for OpenJDK 7 and 8, and only for public > APIs (more or less Java SE and JDK @Exported APIs). > > The size of the history data is currently ~6MB in the JDK checkout and > ~650kB inside the .hg directory (the size could change significantly > if additional classes/elements, like non-public API classes, would > need to be included). The lib/ct.sym file is currently ~4.5MB. > > The ct.sym file is a zip file containing signature files. The > signature files are similar to classfiles (so javac can read them as > classfiles), but are missing some attributes, most notably the Code > attribute. On the top-level, the ct.sym contains directories named > "7", "78" and "8". When compiling for version 'N', the bootclasspath > for that version is obtained by using directories which have 'N' in > their name. > > The sigfiles for ct.sym are created by > /make/tools/symbolgenerator/CreateSymbols.java. > The same file can also be used to construct the sym.txt files. Concise > instructions are part of the CreateSymbols.java. > > I am sending this as one review, as the changes together make one > feature, but the langtools and top-level changes are independent to a > great degree: the langtools changes add the "-platform" javac; and the > top-level changes add the history data and ability to build the ct.sym > file. If desired, these could be pushed and/or reviewed independently. > > Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan > Bateman and others who have provided advices and help on the matter > before. > > Any insights/comments are wholeheartedly welcome. > > Thanks, > Jan From magnus.ihse.bursie at oracle.com Thu May 21 11:21:25 2015 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Thu, 21 May 2015 13:21:25 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555DA88C.1080206@oracle.com> References: <555D82CC.9070105@oracle.com> <555DA88C.1080206@oracle.com> Message-ID: <555DBFB5.4090206@oracle.com> Hi Erik and Jan, Erik's modifications look much better to me. I'm just not entirerly satisfied with how this new symbolgenerator tool fits int our model. It's really a buildtool, similar to the other buildtools we have. First of all, the location is not really ideal. Compare with how the java build tools are stored, e.g. jdk/make/src/classes/build/tools/charsetmapping. Correspondingly, I believe the symbolgenerator should live in $TOP/make/src/classes/build/tools/symbolgenerator. This makes it clear that it's source code, leaves room for native build tools, and sets up a common package prefix (while build.tools. might not be ideal, it's the same as in the JDK build tools, so let's keep it). Second, and this is more of a open question, mostly directed at Erik, shouldn't we build the symbolgenerator tool at the buildtools phase? It might require slightly more work to adapt the buildtools system for the top level, but I believe it is much more in line with what we got. /Magnus On 2015-05-21 11:42, Erik Joelsson wrote: > Hello Jan, > > On the build changes there are some things I would like to change. > > * The creation of the ct.sym file should be done in a separate file, > with a separate top level target. The images target should just be > about linking and pulling things together, not actual > building/compiling of things. > * The calls to MakeDir are not needed. > * There are missing prerequisites in the rule for creating the symbols. > * The jar file creation should use the SetupArchive macro. > * Intermediate build files should be put into the $(SUPPORT_OUTPUTDIR). > * I think it makes sense to have the ct.sym file be part of the > exploded-image. > > Since this was quite a lot of changes, I took the liberty of > implementing them. Here is a webrev with my suggestion for build changes: > > http://cr.openjdk.java.net/~erikj/8072480/webrev.01/ > > /Erik > > On 2015-05-21 09:01, Jan Lahoda wrote: >> Hi, >> >> This is a patch adding a new option, -platform, to javac. >> >> Patch for the top-level repository is here: >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >> >> Patch for the langtools repository is here: >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >> >> These changes also require additional langtools changes as their >> prerequisite: >> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ >> >> Overall, one can imagine '-platform N' to have the same effect as >> '-source N -target N -bootclasspath '. The possible >> values for 'N' are pluggable in a limited way, though (see >> langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). >> Note that this patch only introduces N=7 and N=8, which correspond to >> Open JDK 7 and 8 GA. >> >> A tricky problem to solve is where to get the APIs for platform N. >> The proposal is to include history data in the textual format inside >> the OpenJDK repositories (the input data), process them at build time >> and create a lib/ct.sym file holding the data in the JDK image. javac >> running with the -platform option then compiles against the >> lib/ct.sym file. The input history data are placed >> /make/data/symbols (the sym.txt files). This >> patches only includes data for OpenJDK 7 and 8, and only for public >> APIs (more or less Java SE and JDK @Exported APIs). >> >> The size of the history data is currently ~6MB in the JDK checkout >> and ~650kB inside the .hg directory (the size could change >> significantly if additional classes/elements, like non-public API >> classes, would need to be included). The lib/ct.sym file is currently >> ~4.5MB. >> >> The ct.sym file is a zip file containing signature files. The >> signature files are similar to classfiles (so javac can read them as >> classfiles), but are missing some attributes, most notably the Code >> attribute. On the top-level, the ct.sym contains directories named >> "7", "78" and "8". When compiling for version 'N', the bootclasspath >> for that version is obtained by using directories which have 'N' in >> their name. >> >> The sigfiles for ct.sym are created by >> /make/tools/symbolgenerator/CreateSymbols.java. >> The same file can also be used to construct the sym.txt files. >> Concise instructions are part of the CreateSymbols.java. >> >> I am sending this as one review, as the changes together make one >> feature, but the langtools and top-level changes are independent to a >> great degree: the langtools changes add the "-platform" javac; and >> the top-level changes add the history data and ability to build the >> ct.sym file. If desired, these could be pushed and/or reviewed >> independently. >> >> Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan >> Bateman and others who have provided advices and help on the matter >> before. >> >> Any insights/comments are wholeheartedly welcome. >> >> Thanks, >> Jan > From erik.joelsson at oracle.com Thu May 21 11:47:41 2015 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Thu, 21 May 2015 13:47:41 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555DBFB5.4090206@oracle.com> References: <555D82CC.9070105@oracle.com> <555DA88C.1080206@oracle.com> <555DBFB5.4090206@oracle.com> Message-ID: <555DC5DD.2020607@oracle.com> On 2015-05-21 13:21, Magnus Ihse Bursie wrote: > Hi Erik and Jan, > > Erik's modifications look much better to me. > > I'm just not entirerly satisfied with how this new symbolgenerator > tool fits int our model. It's really a buildtool, similar to the other > buildtools we have. > > First of all, the location is not really ideal. Compare with how the > java build tools are stored, e.g. > jdk/make/src/classes/build/tools/charsetmapping. Correspondingly, I > believe the symbolgenerator should live in > $TOP/make/src/classes/build/tools/symbolgenerator. This makes it clear > that it's source code, leaves room for native build tools, and sets up > a common package prefix (while build.tools. might not be ideal, > it's the same as in the JDK build tools, so let's keep it). > I agree with this. > Second, and this is more of a open question, mostly directed at Erik, > shouldn't we build the symbolgenerator tool at the buildtools phase? > It might require slightly more work to adapt the buildtools system for > the top level, but I believe it is much more in line with what we got. > We had an offline discussion and concluded that the build tools building needs to be redone in some better way, for this new tool and for all the existing ones. Until this happens, we will accept the current solution here. /Erik > /Magnus > > On 2015-05-21 11:42, Erik Joelsson wrote: >> Hello Jan, >> >> On the build changes there are some things I would like to change. >> >> * The creation of the ct.sym file should be done in a separate file, >> with a separate top level target. The images target should just be >> about linking and pulling things together, not actual >> building/compiling of things. >> * The calls to MakeDir are not needed. >> * There are missing prerequisites in the rule for creating the symbols. >> * The jar file creation should use the SetupArchive macro. >> * Intermediate build files should be put into the $(SUPPORT_OUTPUTDIR). >> * I think it makes sense to have the ct.sym file be part of the >> exploded-image. >> >> Since this was quite a lot of changes, I took the liberty of >> implementing them. Here is a webrev with my suggestion for build >> changes: >> >> http://cr.openjdk.java.net/~erikj/8072480/webrev.01/ >> >> /Erik >> >> On 2015-05-21 09:01, Jan Lahoda wrote: >>> Hi, >>> >>> This is a patch adding a new option, -platform, to javac. >>> >>> Patch for the top-level repository is here: >>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >>> >>> Patch for the langtools repository is here: >>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >>> >>> These changes also require additional langtools changes as their >>> prerequisite: >>> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ >>> >>> Overall, one can imagine '-platform N' to have the same effect as >>> '-source N -target N -bootclasspath '. The possible >>> values for 'N' are pluggable in a limited way, though (see >>> langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). >>> Note that this patch only introduces N=7 and N=8, which correspond >>> to Open JDK 7 and 8 GA. >>> >>> A tricky problem to solve is where to get the APIs for platform N. >>> The proposal is to include history data in the textual format inside >>> the OpenJDK repositories (the input data), process them at build >>> time and create a lib/ct.sym file holding the data in the JDK image. >>> javac running with the -platform option then compiles against the >>> lib/ct.sym file. The input history data are placed >>> /make/data/symbols (the sym.txt files). This >>> patches only includes data for OpenJDK 7 and 8, and only for public >>> APIs (more or less Java SE and JDK @Exported APIs). >>> >>> The size of the history data is currently ~6MB in the JDK checkout >>> and ~650kB inside the .hg directory (the size could change >>> significantly if additional classes/elements, like non-public API >>> classes, would need to be included). The lib/ct.sym file is >>> currently ~4.5MB. >>> >>> The ct.sym file is a zip file containing signature files. The >>> signature files are similar to classfiles (so javac can read them as >>> classfiles), but are missing some attributes, most notably the Code >>> attribute. On the top-level, the ct.sym contains directories named >>> "7", "78" and "8". When compiling for version 'N', the bootclasspath >>> for that version is obtained by using directories which have 'N' in >>> their name. >>> >>> The sigfiles for ct.sym are created by >>> /make/tools/symbolgenerator/CreateSymbols.java. The >>> same file can also be used to construct the sym.txt files. Concise >>> instructions are part of the CreateSymbols.java. >>> >>> I am sending this as one review, as the changes together make one >>> feature, but the langtools and top-level changes are independent to >>> a great degree: the langtools changes add the "-platform" javac; and >>> the top-level changes add the history data and ability to build the >>> ct.sym file. If desired, these could be pushed and/or reviewed >>> independently. >>> >>> Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan >>> Bateman and others who have provided advices and help on the matter >>> before. >>> >>> Any insights/comments are wholeheartedly welcome. >>> >>> Thanks, >>> Jan >> > From jan.lahoda at oracle.com Thu May 21 11:48:33 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Thu, 21 May 2015 13:48:33 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555DB419.6020301@oracle.com> References: <555D82CC.9070105@oracle.com> <555DB419.6020301@oracle.com> Message-ID: <555DC611.5000702@oracle.com> Hi Maurizio, Thanks for the comments. On 21.5.2015 12:31, Maurizio Cimadamore wrote: > Hi Jan, > great work - couple of comments below: > > * it seems like some of the routines in Arguments can be simplified > using lambdas - especially lookupPlatformProvider and checkOptionAllowed Yes, I'll take a look. > * Why JDKPlatformProvider is not called JDKPlatformProvider*Factory* ? A remnant of history, I'll fix that. > * JavacProcessingEnvironment.JoiningIterator seems to have commonalities > with CompoundScopeIterator - any chance that we might refactor this a bit? I'll take a look. > * What's the rationale for giving an error if -platform is specified and > a non-StandardFileManager is provided? Can't we simply swallow that, > ignore the platform settings and issue a Lint 'options' warning? If the bootclasspath cannot be set for -platform N, javac would be compiling against the current version of the API, not against the N's APIs. And so the result may not be able to run on N. So it seemed more appropriate to me to refuse to continue rather than continue and produce a potentially wrong result. > * Would it make sense for some of the classfile generation logic in > CreateSymbols to be moved under the classfile API ? Possibly - the Classfile API could be made more friendly to create classes from scratch. I'd prefer to keep that separate from this effort, though. > * I had hard time reconciling some of the comments in CreateSymbols with > how the files were laid out. I think in the end, what you mean is that Ok - I'll work on making the comments more comprehensible. > if you have platforms 7, 8, 9 - you should pick one baseline (i.e. 8) > and then generate diffs for 9 and 7 against the 8 one. If that's the use > case, I think the command line can be simplified a bit in order to > explicitly state which of the platform is the baseline one, and the > remaining parameters can be inferred from the tool (as the > seem to be typically all identical > but one which is set to - the one for the baseline). Maybe the > inference logic should be different (i.e. use 8 as a baseline for 7 and > 7 as a baseline for 6) - but - whatever the logic, I think it should be > chosen once and for all, and live implicitly in the tool? Or are there > reasons as to why it might be handy to customize the baselines? As an example, consider we would be currently storing data for 6, 7 and 8. We could have full 8 APIs stored, and then 8->7 diff and 7->6 diff. So the baseline for 7 would be 8 and the baseline for 6 would be 7. When the data for 9 would be added(*), we could keep the full APIs for 8 (to avoid wasting space in the repository), and then store 8->9 and 8->7 diffs (and drop 6). So 8 would be the baseline for both 7 and 9. So, some flexibility may be useful here. Does this make some sense? (*) For JDK 9, there are no history data stored for 9, -platform 9 uses the real JDK 9's bootclasspath (for JDK 9, -platform 9 is mostly a no-op). We would presumably add the history data for 9 when JDK 9 is finished. Thanks! Jan > > Maurizio > > On 21/05/15 08:01, Jan Lahoda wrote: >> Hi, >> >> This is a patch adding a new option, -platform, to javac. >> >> Patch for the top-level repository is here: >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >> >> Patch for the langtools repository is here: >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >> >> These changes also require additional langtools changes as their >> prerequisite: >> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ >> >> Overall, one can imagine '-platform N' to have the same effect as >> '-source N -target N -bootclasspath '. The possible values >> for 'N' are pluggable in a limited way, though (see >> langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). >> Note that this patch only introduces N=7 and N=8, which correspond to >> Open JDK 7 and 8 GA. >> >> A tricky problem to solve is where to get the APIs for platform N. The >> proposal is to include history data in the textual format inside the >> OpenJDK repositories (the input data), process them at build time and >> create a lib/ct.sym file holding the data in the JDK image. javac >> running with the -platform option then compiles against the lib/ct.sym >> file. The input history data are placed >> /make/data/symbols (the sym.txt files). This >> patches only includes data for OpenJDK 7 and 8, and only for public >> APIs (more or less Java SE and JDK @Exported APIs). >> >> The size of the history data is currently ~6MB in the JDK checkout and >> ~650kB inside the .hg directory (the size could change significantly >> if additional classes/elements, like non-public API classes, would >> need to be included). The lib/ct.sym file is currently ~4.5MB. >> >> The ct.sym file is a zip file containing signature files. The >> signature files are similar to classfiles (so javac can read them as >> classfiles), but are missing some attributes, most notably the Code >> attribute. On the top-level, the ct.sym contains directories named >> "7", "78" and "8". When compiling for version 'N', the bootclasspath >> for that version is obtained by using directories which have 'N' in >> their name. >> >> The sigfiles for ct.sym are created by >> /make/tools/symbolgenerator/CreateSymbols.java. >> The same file can also be used to construct the sym.txt files. Concise >> instructions are part of the CreateSymbols.java. >> >> I am sending this as one review, as the changes together make one >> feature, but the langtools and top-level changes are independent to a >> great degree: the langtools changes add the "-platform" javac; and the >> top-level changes add the history data and ability to build the ct.sym >> file. If desired, these could be pushed and/or reviewed independently. >> >> Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan >> Bateman and others who have provided advices and help on the matter >> before. >> >> Any insights/comments are wholeheartedly welcome. >> >> Thanks, >> Jan > From jan.lahoda at oracle.com Thu May 21 11:58:27 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Thu, 21 May 2015 13:58:27 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555DBFB5.4090206@oracle.com> References: <555D82CC.9070105@oracle.com> <555DA88C.1080206@oracle.com> <555DBFB5.4090206@oracle.com> Message-ID: <555DC863.4050703@oracle.com> Hi Magnus, On 21.5.2015 13:21, Magnus Ihse Bursie wrote: > Hi Erik and Jan, > > Erik's modifications look much better to me. > > I'm just not entirerly satisfied with how this new symbolgenerator tool > fits int our model. It's really a buildtool, similar to the other > buildtools we have. > > First of all, the location is not really ideal. Compare with how the > java build tools are stored, e.g. > jdk/make/src/classes/build/tools/charsetmapping. Correspondingly, I > believe the symbolgenerator should live in > $TOP/make/src/classes/build/tools/symbolgenerator. This makes it clear > that it's source code, leaves room for native build tools, and sets up a > common package prefix (while build.tools. might not be ideal, it's > the same as in the JDK build tools, so let's keep it). Sure - I'll move it. Thanks, Jan > > Second, and this is more of a open question, mostly directed at Erik, > shouldn't we build the symbolgenerator tool at the buildtools phase? It > might require slightly more work to adapt the buildtools system for the > top level, but I believe it is much more in line with what we got. > > /Magnus > > On 2015-05-21 11:42, Erik Joelsson wrote: >> Hello Jan, >> >> On the build changes there are some things I would like to change. >> >> * The creation of the ct.sym file should be done in a separate file, >> with a separate top level target. The images target should just be >> about linking and pulling things together, not actual >> building/compiling of things. >> * The calls to MakeDir are not needed. >> * There are missing prerequisites in the rule for creating the symbols. >> * The jar file creation should use the SetupArchive macro. >> * Intermediate build files should be put into the $(SUPPORT_OUTPUTDIR). >> * I think it makes sense to have the ct.sym file be part of the >> exploded-image. >> >> Since this was quite a lot of changes, I took the liberty of >> implementing them. Here is a webrev with my suggestion for build changes: >> >> http://cr.openjdk.java.net/~erikj/8072480/webrev.01/ >> >> /Erik >> >> On 2015-05-21 09:01, Jan Lahoda wrote: >>> Hi, >>> >>> This is a patch adding a new option, -platform, to javac. >>> >>> Patch for the top-level repository is here: >>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >>> >>> Patch for the langtools repository is here: >>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >>> >>> These changes also require additional langtools changes as their >>> prerequisite: >>> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ >>> >>> Overall, one can imagine '-platform N' to have the same effect as >>> '-source N -target N -bootclasspath '. The possible >>> values for 'N' are pluggable in a limited way, though (see >>> langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). >>> Note that this patch only introduces N=7 and N=8, which correspond to >>> Open JDK 7 and 8 GA. >>> >>> A tricky problem to solve is where to get the APIs for platform N. >>> The proposal is to include history data in the textual format inside >>> the OpenJDK repositories (the input data), process them at build time >>> and create a lib/ct.sym file holding the data in the JDK image. javac >>> running with the -platform option then compiles against the >>> lib/ct.sym file. The input history data are placed >>> /make/data/symbols (the sym.txt files). This >>> patches only includes data for OpenJDK 7 and 8, and only for public >>> APIs (more or less Java SE and JDK @Exported APIs). >>> >>> The size of the history data is currently ~6MB in the JDK checkout >>> and ~650kB inside the .hg directory (the size could change >>> significantly if additional classes/elements, like non-public API >>> classes, would need to be included). The lib/ct.sym file is currently >>> ~4.5MB. >>> >>> The ct.sym file is a zip file containing signature files. The >>> signature files are similar to classfiles (so javac can read them as >>> classfiles), but are missing some attributes, most notably the Code >>> attribute. On the top-level, the ct.sym contains directories named >>> "7", "78" and "8". When compiling for version 'N', the bootclasspath >>> for that version is obtained by using directories which have 'N' in >>> their name. >>> >>> The sigfiles for ct.sym are created by >>> /make/tools/symbolgenerator/CreateSymbols.java. >>> The same file can also be used to construct the sym.txt files. >>> Concise instructions are part of the CreateSymbols.java. >>> >>> I am sending this as one review, as the changes together make one >>> feature, but the langtools and top-level changes are independent to a >>> great degree: the langtools changes add the "-platform" javac; and >>> the top-level changes add the history data and ability to build the >>> ct.sym file. If desired, these could be pushed and/or reviewed >>> independently. >>> >>> Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan >>> Bateman and others who have provided advices and help on the matter >>> before. >>> >>> Any insights/comments are wholeheartedly welcome. >>> >>> Thanks, >>> Jan >> > From maurizio.cimadamore at oracle.com Thu May 21 12:14:19 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 21 May 2015 13:14:19 +0100 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555DC611.5000702@oracle.com> References: <555D82CC.9070105@oracle.com> <555DB419.6020301@oracle.com> <555DC611.5000702@oracle.com> Message-ID: <555DCC1B.4030902@oracle.com> On 21/05/15 12:48, Jan Lahoda wrote: > As an example, consider we would be currently storing data for 6, 7 > and 8. We could have full 8 APIs stored, and then 8->7 diff and 7->6 > diff. So the baseline for 7 would be 8 and the baseline for 6 would be 7. > > When the data for 9 would be added(*), we could keep the full APIs for > 8 (to avoid wasting space in the repository), and then store 8->9 and > 8->7 diffs (and drop 6). So 8 would be the baseline for both 7 and 9. > So, some flexibility may be useful here. > > Does this make some sense? It seems to me that versions form a total order. If you pick N to be your baseline, you should generate a full API for that K, and then generate incremental diffs for K < N and K > N - example: case 1: platforms: { 6, 7, 8 } baseline = 8 files: 8, 8->7, 7->6 case 2: platforms { 7, 8, 9 } baseline = 8 files: 8->9, 8, 8->7 So, can't we just assume that there's a set of platforms (which can be sorted), and a baseline K pointing at one of them? Then it's easy to figure out how you should generate diffs: sym(N) := , where N == K sym(N) := diff between sym(N-1) and N, where N > K sym(N) := diff between N and sym(N + 1), where N < K Maurizio From aleksey.shipilev at oracle.com Thu May 21 12:15:09 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Thu, 21 May 2015 15:15:09 +0300 Subject: String concatenation tweaks In-Reply-To: <55551C6F.4000704@oracle.com> References: <55014F7C.20201@oracle.com> <553139FA.20601@oracle.com> <55313D3A.10008@univ-mlv.fr> <55551C6F.4000704@oracle.com> Message-ID: <555DCC4D.8040505@oracle.com> On 05/15/2015 01:06 AM, Aleksey Shipilev wrote: > It actually does not seem that scary. javac changes seem minimal, > because they basically mirror [1] what is already done for current > String concat and lambda desugaring. > > JDK side of changes is not too scary as well [2], and it readily lends > itself to different implementation strategies, including precomputing > the argument lengths. I realized too late it does not check for argument > nullity properly, but this is a proof-of-concept patch anyway. Updated patches: http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/ INNER_SIZED strategy is enabled by default for everything except java.base. This, and a few other touchups make the patched JDK to build cleanly, and pass the most java/lang and java/util jtreg tests (there are seem to be some failures in Indify-based tests). Thanks, -Aleksey -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From jan.lahoda at oracle.com Thu May 21 13:14:47 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Thu, 21 May 2015 15:14:47 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555DCC1B.4030902@oracle.com> References: <555D82CC.9070105@oracle.com> <555DB419.6020301@oracle.com> <555DC611.5000702@oracle.com> <555DCC1B.4030902@oracle.com> Message-ID: <555DDA47.9060403@oracle.com> On 21.5.2015 14:14, Maurizio Cimadamore wrote: > > > On 21/05/15 12:48, Jan Lahoda wrote: >> As an example, consider we would be currently storing data for 6, 7 >> and 8. We could have full 8 APIs stored, and then 8->7 diff and 7->6 >> diff. So the baseline for 7 would be 8 and the baseline for 6 would be 7. >> >> When the data for 9 would be added(*), we could keep the full APIs for >> 8 (to avoid wasting space in the repository), and then store 8->9 and >> 8->7 diffs (and drop 6). So 8 would be the baseline for both 7 and 9. >> So, some flexibility may be useful here. >> >> Does this make some sense? > It seems to me that versions form a total order. If you pick N to be > your baseline, you should generate a full API for that K, and then > generate incremental diffs for K < N and K > N - example: > > case 1: > > platforms: { 6, 7, 8 } > baseline = 8 > > files: 8, 8->7, 7->6 > > case 2: > > platforms { 7, 8, 9 } > baseline = 8 > > files: 8->9, 8, 8->7 > > So, can't we just assume that there's a set of platforms (which can be > sorted), and a baseline K pointing at one of them? Then it's easy to > figure out how you should generate diffs: > > sym(N) := , where N == K > sym(N) := diff between sym(N-1) and N, where N > K > sym(N) := diff between N and sym(N + 1), where N < K For 6, 7, 8, ... we could assume there is an ordering. But seems to me that the flexibility of being able to specify the baseline (rather than having the chosen automatically based on the version number) is not bad. But I can change it to automatic baseline per the design above, if you prefer. Thanks, Jan > > Maurizio From konstantin.barzilovich at oracle.com Thu May 21 13:20:56 2015 From: konstantin.barzilovich at oracle.com (konstantin barzilovich) Date: Thu, 21 May 2015 16:20:56 +0300 Subject: jls overridding description In-Reply-To: <7AD00602-116A-4831-A8E0-5B547B6B66B5@oracle.com> References: <554A32E5.9080304@oracle.com> <9EC63542-0F62-4DFD-BCCB-BD8814DCB5D2@oracle.com> <555C8B0E.7010609@oracle.com> <7AD00602-116A-4831-A8E0-5B547B6B66B5@oracle.com> Message-ID: <555DDBB8.90601@oracle.com> Hello, It was interesting example. I didn't think about this. Now I see that both conditions are required. Thanks for clarification, Konstantin. On 20.05.2015 18:50, Dan Smith wrote: >> On May 20, 2015, at 7:24 AM, konstantin barzilovich wrote: >> >> Hello, >> >> Thank you for the answer. >> As I understand, you said that jls-8.4.8.1-100-B can be false while jls-8.4.8.1-100-C is true. > Right: you can have mC with a subsignature of mA, but still inherit mA. > >> But is it possible that jls-8.4.8.1-100-C is false while jls-8.4.8.1-100-B is true? (the opposite situation) > Can you not inherit mA, but choose an mC that does not have a subsignature of mA? Sure. Note that the selection of mA and mC is pretty unrestricted -- this subsignature clause it what limits the set of methods to things you'd intuitively expect to consider. > > So, for example: > > public class A { > public void foo() {} // mA > } > > public class B { > public void bar(int arg) {} // mC > public void foo() {} > } > > Is A a superclass of C? Yep. Does C inherit mA? Nope -- the declaration of another 'foo' method prevents it. Is mA public? Yep. > > But mC definitely does not override mA. > > ?Dan From alexander.v.stepanov at oracle.com Thu May 21 16:12:43 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Thu, 21 May 2015 19:12:43 +0300 Subject: RFR [9] 8080880: some docs cleanup for langtools In-Reply-To: <555E02BE.7020407@oracle.com> References: <555E02BE.7020407@oracle.com> Message-ID: <555E03FB.40803@oracle.com> Hello, Could you please review the following fix http://cr.openjdk.java.net/~avstepan/8080880/webrev.00/ for https://bugs.openjdk.java.net/browse/JDK-8080880 Just some minor fix for docs, no other code touched. The affected packages should (probably) not be visible in the new modular system, but nevertheless... Thanks, Alexander From maurizio.cimadamore at oracle.com Thu May 21 17:38:52 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 21 May 2015 18:38:52 +0100 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555DDA47.9060403@oracle.com> References: <555D82CC.9070105@oracle.com> <555DB419.6020301@oracle.com> <555DC611.5000702@oracle.com> <555DCC1B.4030902@oracle.com> <555DDA47.9060403@oracle.com> Message-ID: <555E182C.1050806@oracle.com> On 21/05/15 14:14, Jan Lahoda wrote: > For 6, 7, 8, ... we could assume there is an ordering. But seems to me > that the flexibility of being able to specify the baseline (rather > than having the chosen automatically based on the version number) is > not bad. But I can change it to automatic baseline per the design > above, if you prefer. I guess it would be nice (as discussed privately) if a side-effect of this effort was also to specify which diff files are generated and how given a set of available platforms. Maurizio From jonathan.gibbons at oracle.com Thu May 21 18:56:12 2015 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Thu, 21 May 2015 11:56:12 -0700 Subject: RFR [9] 8080880: some docs cleanup for langtools In-Reply-To: <555E03FB.40803@oracle.com> References: <555E02BE.7020407@oracle.com> <555E03FB.40803@oracle.com> Message-ID: <555E2A4C.9010903@oracle.com> On 05/21/2015 09:12 AM, alexander stepanov wrote: > Hello, > > Could you please review the following fix > http://cr.openjdk.java.net/~avstepan/8080880/webrev.00/ > for > https://bugs.openjdk.java.net/browse/JDK-8080880 > > Just some minor fix for docs, no other code touched. > > The affected packages should (probably) not be visible in the new > modular system, but nevertheless... > > Thanks, > Alexander Alexander, It is not appropriate to do partial bulk update to the "not a supported API" comment at the head of the internal files. It is strongly preferred that this part of the comment remain consistent across all source files, so that it is amenable to bulk updates, should we wish to do so. I would suggest you separate the otherwise useful work to fix individual minor doc issues from any work involving the standard "not a supported API" comment at the head of each file. -- Jon From mark.reinhold at oracle.com Thu May 21 19:59:41 2015 From: mark.reinhold at oracle.com (mark.reinhold at oracle.com) Date: Thu, 21 May 2015 12:59:41 -0700 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555D82CC.9070105@oracle.com> References: <555D82CC.9070105@oracle.com> Message-ID: <20150521125941.1758@eggemoggin.niobe.net> 2015/5/21 12:01 -0700, jan.lahoda at oracle.com: > This is a patch adding a new option, -platform, to javac. > > Patch for the top-level repository is here: > http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ > > Patch for the langtools repository is here: > http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ > > These changes also require additional langtools changes as their > prerequisite: > http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ Nice work -- I'm glad to see this coming in. What's the rationale for putting the symbol generator and all its data in the top-level repo? That'll add quite a bit of heft to a repo that's always been intended to remain fairly lightweight. Wouldn't it make more sense for this code and data to be placed in the langtools repo? Or is there some sort of build-bootstrapping issue here? - Mark From erik.joelsson at oracle.com Fri May 22 06:49:47 2015 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Fri, 22 May 2015 08:49:47 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <20150521125941.1758@eggemoggin.niobe.net> References: <555D82CC.9070105@oracle.com> <20150521125941.1758@eggemoggin.niobe.net> Message-ID: <555ED18B.8060802@oracle.com> On 2015-05-21 21:59, mark.reinhold at oracle.com wrote: > 2015/5/21 12:01 -0700, jan.lahoda at oracle.com: >> This is a patch adding a new option, -platform, to javac. >> >> Patch for the top-level repository is here: >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >> >> Patch for the langtools repository is here: >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >> >> These changes also require additional langtools changes as their >> prerequisite: >> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ > Nice work -- I'm glad to see this coming in. > > What's the rationale for putting the symbol generator and all its data > in the top-level repo? That'll add quite a bit of heft to a repo that's > always been intended to remain fairly lightweight. Wouldn't it make > more sense for this code and data to be placed in the langtools repo? > Or is there some sort of build-bootstrapping issue here? Technically these files could go in any repo, it's only a question of where they best fit from a logical/maintaining point of view. I had not thought about the langtools repo before, I just thought that it didn't fit in the jdk repo so better put it in the top as it applies to all modules. But the user of this data is the compiler so langtools does make sense. /Erik From jan.lahoda at oracle.com Fri May 22 07:20:16 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Fri, 22 May 2015 09:20:16 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555ED18B.8060802@oracle.com> References: <555D82CC.9070105@oracle.com> <20150521125941.1758@eggemoggin.niobe.net> <555ED18B.8060802@oracle.com> Message-ID: <555ED8B0.2030409@oracle.com> On 22.5.2015 08:49, Erik Joelsson wrote: > > On 2015-05-21 21:59, mark.reinhold at oracle.com wrote: >> 2015/5/21 12:01 -0700, jan.lahoda at oracle.com: >>> This is a patch adding a new option, -platform, to javac. >>> >>> Patch for the top-level repository is here: >>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >>> >>> Patch for the langtools repository is here: >>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >>> >>> These changes also require additional langtools changes as their >>> prerequisite: >>> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ >> Nice work -- I'm glad to see this coming in. >> >> What's the rationale for putting the symbol generator and all its data >> in the top-level repo? That'll add quite a bit of heft to a repo that's >> always been intended to remain fairly lightweight. Wouldn't it make >> more sense for this code and data to be placed in the langtools repo? >> Or is there some sort of build-bootstrapping issue here? > Technically these files could go in any repo, it's only a question of > where they best fit from a logical/maintaining point of view. I had not > thought about the langtools repo before, I just thought that it didn't > fit in the jdk repo so better put it in the top as it applies to all > modules. But the user of this data is the compiler so langtools does > make sense. There has been a brief discussion on which repo to use some time ago, and top-level repo seemed reasonable. I am personally fine with the langtools repo, if that's preferred. (Langtools repo is often cloned and used standalone, so these standalone checkouts would be bigger, but probably not a big problem.) Thanks, Jan > > /Erik > From forax at univ-mlv.fr Fri May 22 07:59:12 2015 From: forax at univ-mlv.fr (=?ISO-8859-1?Q?R=E9mi_Forax?=) Date: Fri, 22 May 2015 07:59:12 +0000 Subject: String concatenation tweaks In-Reply-To: <555DCC4D.8040505@oracle.com> References: <55014F7C.20201@oracle.com> <553139FA.20601@oracle.com> <55313D3A.10008@univ-mlv.fr> <55551C6F.4000704@oracle.com> <555DCC4D.8040505@oracle.com> Message-ID: <7CDF6C9C-90CE-4D93-9290-10D9CCC29BB9@univ-mlv.fr> Nice patch. I think you don't need to generate an inner class because you can use MethodHandles.foldArguments with a combiner that calculate the size and a target method that calls StringBuilder::new and append on each argument. I will write a code example for that during the week end. regards, R?mi Le 21 mai 2015 14:15:09 CEST, Aleksey Shipilev a ?crit : >On 05/15/2015 01:06 AM, Aleksey Shipilev wrote: >> It actually does not seem that scary. javac changes seem minimal, >> because they basically mirror [1] what is already done for current >> String concat and lambda desugaring. >> >> JDK side of changes is not too scary as well [2], and it readily >lends >> itself to different implementation strategies, including precomputing >> the argument lengths. I realized too late it does not check for >argument >> nullity properly, but this is a proof-of-concept patch anyway. > >Updated patches: > http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/ > >INNER_SIZED strategy is enabled by default for everything except >java.base. This, and a few other touchups make the patched JDK to build >cleanly, and pass the most java/lang and java/util jtreg tests (there >are seem to be some failures in Indify-based tests). > >Thanks, >-Aleksey From aleksey.shipilev at oracle.com Fri May 22 08:29:43 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Fri, 22 May 2015 11:29:43 +0300 Subject: String concatenation tweaks In-Reply-To: <7CDF6C9C-90CE-4D93-9290-10D9CCC29BB9@univ-mlv.fr> References: <55014F7C.20201@oracle.com> <553139FA.20601@oracle.com> <55313D3A.10008@univ-mlv.fr> <55551C6F.4000704@oracle.com> <555DCC4D.8040505@oracle.com> <7CDF6C9C-90CE-4D93-9290-10D9CCC29BB9@univ-mlv.fr> Message-ID: <555EE8F7.5040007@oracle.com> On 22.05.2015 10:59, R?mi Forax wrote: > Nice patch. I think you don't need to generate an inner class because > you can use MethodHandles.foldArguments with a combiner that > calculate the size and a target method that calls StringBuilder::new > and append on each argument. I will write a code example for that > during the week end. Thanks Remi! Yes, inner classes seem to be the necessary evil when you need to generate "just" a single method. Our saving grace here is that we only need to do this for one "shape" of concat, and there are seem to be only handful in a given application. I agree that doing that purely on MHs would be cleaner, but I have my doubts about the performance of it. Let's see! -Aleksey. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From alexander.v.stepanov at oracle.com Fri May 22 10:14:41 2015 From: alexander.v.stepanov at oracle.com (alexander stepanov) Date: Fri, 22 May 2015 13:14:41 +0300 Subject: RFR [9] 8080880: some docs cleanup for langtools In-Reply-To: <555E2A4C.9010903@oracle.com> References: <555E02BE.7020407@oracle.com> <555E03FB.40803@oracle.com> <555E2A4C.9010903@oracle.com> Message-ID: <555F0191.1010609@oracle.com> Hello Jonathan, Thanks. > It is not appropriate to do partial bulk update to the "not a supported API" The responding changes were reverted, please see http://cr.openjdk.java.net/~avstepan/8080880/webrev.01/ Regards, Alexander On 21.05.2015 21:56, Jonathan Gibbons wrote: > > On 05/21/2015 09:12 AM, alexander stepanov wrote: >> Hello, >> >> Could you please review the following fix >> http://cr.openjdk.java.net/~avstepan/8080880/webrev.00/ >> for >> https://bugs.openjdk.java.net/browse/JDK-8080880 >> >> Just some minor fix for docs, no other code touched. >> >> The affected packages should (probably) not be visible in the new >> modular system, but nevertheless... >> >> Thanks, >> Alexander > > Alexander, > > It is not appropriate to do partial bulk update to the "not a > supported API" > comment at the head of the internal files. It is strongly preferred > that this > part of the comment remain consistent across all source files, so that > it is > amenable to bulk updates, should we wish to do so. > > I would suggest you separate the otherwise useful work to fix individual > minor doc issues from any work involving the standard "not a supported > API" comment at the head of each file. > > -- Jon From jan.lahoda at oracle.com Fri May 22 12:38:06 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Fri, 22 May 2015 14:38:06 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555DB419.6020301@oracle.com> References: <555D82CC.9070105@oracle.com> <555DB419.6020301@oracle.com> Message-ID: <555F232E.1060105@oracle.com> Hi, I've uploaded a new iteration of the patch(es): top-level repository: http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/top-level/ langtools: http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/langtools/ (besides full webrevs, there are also webrevs showing the differences between .00 and .01 available - see the "Delta webrev" link under "Author's comments") Summary of changes: -applied Eric's build changes -moved CreateSymbols into make/src/classes/build/tools/symbolgenerator -tried to improve the specification of base platforms in CreateSymbols, per Maurizio's comment -other cleanup in langtools per Maurizio's comments. Thanks, Jan On 21.5.2015 12:31, Maurizio Cimadamore wrote: > Hi Jan, > great work - couple of comments below: > > * it seems like some of the routines in Arguments can be simplified > using lambdas - especially lookupPlatformProvider and checkOptionAllowed > * Why JDKPlatformProvider is not called JDKPlatformProvider*Factory* ? > * JavacProcessingEnvironment.JoiningIterator seems to have commonalities > with CompoundScopeIterator - any chance that we might refactor this a bit? > * What's the rationale for giving an error if -platform is specified and > a non-StandardFileManager is provided? Can't we simply swallow that, > ignore the platform settings and issue a Lint 'options' warning? > * Would it make sense for some of the classfile generation logic in > CreateSymbols to be moved under the classfile API ? > * I had hard time reconciling some of the comments in CreateSymbols with > how the files were laid out. I think in the end, what you mean is that > if you have platforms 7, 8, 9 - you should pick one baseline (i.e. 8) > and then generate diffs for 9 and 7 against the 8 one. If that's the use > case, I think the command line can be simplified a bit in order to > explicitly state which of the platform is the baseline one, and the > remaining parameters can be inferred from the tool (as the > seem to be typically all identical > but one which is set to - the one for the baseline). Maybe the > inference logic should be different (i.e. use 8 as a baseline for 7 and > 7 as a baseline for 6) - but - whatever the logic, I think it should be > chosen once and for all, and live implicitly in the tool? Or are there > reasons as to why it might be handy to customize the baselines? > > Maurizio > > On 21/05/15 08:01, Jan Lahoda wrote: >> Hi, >> >> This is a patch adding a new option, -platform, to javac. >> >> Patch for the top-level repository is here: >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >> >> Patch for the langtools repository is here: >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >> >> These changes also require additional langtools changes as their >> prerequisite: >> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ >> >> Overall, one can imagine '-platform N' to have the same effect as >> '-source N -target N -bootclasspath '. The possible values >> for 'N' are pluggable in a limited way, though (see >> langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). >> Note that this patch only introduces N=7 and N=8, which correspond to >> Open JDK 7 and 8 GA. >> >> A tricky problem to solve is where to get the APIs for platform N. The >> proposal is to include history data in the textual format inside the >> OpenJDK repositories (the input data), process them at build time and >> create a lib/ct.sym file holding the data in the JDK image. javac >> running with the -platform option then compiles against the lib/ct.sym >> file. The input history data are placed >> /make/data/symbols (the sym.txt files). This >> patches only includes data for OpenJDK 7 and 8, and only for public >> APIs (more or less Java SE and JDK @Exported APIs). >> >> The size of the history data is currently ~6MB in the JDK checkout and >> ~650kB inside the .hg directory (the size could change significantly >> if additional classes/elements, like non-public API classes, would >> need to be included). The lib/ct.sym file is currently ~4.5MB. >> >> The ct.sym file is a zip file containing signature files. The >> signature files are similar to classfiles (so javac can read them as >> classfiles), but are missing some attributes, most notably the Code >> attribute. On the top-level, the ct.sym contains directories named >> "7", "78" and "8". When compiling for version 'N', the bootclasspath >> for that version is obtained by using directories which have 'N' in >> their name. >> >> The sigfiles for ct.sym are created by >> /make/tools/symbolgenerator/CreateSymbols.java. >> The same file can also be used to construct the sym.txt files. Concise >> instructions are part of the CreateSymbols.java. >> >> I am sending this as one review, as the changes together make one >> feature, but the langtools and top-level changes are independent to a >> great degree: the langtools changes add the "-platform" javac; and the >> top-level changes add the history data and ability to build the ct.sym >> file. If desired, these could be pushed and/or reviewed independently. >> >> Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan >> Bateman and others who have provided advices and help on the matter >> before. >> >> Any insights/comments are wholeheartedly welcome. >> >> Thanks, >> Jan > From maurizio.cimadamore at oracle.com Fri May 22 12:52:34 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 22 May 2015 13:52:34 +0100 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555F232E.1060105@oracle.com> References: <555D82CC.9070105@oracle.com> <555DB419.6020301@oracle.com> <555F232E.1060105@oracle.com> Message-ID: <555F2692.5030002@oracle.com> Excellent work. I think the comment in CreateSymbols could be made clearer w.r.t. Probe - i.e. that Probe should be ran on top of the JDK N - i.e. /bin/java Probe --> classes-8 /bin/java Probe --> classes-7 /bin/java Probe --> classes-7 etc. Maurizio On 22/05/15 13:38, Jan Lahoda wrote: > Hi, > > I've uploaded a new iteration of the patch(es): > top-level repository: > http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/top-level/ > langtools: > http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/langtools/ > > (besides full webrevs, there are also webrevs showing the differences > between .00 and .01 available - see the "Delta webrev" link under > "Author's comments") > > Summary of changes: > -applied Eric's build changes > -moved CreateSymbols into make/src/classes/build/tools/symbolgenerator > -tried to improve the specification of base platforms in > CreateSymbols, per Maurizio's comment > -other cleanup in langtools per Maurizio's comments. > > Thanks, > Jan > > On 21.5.2015 12:31, Maurizio Cimadamore wrote: >> Hi Jan, >> great work - couple of comments below: >> >> * it seems like some of the routines in Arguments can be simplified >> using lambdas - especially lookupPlatformProvider and checkOptionAllowed >> * Why JDKPlatformProvider is not called JDKPlatformProvider*Factory* ? >> * JavacProcessingEnvironment.JoiningIterator seems to have commonalities >> with CompoundScopeIterator - any chance that we might refactor this a >> bit? >> * What's the rationale for giving an error if -platform is specified and >> a non-StandardFileManager is provided? Can't we simply swallow that, >> ignore the platform settings and issue a Lint 'options' warning? >> * Would it make sense for some of the classfile generation logic in >> CreateSymbols to be moved under the classfile API ? >> * I had hard time reconciling some of the comments in CreateSymbols with >> how the files were laid out. I think in the end, what you mean is that >> if you have platforms 7, 8, 9 - you should pick one baseline (i.e. 8) >> and then generate diffs for 9 and 7 against the 8 one. If that's the use >> case, I think the command line can be simplified a bit in order to >> explicitly state which of the platform is the baseline one, and the >> remaining parameters can be inferred from the tool (as the >> seem to be typically all identical >> but one which is set to - the one for the baseline). Maybe the >> inference logic should be different (i.e. use 8 as a baseline for 7 and >> 7 as a baseline for 6) - but - whatever the logic, I think it should be >> chosen once and for all, and live implicitly in the tool? Or are there >> reasons as to why it might be handy to customize the baselines? >> >> Maurizio >> >> On 21/05/15 08:01, Jan Lahoda wrote: >>> Hi, >>> >>> This is a patch adding a new option, -platform, to javac. >>> >>> Patch for the top-level repository is here: >>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >>> >>> Patch for the langtools repository is here: >>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >>> >>> These changes also require additional langtools changes as their >>> prerequisite: >>> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ >>> >>> Overall, one can imagine '-platform N' to have the same effect as >>> '-source N -target N -bootclasspath '. The possible values >>> for 'N' are pluggable in a limited way, though (see >>> langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). >>> >>> Note that this patch only introduces N=7 and N=8, which correspond to >>> Open JDK 7 and 8 GA. >>> >>> A tricky problem to solve is where to get the APIs for platform N. The >>> proposal is to include history data in the textual format inside the >>> OpenJDK repositories (the input data), process them at build time and >>> create a lib/ct.sym file holding the data in the JDK image. javac >>> running with the -platform option then compiles against the lib/ct.sym >>> file. The input history data are placed >>> /make/data/symbols (the sym.txt files). This >>> patches only includes data for OpenJDK 7 and 8, and only for public >>> APIs (more or less Java SE and JDK @Exported APIs). >>> >>> The size of the history data is currently ~6MB in the JDK checkout and >>> ~650kB inside the .hg directory (the size could change significantly >>> if additional classes/elements, like non-public API classes, would >>> need to be included). The lib/ct.sym file is currently ~4.5MB. >>> >>> The ct.sym file is a zip file containing signature files. The >>> signature files are similar to classfiles (so javac can read them as >>> classfiles), but are missing some attributes, most notably the Code >>> attribute. On the top-level, the ct.sym contains directories named >>> "7", "78" and "8". When compiling for version 'N', the bootclasspath >>> for that version is obtained by using directories which have 'N' in >>> their name. >>> >>> The sigfiles for ct.sym are created by >>> /make/tools/symbolgenerator/CreateSymbols.java. >>> The same file can also be used to construct the sym.txt files. Concise >>> instructions are part of the CreateSymbols.java. >>> >>> I am sending this as one review, as the changes together make one >>> feature, but the langtools and top-level changes are independent to a >>> great degree: the langtools changes add the "-platform" javac; and the >>> top-level changes add the history data and ability to build the ct.sym >>> file. If desired, these could be pushed and/or reviewed independently. >>> >>> Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan >>> Bateman and others who have provided advices and help on the matter >>> before. >>> >>> Any insights/comments are wholeheartedly welcome. >>> >>> Thanks, >>> Jan >> From jan.lahoda at oracle.com Fri May 22 13:22:39 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Fri, 22 May 2015 15:22:39 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555F2692.5030002@oracle.com> References: <555D82CC.9070105@oracle.com> <555DB419.6020301@oracle.com> <555F232E.1060105@oracle.com> <555F2692.5030002@oracle.com> Message-ID: <555F2D9F.2090505@oracle.com> On 22.5.2015 14:52, Maurizio Cimadamore wrote: > Excellent work. > > I think the comment in CreateSymbols could be made clearer w.r.t. Probe > - i.e. that Probe should be ran on top of the JDK N - i.e. > > /bin/java Probe --> classes-8 > /bin/java Probe --> classes-7 > /bin/java Probe --> classes-7 > > etc. Sure, will do. I'll also look at generating the make/data/symbols/symbols descriptions automatically, per our offline discussion. Thanks! Jan > > Maurizio > > On 22/05/15 13:38, Jan Lahoda wrote: >> Hi, >> >> I've uploaded a new iteration of the patch(es): >> top-level repository: >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/top-level/ >> langtools: >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/langtools/ >> >> (besides full webrevs, there are also webrevs showing the differences >> between .00 and .01 available - see the "Delta webrev" link under >> "Author's comments") >> >> Summary of changes: >> -applied Eric's build changes >> -moved CreateSymbols into make/src/classes/build/tools/symbolgenerator >> -tried to improve the specification of base platforms in >> CreateSymbols, per Maurizio's comment >> -other cleanup in langtools per Maurizio's comments. >> >> Thanks, >> Jan >> >> On 21.5.2015 12:31, Maurizio Cimadamore wrote: >>> Hi Jan, >>> great work - couple of comments below: >>> >>> * it seems like some of the routines in Arguments can be simplified >>> using lambdas - especially lookupPlatformProvider and checkOptionAllowed >>> * Why JDKPlatformProvider is not called JDKPlatformProvider*Factory* ? >>> * JavacProcessingEnvironment.JoiningIterator seems to have commonalities >>> with CompoundScopeIterator - any chance that we might refactor this a >>> bit? >>> * What's the rationale for giving an error if -platform is specified and >>> a non-StandardFileManager is provided? Can't we simply swallow that, >>> ignore the platform settings and issue a Lint 'options' warning? >>> * Would it make sense for some of the classfile generation logic in >>> CreateSymbols to be moved under the classfile API ? >>> * I had hard time reconciling some of the comments in CreateSymbols with >>> how the files were laid out. I think in the end, what you mean is that >>> if you have platforms 7, 8, 9 - you should pick one baseline (i.e. 8) >>> and then generate diffs for 9 and 7 against the 8 one. If that's the use >>> case, I think the command line can be simplified a bit in order to >>> explicitly state which of the platform is the baseline one, and the >>> remaining parameters can be inferred from the tool (as the >>> seem to be typically all identical >>> but one which is set to - the one for the baseline). Maybe the >>> inference logic should be different (i.e. use 8 as a baseline for 7 and >>> 7 as a baseline for 6) - but - whatever the logic, I think it should be >>> chosen once and for all, and live implicitly in the tool? Or are there >>> reasons as to why it might be handy to customize the baselines? >>> >>> Maurizio >>> >>> On 21/05/15 08:01, Jan Lahoda wrote: >>>> Hi, >>>> >>>> This is a patch adding a new option, -platform, to javac. >>>> >>>> Patch for the top-level repository is here: >>>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >>>> >>>> Patch for the langtools repository is here: >>>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >>>> >>>> These changes also require additional langtools changes as their >>>> prerequisite: >>>> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ >>>> >>>> Overall, one can imagine '-platform N' to have the same effect as >>>> '-source N -target N -bootclasspath '. The possible values >>>> for 'N' are pluggable in a limited way, though (see >>>> langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). >>>> >>>> Note that this patch only introduces N=7 and N=8, which correspond to >>>> Open JDK 7 and 8 GA. >>>> >>>> A tricky problem to solve is where to get the APIs for platform N. The >>>> proposal is to include history data in the textual format inside the >>>> OpenJDK repositories (the input data), process them at build time and >>>> create a lib/ct.sym file holding the data in the JDK image. javac >>>> running with the -platform option then compiles against the lib/ct.sym >>>> file. The input history data are placed >>>> /make/data/symbols (the sym.txt files). This >>>> patches only includes data for OpenJDK 7 and 8, and only for public >>>> APIs (more or less Java SE and JDK @Exported APIs). >>>> >>>> The size of the history data is currently ~6MB in the JDK checkout and >>>> ~650kB inside the .hg directory (the size could change significantly >>>> if additional classes/elements, like non-public API classes, would >>>> need to be included). The lib/ct.sym file is currently ~4.5MB. >>>> >>>> The ct.sym file is a zip file containing signature files. The >>>> signature files are similar to classfiles (so javac can read them as >>>> classfiles), but are missing some attributes, most notably the Code >>>> attribute. On the top-level, the ct.sym contains directories named >>>> "7", "78" and "8". When compiling for version 'N', the bootclasspath >>>> for that version is obtained by using directories which have 'N' in >>>> their name. >>>> >>>> The sigfiles for ct.sym are created by >>>> /make/tools/symbolgenerator/CreateSymbols.java. >>>> The same file can also be used to construct the sym.txt files. Concise >>>> instructions are part of the CreateSymbols.java. >>>> >>>> I am sending this as one review, as the changes together make one >>>> feature, but the langtools and top-level changes are independent to a >>>> great degree: the langtools changes add the "-platform" javac; and the >>>> top-level changes add the history data and ability to build the ct.sym >>>> file. If desired, these could be pushed and/or reviewed independently. >>>> >>>> Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan >>>> Bateman and others who have provided advices and help on the matter >>>> before. >>>> >>>> Any insights/comments are wholeheartedly welcome. >>>> >>>> Thanks, >>>> Jan >>> > From daniel.smith at oracle.com Fri May 22 22:20:11 2015 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 22 May 2015 16:20:11 -0600 Subject: Call for Speakers -- 2015 JVM Language Summit In-Reply-To: References: Message-ID: <6FC0BD44-66FB-4C93-A10F-DA7DC33CC037@oracle.com> Reminder: last call for speaker submissions. General registration is also open. We've hit our initial allotment for early registration, but you can register as a "Wait List Attendee" to be notified when we increase the limit (should be soon). ?Dan > On Apr 15, 2015, at 11:02 AM, Dan Smith wrote: > > CALL FOR SPEAKERS -- JVM LANGUAGE SUMMIT, AUGUST 2015 > > We are pleased to announce the 2015 JVM Language Summit to be held at Oracle's Santa Clara campus on August 10-12, 2015. Registration is now open for speaker submissions (presentations and workshops) and will remain open until May 22, 2015. There is no registration fee for speakers. > > The JVM Language Summit is an open technical collaboration among language designers, compiler writers, tool builders, runtime engineers, and VM architects. We will share our experiences as creators of both the JVM and programming languages for the JVM. We also welcome non-JVM developers of similar technologies to attend or speak on their runtime, VM, or language of choice. > > Presentations will be recorded and made available to the public via the Oracle Technology Network. > > This event is being organized by language and JVM engineers; no marketers involved! So bring your slide rules and be prepared for some seriously geeky discussions. > > Format > > The summit is held in a single classroom-style room to support direct communication between participants. About 80-100 attendees are expected. > > As in previous years, we will divide the schedule between traditional presentations and "workshops." Workshops are informal, facilitated discussion groups among smaller, self-selected participants, and should enable deeper "dives" into the subject matter. If there is interest, there will also be impromptu "lightning talks." Traditional presentations (about 7 each day) will be given in a single track, while workshops (2?3 each day) will occur in parallel. > > Instructions for Speaker Registration > > If you'd like give a presentation or lead a workshop, please register as a Speaker and include a detailed abstract. There is no fee. You will be notified about whether your proposal has been accepted; if not, you will be able to register as a regular attendee. > > For a successful presentation or workshop submission, please note the following: > > - All talks should be deeply technical, given by designers and implementors to designers and implementors. We all speak Code here! > > - Each talk, we hope and expect, will inform the audience, in detail, about the state of the art of language design and implementation on the JVM, or will explore the present and future capabilities of the JVM itself. (Some will do so indirectly by discussing non-JVM technologies.) > > - Know your audience: attendees may not be likely to ever use your specific language or tool, but could learn something from your interactions with the JVM. A broad goal of the summit is to inspire us to work together on JVM-based technologies that enable a rich ecosystem at higher layers. > > We encourage speakers to submit both a presentation and a workshop; we will arrange to schedule the presentation before the workshop, so that the presentation can spark people's interest and the workshop will allow those who are really interested to go deeper into the subject area. Workshop facilitators may, but are not expected to, prepare presentation materials; in any case, they should come prepared to guide a deep technical discussion. > > To register: > http://regonline.com/jvmls2015 > > For further information: > http://jvmlangsummit.com > > Questions: > inquire at jvmlangsummit.com > > We hope to see you in August! From forax at univ-mlv.fr Sun May 24 15:33:06 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Sun, 24 May 2015 17:33:06 +0200 Subject: String concatenation tweaks In-Reply-To: <555EE8F7.5040007@oracle.com> References: <55014F7C.20201@oracle.com> <553139FA.20601@oracle.com> <55313D3A.10008@univ-mlv.fr> <55551C6F.4000704@oracle.com> <555DCC4D.8040505@oracle.com> <7CDF6C9C-90CE-4D93-9290-10D9CCC29BB9@univ-mlv.fr> <555EE8F7.5040007@oracle.com> Message-ID: <5561EF32.8080101@univ-mlv.fr> Here is my version (see at the end of this message). the code works that way, first, transform the values to String (masking null if necessary) if it's an Object or keep it if it's a primitive type. Then, if it's a String call String.length on it, if it's a primitive type, add 16 to the initial value and then sum all of the either values (by dropping the value that are primitive and hoping that the JIT is smart enough to unroll the loop that does the sum). Then the result of the sum is used to create the StringBuilder and the String or the primitive values are appended by calling append() on the StringBuilder, At the end, the StringBuilder is converted to a String which is returned. In the code, I use a lambda as a link list to register which parameter should be dropped or not. And I do a second for loop backward because the calls to append are done in reverse order. Technically, I can use a lambda too for this case and do the whole thing in one loop (the lambda will create a linked list that I will crawle recursively from the end to the beginning but I think the current code is more readable despite being slightly bigger in size. On 05/22/2015 10:29 AM, Aleksey Shipilev wrote: > On 22.05.2015 10:59, R?mi Forax wrote: >> Nice patch. I think you don't need to generate an inner class because >> you can use MethodHandles.foldArguments with a combiner that >> calculate the size and a target method that calls StringBuilder::new >> and append on each argument. I will write a code example for that >> during the week end. > Thanks Remi! > > Yes, inner classes seem to be the necessary evil when you need to > generate "just" a single method. Our saving grace here is that we only > need to do this for one "shape" of concat, and there are seem to be only > handful in a given application. I agree that doing that purely on MHs > would be cleaner, but I have my doubts about the performance of it. > Let's see! I hope that lambda forms will do the sharing. > > -Aleksey. > > R?mi /* * Copyright (c) 2012, 2015, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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. */ package java.lang.invoke; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Label; import jdk.internal.org.objectweb.asm.MethodVisitor; import jdk.internal.org.objectweb.asm.Opcodes; import opto_string_concat.StringConcatTestFactory; import sun.misc.Unsafe; import sun.security.action.GetPropertyAction; import java.lang.invoke.MethodHandles.Lookup; import java.security.AccessController; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.PropertyPermission; import java.util.concurrent.ConcurrentHashMap; import java.util.function.UnaryOperator; import static jdk.internal.org.objectweb.asm.Opcodes.*; /** * Generates the String concatenation stub. * * @author Aleksey Shipilev */ public class StringConcatFactory { private static final Strategy STRATEGY; private static final boolean DEBUG; private static final ProxyClassesDumper DUMPER; static { { final String key = "java.lang.invoke.stringConcat"; String str = AccessController.doPrivileged( new GetPropertyAction(key), null, new PropertyPermission(key, "read")); STRATEGY = (str == null) ? Strategy.INNER_SIZED : Strategy.valueOf(str); } { final String key = "java.lang.invoke.stringConcat.debug"; String str = AccessController.doPrivileged( new GetPropertyAction(key), null, new PropertyPermission(key, "read")); DEBUG = (str != null); } { final String key = "java.lang.invoke.stringConcat.dumpClasses"; String str = AccessController.doPrivileged( new GetPropertyAction(key), null, new PropertyPermission(key , "read")); DUMPER = (str == null) ? null : ProxyClassesDumper.getInstance(str); } } private enum Strategy { NAIVE_MH_FILTER, NAIVE_MH_FILTER_SIZED, INNER, INNER_SIZED, FULL_MH } private static final Map CACHE = new ConcurrentHashMap(); /** * Bootstrap method for javac-generated concat call. * * @param caller caller context * @param name ignored * @param args method arguments, in order * @return a callsite with actual method to concatenate strings * @throws Exception if something goes wrong */ public static CallSite stringConcat(MethodHandles.Lookup caller, String name, MethodType args) throws Exception { if (DEBUG) { System.out.print("StringConcatFactory "); System.out.print(STRATEGY); System.out.print(" is here for "); System.out.print(args); System.out.print(" "); } CallSite cs = CACHE.get(args); if (cs != null) { if (DEBUG) { System.out.println(" "); } } else { cs = generate(caller, args); CACHE.put(args, cs); if (DEBUG) { System.out.println(); } } return cs; } private static CallSite generate(MethodHandles.Lookup caller, MethodType args) throws Exception { switch (STRATEGY) { case NAIVE_MH_FILTER: return mhFiltered(caller, args, false); case NAIVE_MH_FILTER_SIZED: return mhFiltered(caller, args, true); case INNER: return innerClass(caller, args, false); case INNER_SIZED: return innerClass(caller, args, true); case FULL_MH: return mhFull(caller, args); default: throw new IllegalStateException("Not implemented yet: " + STRATEGY); } } /* ------------------------------------ Method handler adapters strategy ------------------------------------ */ private static CallSite mhFiltered(MethodHandles.Lookup caller, MethodType args, boolean sized) throws Exception { MethodHandle resultString = caller.findStatic( StringConcatFactory.class, (sized ? "concatNaiveSized" : "concatNaive"), MethodType.methodType(String.class, String[].class)); MethodHandle adapted = resultString.asCollector(String[].class, args.parameterCount()); // Adapt arguments, if needed: call String.valueOf on them. Class[] params = args.parameterArray(); for (int p = 0; p < params.length; p++) { if (params[p] != String.class) { MethodHandle valueOf = caller.findStatic( String.class, "valueOf", MethodType.methodType(String.class, params[p])); adapted = MethodHandles.filterArgument(adapted, p, valueOf); } } return new ConstantCallSite(adapted); } /** * Naive concatenation. * Argument conversion was already handled by the caller. * * @param args strings to concatenate * @return concatenated string */ public static String concatNaive(String[] args) { StringBuilder sb = new StringBuilder(); for (String s : args) { sb.append(s); } return sb.toString(); } /** * Naive concatenation + pre-sized StringBuilder * Argument conversion was already handled by the caller. * * @param args strings to concatenate * @return concatenated string */ public static String concatNaiveSized(String[] args) { int len = 0; for (String s : args) { len += s.length(); } StringBuilder sb = new StringBuilder(len); for (String s : args) { sb.append(s); } return sb.toString(); } /* ---------------------------------------- Inner class strategy -------------------------------------------- */ static final Unsafe UNSAFE = Unsafe.getUnsafe(); static final int CLASSFILE_VERSION = 52; static final String JAVA_LANG_OBJECT = "java/lang/Object"; static final String NAME_FACTORY = "concat"; static final String CLASS_NAME = "java/lang/String$Concat"; static final String NAME_CTOR = ""; static final String CLASS_STRING_BUILDER = "java/lang/StringBuilder"; static final String CLASS_STRING = "java/lang/String"; static final String SIG_TO_STRING = "()Ljava/lang/String;"; private static CallSite innerClass(MethodHandles.Lookup caller, MethodType args, boolean sized) { Class targetClass = caller.lookupClass(); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES); cw.visit(CLASSFILE_VERSION, ACC_SUPER + ACC_FINAL + ACC_SYNTHETIC, CLASS_NAME, null, JAVA_LANG_OBJECT, null ); MethodVisitor mv = cw.visitMethod( ACC_PUBLIC + ACC_STATIC + ACC_FINAL, NAME_FACTORY, args.toMethodDescriptorString(), null, null); mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true); mv.visitCode(); Class[] arr = args.parameterArray(); // In sized mode, it makes sense to make StringBuilder append chains look // familiar to OptimizeStringConcat. Therefore, we need to do null-checks // early. if (sized) { int off = 0; for (Class cl : arr) { if (cl == String.class) { Label l0 = new Label(); mv.visitIntInsn(ALOAD, off); mv.visitJumpInsn(IFNONNULL, l0); mv.visitLdcInsn("null"); mv.visitIntInsn(ASTORE, off); mv.visitLabel(l0); } off += getParameterSize(cl); } } // Prepare StringBuilder instance mv.visitTypeInsn(NEW, CLASS_STRING_BUILDER); mv.visitInsn(DUP); if (sized) { // Walk through the arguments, and try to estimate the final length int add = 0; mv.visitInsn(ICONST_0); int off = 0; for (Class cl : arr) { // TODO: For anything other than Strings and primitives, it makes sense to call String.valueOf first. if (cl == String.class) { mv.visitIntInsn(ALOAD, off); mv.visitMethodInsn( INVOKEVIRTUAL, CLASS_STRING, "length", "()I", false ); mv.visitInsn(IADD); } else if (cl.isPrimitive()) { // TODO: Consider a more accurate estimate for primitives. add += 16; } off += getParameterSize(cl); } if (add > 0) { iconst(mv, add); mv.visitInsn(IADD); } mv.visitMethodInsn( INVOKESPECIAL, CLASS_STRING_BUILDER, NAME_CTOR, "(I)V", false ); } else { mv.visitMethodInsn( INVOKESPECIAL, CLASS_STRING_BUILDER, NAME_CTOR, "()V", false ); } int off = 0; for (Class cl : arr) { mv.visitVarInsn(getLoadOpcode(cl), off); off += getParameterSize(cl); mv.visitMethodInsn( INVOKEVIRTUAL, CLASS_STRING_BUILDER, "append", getDesc(cl), false ); } mv.visitMethodInsn( INVOKEVIRTUAL, CLASS_STRING_BUILDER, "toString", SIG_TO_STRING, false ); mv.visitInsn(ARETURN); mv.visitMaxs(-1, -1); mv.visitEnd(); cw.visitEnd(); final byte[] classBytes = cw.toByteArray(); final Class innerClass = UNSAFE.defineAnonymousClass(targetClass, classBytes, null); if (DUMPER != null) { DUMPER.dumpClass(args.toString() + ".class", classBytes); } try { UNSAFE.ensureClassInitialized(innerClass); return new ConstantCallSite( MethodHandles.Lookup.IMPL_LOOKUP .findStatic(innerClass, NAME_FACTORY, args)); } catch (ReflectiveOperationException e) { throw new IllegalStateException("Exception finding constructor", e); } } private static String getDesc(Class cl) { if (cl.isPrimitive()) { if (cl == Integer.TYPE) { return "(I)Ljava/lang/StringBuilder;"; } else if (cl == Boolean.TYPE) { return "(Z)Ljava/lang/StringBuilder;"; } else if (cl == Byte.TYPE) { return "(B)Ljava/lang/StringBuilder;"; } else if (cl == Character.TYPE) { return "(C)Ljava/lang/StringBuilder;"; } else if (cl == Short.TYPE) { return "(S)Ljava/lang/StringBuilder;"; } else if (cl == Double.TYPE) { return "(D)Ljava/lang/StringBuilder;"; } else if (cl == Float.TYPE) { return "(F)Ljava/lang/StringBuilder;"; } else if (cl == Long.TYPE) { return "(J)Ljava/lang/StringBuilder;"; } else { throw new IllegalStateException(); } } else if (cl == String.class) { return "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; } else if (cl == StringBuffer.class) { return "(Ljava/util/StringBuffer;)Ljava/lang/StringBuilder;"; } else if (cl == CharSequence.class) { return "(Ljava/lang/CharSequence;)Ljava/lang/StringBuilder;"; } else if (cl == char[].class) { return "([C)Ljava/lang/StringBuilder;"; } else { return "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"; } } /** * The following method is copied from * org.objectweb.asm.commons.InstructionAdapter. Part of ASM: a very small * and fast Java bytecode manipulation framework. * Copyright (c) 2000-2005 INRIA, France Telecom All rights reserved. */ private static void iconst(MethodVisitor mv, final int cst) { if (cst >= -1 && cst <= 5) { mv.visitInsn(Opcodes.ICONST_0 + cst); } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) { mv.visitIntInsn(Opcodes.BIPUSH, cst); } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) { mv.visitIntInsn(Opcodes.SIPUSH, cst); } else { mv.visitLdcInsn(cst); } } private static int getLoadOpcode(Class c) { if (c == Void.TYPE) { throw new InternalError("Unexpected void type of load opcode"); } return ILOAD + getOpcodeOffset(c); } private static int getOpcodeOffset(Class c) { if (c.isPrimitive()) { if (c == Long.TYPE) { return 1; } else if (c == Float.TYPE) { return 2; } else if (c == Double.TYPE) { return 3; } return 0; } else { return 4; } } private static int getParameterSize(Class c) { if (c == Void.TYPE) { return 0; } else if (c == Long.TYPE || c == Double.TYPE) { return 2; } return 1; } /* ------------------------------- Full Method handler adapters strategy ------------------------------------ */ private static CallSite mhFull(MethodHandles.Lookup caller, MethodType args) throws Exception { return new ConstantCallSite(createMH(caller, args)); } private static MethodHandle createMH(MethodHandles.Lookup lookup, MethodType methodType) throws NoSuchMethodException, IllegalAccessException { // filter: String -> nullmask + identity // primitive -> do nothing // Object -> nullmask + Object.toString // lengther: String -> String.length // primitive -> drop and initial += 16 int parameterCount = methodType.parameterCount(); MethodHandle[] filters = new MethodHandle[parameterCount]; ArrayList lengthers = new ArrayList<>(parameterCount); ArrayList> appendTypeList = new ArrayList<>(parameterCount); UnaryOperator dropperOp = UnaryOperator.identity(); int initial = 0; for(int i = 0; i < parameterCount; i++) { Class type = methodType.parameterType(i); filters[i] = filter(lookup, type); Class appendType; // either a primitive or String if (type.isPrimitive()) { appendType = type; initial += 16; // TODO: Consider a more accurate estimate for primitives. UnaryOperator _dropperOp = dropperOp; int _i = i; dropperOp = mh -> MethodHandles.dropArguments(_dropperOp.apply(mh), _i, type); } else { appendType = String.class; lengthers.add(STRING_LENGTH); } appendTypeList.add(appendType); } MethodHandle builder = MethodHandles.dropArguments(MethodHandles.identity(StringBuilder.class), 1, appendTypeList); for(int i = parameterCount; --i>=0; ) { // in reverse because append are composed in reverse too Class appendType = appendTypeList.get(i); MethodHandle appender = appender(appendType); if (i != 0) { appender = MethodHandles.dropArguments(appender, 1, appendTypeList.subList(0, i)); } builder = MethodHandles.foldArguments(builder, appender); } MethodHandle adder = MethodHandles.insertArguments(SUM, 0, initial).asCollector(int[].class, lengthers.size()); adder = MethodHandles.filterArguments(adder, 0, lengthers.toArray(new MethodHandle[lengthers.size()])); adder = dropperOp.apply(adder); MethodHandle newBuilder = MethodHandles.filterReturnValue(adder, NEW_STRING_BUILDER); MethodHandle target = MethodHandles.foldArguments(builder, newBuilder); target = MethodHandles.filterArguments(target, 0, filters); return MethodHandles.filterReturnValue(target, BUILDER_TO_STRING); } private static MethodHandle appender(Class appendType) throws NoSuchMethodException, IllegalAccessException { //TODO: cache these method handles ! MethodHandle appender = MethodHandles.publicLookup().findVirtual(StringBuilder.class, "append", MethodType.methodType(StringBuilder.class, appendType)); return appender.asType(MethodType.methodType(void.class, StringBuilder.class, appendType)); // should return void } private static MethodHandle filter(MethodHandles.Lookup lookup, Class type) throws NoSuchMethodException, IllegalAccessException { if (type.isPrimitive()) { return null; // identity filter } MethodHandle op; if (type == String.class) { op = MethodHandles.identity(type); } else { op = lookup.findVirtual(type, "toString", MethodType.methodType(String.class)); // try de-virtualize if possible } return MethodHandles.guardWithTest( IS_NULL.asType(MethodType.methodType(boolean.class, type)), NULL_STRING.asType(MethodType.methodType(String.class, type)), op); } // called by a method handle private static boolean isNull(Object s) { return s == null; } // called by a method handle private static int sum(int initial, int[] vs) { int sum = initial; // this loop should be unrolled by the JIT for(int v: vs) { sum += v; } return sum; } private static final MethodHandle NULL_STRING, NEW_STRING_BUILDER, STRING_LENGTH, BUILDER_TO_STRING, IS_NULL, SUM; static { NULL_STRING = MethodHandles.dropArguments(MethodHandles.constant(String.class, "null"), 0, Object.class); Lookup publicLookup = MethodHandles.publicLookup(); try { NEW_STRING_BUILDER = publicLookup.findConstructor(StringBuilder.class, MethodType.methodType(void.class, int.class)); STRING_LENGTH = publicLookup.findVirtual(String.class, "length", MethodType.methodType(int.class)); BUILDER_TO_STRING = publicLookup.findVirtual(StringBuilder.class, "toString", MethodType.methodType(String.class)); IS_NULL = MethodHandles.lookup().findStatic(StringConcatTestFactory.class, "isNull", MethodType.methodType(boolean.class, Object.class)); SUM = MethodHandles.lookup().findStatic(StringConcatTestFactory.class, "sum", MethodType.methodType(int.class, int.class, int[].class)); } catch (NoSuchMethodException | IllegalAccessException e) { throw new AssertionError(e); } } } From magnus.ihse.bursie at oracle.com Mon May 25 07:51:20 2015 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Mon, 25 May 2015 09:51:20 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555F232E.1060105@oracle.com> References: <555D82CC.9070105@oracle.com> <555DB419.6020301@oracle.com> <555F232E.1060105@oracle.com> Message-ID: <5562D478.3000806@oracle.com> On 2015-05-22 14:38, Jan Lahoda wrote: > Hi, > > I've uploaded a new iteration of the patch(es): > top-level repository: > http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/top-level/ > langtools: > http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/langtools/ > > (besides full webrevs, there are also webrevs showing the differences > between .00 and .01 available - see the "Delta webrev" link under > "Author's comments") > > Summary of changes: > -applied Eric's build changes > -moved CreateSymbols into make/src/classes/build/tools/symbolgenerator > -tried to improve the specification of base platforms in > CreateSymbols, per Maurizio's comment > -other cleanup in langtools per Maurizio's comments. Looks good to me! Copyright year in CreateSymbols.java says 2014, maybe time to update it? :-) /Magnus > > Thanks, > Jan > > On 21.5.2015 12:31, Maurizio Cimadamore wrote: >> Hi Jan, >> great work - couple of comments below: >> >> * it seems like some of the routines in Arguments can be simplified >> using lambdas - especially lookupPlatformProvider and checkOptionAllowed >> * Why JDKPlatformProvider is not called JDKPlatformProvider*Factory* ? >> * JavacProcessingEnvironment.JoiningIterator seems to have commonalities >> with CompoundScopeIterator - any chance that we might refactor this a >> bit? >> * What's the rationale for giving an error if -platform is specified and >> a non-StandardFileManager is provided? Can't we simply swallow that, >> ignore the platform settings and issue a Lint 'options' warning? >> * Would it make sense for some of the classfile generation logic in >> CreateSymbols to be moved under the classfile API ? >> * I had hard time reconciling some of the comments in CreateSymbols with >> how the files were laid out. I think in the end, what you mean is that >> if you have platforms 7, 8, 9 - you should pick one baseline (i.e. 8) >> and then generate diffs for 9 and 7 against the 8 one. If that's the use >> case, I think the command line can be simplified a bit in order to >> explicitly state which of the platform is the baseline one, and the >> remaining parameters can be inferred from the tool (as the >> seem to be typically all identical >> but one which is set to - the one for the baseline). Maybe the >> inference logic should be different (i.e. use 8 as a baseline for 7 and >> 7 as a baseline for 6) - but - whatever the logic, I think it should be >> chosen once and for all, and live implicitly in the tool? Or are there >> reasons as to why it might be handy to customize the baselines? >> >> Maurizio >> >> On 21/05/15 08:01, Jan Lahoda wrote: >>> Hi, >>> >>> This is a patch adding a new option, -platform, to javac. >>> >>> Patch for the top-level repository is here: >>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >>> >>> Patch for the langtools repository is here: >>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >>> >>> These changes also require additional langtools changes as their >>> prerequisite: >>> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ >>> >>> Overall, one can imagine '-platform N' to have the same effect as >>> '-source N -target N -bootclasspath '. The possible values >>> for 'N' are pluggable in a limited way, though (see >>> langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). >>> >>> Note that this patch only introduces N=7 and N=8, which correspond to >>> Open JDK 7 and 8 GA. >>> >>> A tricky problem to solve is where to get the APIs for platform N. The >>> proposal is to include history data in the textual format inside the >>> OpenJDK repositories (the input data), process them at build time and >>> create a lib/ct.sym file holding the data in the JDK image. javac >>> running with the -platform option then compiles against the lib/ct.sym >>> file. The input history data are placed >>> /make/data/symbols (the sym.txt files). This >>> patches only includes data for OpenJDK 7 and 8, and only for public >>> APIs (more or less Java SE and JDK @Exported APIs). >>> >>> The size of the history data is currently ~6MB in the JDK checkout and >>> ~650kB inside the .hg directory (the size could change significantly >>> if additional classes/elements, like non-public API classes, would >>> need to be included). The lib/ct.sym file is currently ~4.5MB. >>> >>> The ct.sym file is a zip file containing signature files. The >>> signature files are similar to classfiles (so javac can read them as >>> classfiles), but are missing some attributes, most notably the Code >>> attribute. On the top-level, the ct.sym contains directories named >>> "7", "78" and "8". When compiling for version 'N', the bootclasspath >>> for that version is obtained by using directories which have 'N' in >>> their name. >>> >>> The sigfiles for ct.sym are created by >>> /make/tools/symbolgenerator/CreateSymbols.java. >>> The same file can also be used to construct the sym.txt files. Concise >>> instructions are part of the CreateSymbols.java. >>> >>> I am sending this as one review, as the changes together make one >>> feature, but the langtools and top-level changes are independent to a >>> great degree: the langtools changes add the "-platform" javac; and the >>> top-level changes add the history data and ability to build the ct.sym >>> file. If desired, these could be pushed and/or reviewed independently. >>> >>> Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan >>> Bateman and others who have provided advices and help on the matter >>> before. >>> >>> Any insights/comments are wholeheartedly welcome. >>> >>> Thanks, >>> Jan >> From aleksey.shipilev at oracle.com Mon May 25 19:01:52 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Mon, 25 May 2015 22:01:52 +0300 Subject: String concatenation tweaks In-Reply-To: <5561EF32.8080101@univ-mlv.fr> References: <55014F7C.20201@oracle.com> <553139FA.20601@oracle.com> <55313D3A.10008@univ-mlv.fr> <55551C6F.4000704@oracle.com> <555DCC4D.8040505@oracle.com> <7CDF6C9C-90CE-4D93-9290-10D9CCC29BB9@univ-mlv.fr> <555EE8F7.5040007@oracle.com> <5561EF32.8080101@univ-mlv.fr> Message-ID: <556371A0.80600@oracle.com> On 05/24/2015 06:33 PM, Remi Forax wrote: > Here is my version (see at the end of this message). Thanks! Merged it into the patchset with minor polish: http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/ The performance is interesting. It seems to break OptimizeStringConcat, and so it's a performance win only on non-optimized chains, like string_string_long. The allocation pressure is slightly higher as well, seems to be because int[] from the collector is not scalarized. You may want to tune it more, JMH benchmarks are here: http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/indy-concat-bench.tar.gz ...and -prof perfasm, -prof perfnorm, and -prof gc are your friends. Thanks, -Aleksey -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From mail at florian-schoppmann.net Tue May 26 02:57:14 2015 From: mail at florian-schoppmann.net (Florian Schoppmann) Date: Mon, 25 May 2015 19:57:14 -0700 Subject: JEP 119 / Implementation of javax.lang.model.util.Types Message-ID: <1m4zti6.p7nsvt115i3i8N%mail@florian-schoppmann.net> Hi all, This Github repository of mine provides an abstract skeletal implementation of the type-system related methods of interface javax.lang.model.util.Types, plus a concrete realization backed by the core Java Reflection API, akin to JEP 119 by Joe Darcy. Obviously, there also exists an official JEP 119 implementation, so far in proof-of-concept state: In their current states, the two projects have slightly different goals: E.g., CoreReflectionFactory.java in the official JEP 119 implementation does not yet implement all subtyping-related relations like, e.g., JLS ?4.5.1 "contains", whereas my project is so far only concerned with subtyping but does not implement any Element-subinterfaces except TypeElement). Moreover, JEP 119 is only concerned with backing javax.lang.model by Core Reflection, whereas the goal of my project is to allow arbitrary backing (say, e.g., by the domain model of some DSL that needs to support the Java type system). If there should be any interest in using my code or parts of it for the JDK, I would be happy to help with any necessary adjustments. Florian PS: X-post to core-libs.devel and compiler.devel. Follow-up to core-libs suggested. From forax at univ-mlv.fr Tue May 26 13:31:59 2015 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 26 May 2015 15:31:59 +0200 Subject: String concatenation tweaks In-Reply-To: <556371A0.80600@oracle.com> References: <55014F7C.20201@oracle.com> <553139FA.20601@oracle.com> <55313D3A.10008@univ-mlv.fr> <55551C6F.4000704@oracle.com> <555DCC4D.8040505@oracle.com> <7CDF6C9C-90CE-4D93-9290-10D9CCC29BB9@univ-mlv.fr> <555EE8F7.5040007@oracle.com> <5561EF32.8080101@univ-mlv.fr> <556371A0.80600@oracle.com> Message-ID: <556475CF.8090406@univ-mlv.fr> On 05/25/2015 09:01 PM, Aleksey Shipilev wrote: > On 05/24/2015 06:33 PM, Remi Forax wrote: >> Here is my version (see at the end of this message). > Thanks! Merged it into the patchset with minor polish: > http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/ > > The performance is interesting. It seems to break OptimizeStringConcat, > and so it's a performance win only on non-optimized chains, like > string_string_long. The allocation pressure is slightly higher as well, > seems to be because int[] from the collector is not scalarized. I wonder if the two things are not related, fail to unroll -> creation of int[] -> non constant value for the StringBuilder constructor -> break of OptimizeStringConcat optimization. Here is a new patch that do the unrolling by hand with a nifty trick to avoid to create an overload for each arities of sum, i'm not very pround of it because it creates an artificial performance cliff if there is more than 8 parameters but at least it will confirm or not my theory. > > You may want to tune it more, JMH benchmarks are here: > http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/indy-concat-bench.tar.gz > > ...and -prof perfasm, -prof perfnorm, and -prof gc are your friends. > > Thanks, > -Aleksey regards, R?mi > /* * Copyright (c) 2012, 2015, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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. */ package java.lang.invoke; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Label; import jdk.internal.org.objectweb.asm.MethodVisitor; import jdk.internal.org.objectweb.asm.Opcodes; import opto_string_concat.StringConcatTestFactory; import sun.misc.Unsafe; import sun.security.action.GetPropertyAction; import java.lang.invoke.MethodHandles.Lookup; import java.security.AccessController; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.PropertyPermission; import java.util.concurrent.ConcurrentHashMap; import java.util.function.UnaryOperator; import java.util.stream.IntStream; import static jdk.internal.org.objectweb.asm.Opcodes.*; /** * Generates the String concatenation stub. * * @author Aleksey Shipilev */ public class StringConcatFactory { private static final Strategy STRATEGY; private static final boolean DEBUG; private static final ProxyClassesDumper DUMPER; static { { final String key = "java.lang.invoke.stringConcat"; String str = AccessController.doPrivileged( new GetPropertyAction(key), null, new PropertyPermission(key, "read")); STRATEGY = (str == null) ? Strategy.INNER_SIZED : Strategy.valueOf(str); } { final String key = "java.lang.invoke.stringConcat.debug"; String str = AccessController.doPrivileged( new GetPropertyAction(key), null, new PropertyPermission(key, "read")); DEBUG = (str != null); } { final String key = "java.lang.invoke.stringConcat.dumpClasses"; String str = AccessController.doPrivileged( new GetPropertyAction(key), null, new PropertyPermission(key , "read")); DUMPER = (str == null) ? null : ProxyClassesDumper.getInstance(str); } } private enum Strategy { NAIVE_MH_FILTER, NAIVE_MH_FILTER_SIZED, INNER, INNER_SIZED, FULL_MH } private static final Map CACHE = new ConcurrentHashMap(); /** * Bootstrap method for javac-generated concat call. * * @param caller caller context * @param name ignored * @param args method arguments, in order * @return a callsite with actual method to concatenate strings * @throws Exception if something goes wrong */ public static CallSite stringConcat(MethodHandles.Lookup caller, String name, MethodType args) throws Exception { if (DEBUG) { System.out.print("StringConcatFactory "); System.out.print(STRATEGY); System.out.print(" is here for "); System.out.print(args); System.out.print(" "); } CallSite cs = CACHE.get(args); if (cs != null) { if (DEBUG) { System.out.println(" "); } } else { cs = generate(caller, args); CACHE.put(args, cs); if (DEBUG) { System.out.println(); } } return cs; } private static CallSite generate(MethodHandles.Lookup caller, MethodType args) throws Exception { switch (STRATEGY) { case NAIVE_MH_FILTER: return mhFiltered(caller, args, false); case NAIVE_MH_FILTER_SIZED: return mhFiltered(caller, args, true); case INNER: return innerClass(caller, args, false); case INNER_SIZED: return innerClass(caller, args, true); case FULL_MH: return mhFull(caller, args); default: throw new IllegalStateException("Not implemented yet: " + STRATEGY); } } /* ------------------------------------ Method handler adapters strategy ------------------------------------ */ private static CallSite mhFiltered(MethodHandles.Lookup caller, MethodType args, boolean sized) throws Exception { MethodHandle resultString = caller.findStatic( StringConcatFactory.class, (sized ? "concatNaiveSized" : "concatNaive"), MethodType.methodType(String.class, String[].class)); MethodHandle adapted = resultString.asCollector(String[].class, args.parameterCount()); // Adapt arguments, if needed: call String.valueOf on them. Class[] params = args.parameterArray(); for (int p = 0; p < params.length; p++) { if (params[p] != String.class) { MethodHandle valueOf = caller.findStatic( String.class, "valueOf", MethodType.methodType(String.class, params[p])); adapted = MethodHandles.filterArgument(adapted, p, valueOf); } } return new ConstantCallSite(adapted); } /** * Naive concatenation. * Argument conversion was already handled by the caller. * * @param args strings to concatenate * @return concatenated string */ public static String concatNaive(String[] args) { StringBuilder sb = new StringBuilder(); for (String s : args) { sb.append(s); } return sb.toString(); } /** * Naive concatenation + pre-sized StringBuilder * Argument conversion was already handled by the caller. * * @param args strings to concatenate * @return concatenated string */ public static String concatNaiveSized(String[] args) { int len = 0; for (String s : args) { len += s.length(); } StringBuilder sb = new StringBuilder(len); for (String s : args) { sb.append(s); } return sb.toString(); } /* ---------------------------------------- Inner class strategy -------------------------------------------- */ static final Unsafe UNSAFE = Unsafe.getUnsafe(); static final int CLASSFILE_VERSION = 52; static final String JAVA_LANG_OBJECT = "java/lang/Object"; static final String NAME_FACTORY = "concat"; static final String CLASS_NAME = "java/lang/String$Concat"; static final String NAME_CTOR = ""; static final String CLASS_STRING_BUILDER = "java/lang/StringBuilder"; static final String CLASS_STRING = "java/lang/String"; static final String SIG_TO_STRING = "()Ljava/lang/String;"; private static CallSite innerClass(MethodHandles.Lookup caller, MethodType args, boolean sized) { Class targetClass = caller.lookupClass(); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES); cw.visit(CLASSFILE_VERSION, ACC_SUPER + ACC_FINAL + ACC_SYNTHETIC, CLASS_NAME, null, JAVA_LANG_OBJECT, null ); MethodVisitor mv = cw.visitMethod( ACC_PUBLIC + ACC_STATIC + ACC_FINAL, NAME_FACTORY, args.toMethodDescriptorString(), null, null); mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true); mv.visitCode(); Class[] arr = args.parameterArray(); // In sized mode, it makes sense to make StringBuilder append chains look // familiar to OptimizeStringConcat. Therefore, we need to do null-checks // early. if (sized) { int off = 0; for (Class cl : arr) { if (cl == String.class) { Label l0 = new Label(); mv.visitIntInsn(ALOAD, off); mv.visitJumpInsn(IFNONNULL, l0); mv.visitLdcInsn("null"); mv.visitIntInsn(ASTORE, off); mv.visitLabel(l0); } off += getParameterSize(cl); } } // Prepare StringBuilder instance mv.visitTypeInsn(NEW, CLASS_STRING_BUILDER); mv.visitInsn(DUP); if (sized) { // Walk through the arguments, and try to estimate the final length int add = 0; mv.visitInsn(ICONST_0); int off = 0; for (Class cl : arr) { // TODO: For anything other than Strings and primitives, it makes sense to call String.valueOf first. if (cl == String.class) { mv.visitIntInsn(ALOAD, off); mv.visitMethodInsn( INVOKEVIRTUAL, CLASS_STRING, "length", "()I", false ); mv.visitInsn(IADD); } else if (cl.isPrimitive()) { // TODO: Consider a more accurate estimate for primitives. add += 16; } off += getParameterSize(cl); } if (add > 0) { iconst(mv, add); mv.visitInsn(IADD); } mv.visitMethodInsn( INVOKESPECIAL, CLASS_STRING_BUILDER, NAME_CTOR, "(I)V", false ); } else { mv.visitMethodInsn( INVOKESPECIAL, CLASS_STRING_BUILDER, NAME_CTOR, "()V", false ); } int off = 0; for (Class cl : arr) { mv.visitVarInsn(getLoadOpcode(cl), off); off += getParameterSize(cl); mv.visitMethodInsn( INVOKEVIRTUAL, CLASS_STRING_BUILDER, "append", getDesc(cl), false ); } mv.visitMethodInsn( INVOKEVIRTUAL, CLASS_STRING_BUILDER, "toString", SIG_TO_STRING, false ); mv.visitInsn(ARETURN); mv.visitMaxs(-1, -1); mv.visitEnd(); cw.visitEnd(); final byte[] classBytes = cw.toByteArray(); final Class innerClass = UNSAFE.defineAnonymousClass(targetClass, classBytes, null); if (DUMPER != null) { DUMPER.dumpClass(args.toString() + ".class", classBytes); } try { UNSAFE.ensureClassInitialized(innerClass); return new ConstantCallSite( MethodHandles.Lookup.IMPL_LOOKUP .findStatic(innerClass, NAME_FACTORY, args)); } catch (ReflectiveOperationException e) { throw new IllegalStateException("Exception finding constructor", e); } } private static String getDesc(Class cl) { if (cl.isPrimitive()) { if (cl == Integer.TYPE) { return "(I)Ljava/lang/StringBuilder;"; } else if (cl == Boolean.TYPE) { return "(Z)Ljava/lang/StringBuilder;"; } else if (cl == Byte.TYPE) { return "(B)Ljava/lang/StringBuilder;"; } else if (cl == Character.TYPE) { return "(C)Ljava/lang/StringBuilder;"; } else if (cl == Short.TYPE) { return "(S)Ljava/lang/StringBuilder;"; } else if (cl == Double.TYPE) { return "(D)Ljava/lang/StringBuilder;"; } else if (cl == Float.TYPE) { return "(F)Ljava/lang/StringBuilder;"; } else if (cl == Long.TYPE) { return "(J)Ljava/lang/StringBuilder;"; } else { throw new IllegalStateException(); } } else if (cl == String.class) { return "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; } else if (cl == StringBuffer.class) { return "(Ljava/util/StringBuffer;)Ljava/lang/StringBuilder;"; } else if (cl == CharSequence.class) { return "(Ljava/lang/CharSequence;)Ljava/lang/StringBuilder;"; } else if (cl == char[].class) { return "([C)Ljava/lang/StringBuilder;"; } else { return "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"; } } /** * The following method is copied from * org.objectweb.asm.commons.InstructionAdapter. Part of ASM: a very small * and fast Java bytecode manipulation framework. * Copyright (c) 2000-2005 INRIA, France Telecom All rights reserved. */ private static void iconst(MethodVisitor mv, final int cst) { if (cst >= -1 && cst <= 5) { mv.visitInsn(Opcodes.ICONST_0 + cst); } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) { mv.visitIntInsn(Opcodes.BIPUSH, cst); } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) { mv.visitIntInsn(Opcodes.SIPUSH, cst); } else { mv.visitLdcInsn(cst); } } private static int getLoadOpcode(Class c) { if (c == Void.TYPE) { throw new InternalError("Unexpected void type of load opcode"); } return ILOAD + getOpcodeOffset(c); } private static int getOpcodeOffset(Class c) { if (c.isPrimitive()) { if (c == Long.TYPE) { return 1; } else if (c == Float.TYPE) { return 2; } else if (c == Double.TYPE) { return 3; } return 0; } else { return 4; } } private static int getParameterSize(Class c) { if (c == Void.TYPE) { return 0; } else if (c == Long.TYPE || c == Double.TYPE) { return 2; } return 1; } /* ------------------------------- Full Method handler adapters strategy ------------------------------------ */ private static CallSite mhFull(MethodHandles.Lookup caller, MethodType args) throws Exception { return new ConstantCallSite(createMH(caller, args)); } private static MethodHandle createMH(MethodHandles.Lookup lookup, MethodType methodType) throws NoSuchMethodException, IllegalAccessException { // filter: String -> nullmask + identity // primitive -> do nothing // Object -> nullmask + Object.toString // adder: String -> String.length // primitive drop and initial += 16 int parameterCount = methodType.parameterCount(); MethodHandle[] filters = new MethodHandle[parameterCount]; ArrayList lengthers = new ArrayList<>(parameterCount); ArrayList> appendTypeList = new ArrayList<>(parameterCount); UnaryOperator dropperOp = UnaryOperator.identity(); int initial = 0; for(int i = 0; i < parameterCount; i++) { Class type = methodType.parameterType(i); filters[i] = filter(lookup, type); Class appendType; // either a primitive or String if (type.isPrimitive()) { appendType = type; initial += 16; // TODO: Consider a more accurate estimate for primitives. UnaryOperator _dropperOp = dropperOp; int _i = i; dropperOp = mh -> MethodHandles.dropArguments(_dropperOp.apply(mh), _i, type); } else { appendType = String.class; lengthers.add(STRING_LENGTH); } appendTypeList.add(appendType); } MethodHandle builder = MethodHandles.dropArguments(MethodHandles.identity(StringBuilder.class), 1, appendTypeList); for(int i = parameterCount; --i>=0; ) { // in reverse because calls to append() are composed in reverse too Class appendType = appendTypeList.get(i); MethodHandle appender = appender(appendType); if (i != 0) { appender = MethodHandles.dropArguments(appender, 1, appendTypeList.subList(0, i)); } builder = MethodHandles.foldArguments(builder, appender); } MethodHandle sum; if (lengthers.size() <= SUM_UNROLLED_COUNT) { sum = MethodHandles.insertArguments(SUM_UNROLLED, 1, IntStream.range(0, SUM_UNROLLED_COUNT - lengthers.size()).mapToObj(__ -> 0).toArray()); } else { sum = SUM.asCollector(int[].class, lengthers.size()); } MethodHandle adder = MethodHandles.insertArguments(sum, 0, initial); adder = MethodHandles.filterArguments(adder, 0, lengthers.toArray(new MethodHandle[lengthers.size()])); adder = dropperOp.apply(adder); MethodHandle newBuilder = MethodHandles.filterReturnValue(adder, NEW_STRING_BUILDER); MethodHandle target = MethodHandles.foldArguments(builder, newBuilder); target = MethodHandles.filterArguments(target, 0, filters); return MethodHandles.filterReturnValue(target, BUILDER_TO_STRING); } private static MethodHandle appender(Class appendType) throws NoSuchMethodException, IllegalAccessException { //TODO: cache these method handles ! MethodHandle appender = MethodHandles.publicLookup().findVirtual(StringBuilder.class, "append", MethodType.methodType(StringBuilder.class, appendType)); return appender.asType(MethodType.methodType(void.class, StringBuilder.class, appendType)); // should return void } private static MethodHandle filter(MethodHandles.Lookup lookup, Class type) throws NoSuchMethodException, IllegalAccessException { if (type.isPrimitive()) { return null; // identity filter } MethodHandle op; if (type == String.class) { op = MethodHandles.identity(type); } else { op = lookup.findVirtual(type, "toString", MethodType.methodType(String.class)); // try de-virtualize if possible } return MethodHandles.guardWithTest( IS_NULL.asType(MethodType.methodType(boolean.class, type)), NULL_STRING.asType(MethodType.methodType(String.class, type)), op); } // called by a method handle private static boolean isNull(Object s) { return s == null; } // called by a method handle private static int sumUnrolled(int initial, int v0, int v1, int v2, int v3, int v4, int v5, int v6, int v7) { return initial + v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7; } // called by a method handle private static int sum(int initial, int[] vs) { int sum = initial; // this loop is not unrolled by the JIT :( for(int v: vs) { sum += v; } return sum; } private static final int SUM_UNROLLED_COUNT = 8; private static final MethodHandle NULL_STRING, NEW_STRING_BUILDER, STRING_LENGTH, BUILDER_TO_STRING, IS_NULL, SUM, SUM_UNROLLED; static { NULL_STRING = MethodHandles.dropArguments(MethodHandles.constant(String.class, "null"), 0, Object.class); Lookup publicLookup = MethodHandles.publicLookup(); try { NEW_STRING_BUILDER = publicLookup.findConstructor(StringBuilder.class, MethodType.methodType(void.class, int.class)); STRING_LENGTH = publicLookup.findVirtual(String.class, "length", MethodType.methodType(int.class)); BUILDER_TO_STRING = publicLookup.findVirtual(StringBuilder.class, "toString", MethodType.methodType(String.class)); IS_NULL = MethodHandles.lookup().findStatic(StringConcatTestFactory.class, "isNull", MethodType.methodType(boolean.class, Object.class)); SUM = MethodHandles.lookup().findStatic(StringConcatTestFactory.class, "sum", MethodType.methodType(int.class, int.class, int[].class)); SUM_UNROLLED = MethodHandles.lookup().findStatic(StringConcatTestFactory.class, "sumUnrolled", MethodType.methodType(int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class)); } catch (NoSuchMethodException | IllegalAccessException e) { throw new AssertionError(e); } } } From jan.lahoda at oracle.com Wed May 27 09:37:49 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Wed, 27 May 2015 11:37:49 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <555F2D9F.2090505@oracle.com> References: <555D82CC.9070105@oracle.com> <555DB419.6020301@oracle.com> <555F232E.1060105@oracle.com> <555F2692.5030002@oracle.com> <555F2D9F.2090505@oracle.com> Message-ID: <5565906D.1050400@oracle.com> Hi, I've uploaded another iteration, with these changes: -the "symbols" file is now generated automatically (for the typical OpenJDK case). -fixed a minor issue in CreateSymbols that could cause putting class description into wrong a file (the "break" -> "break OUTER;" change). -jdk.management module has been split out from java.management recently, so splitting the corresponding .sym.txt files into java.management and jdk.management as well. -updating the copyright year in CreateSymbols, as noted by Magnus. Webrevs: -top-level: http://cr.openjdk.java.net/~jlahoda/8072480/webrev.02/top-level/ -langtools (no changes against the last webrev): http://cr.openjdk.java.net/~jlahoda/8072480/webrev.02/langtools/ Delta webrevs against the previous iteration are included under "Author comments". Thanks for the comments so far! Jan On 22.5.2015 15:22, Jan Lahoda wrote: > On 22.5.2015 14:52, Maurizio Cimadamore wrote: >> Excellent work. >> >> I think the comment in CreateSymbols could be made clearer w.r.t. Probe >> - i.e. that Probe should be ran on top of the JDK N - i.e. >> >> /bin/java Probe --> classes-8 >> /bin/java Probe --> classes-7 >> /bin/java Probe --> classes-7 >> >> etc. > > Sure, will do. > > I'll also look at generating the make/data/symbols/symbols descriptions > automatically, per our offline discussion. > > Thanks! > > Jan > >> >> Maurizio >> >> On 22/05/15 13:38, Jan Lahoda wrote: >>> Hi, >>> >>> I've uploaded a new iteration of the patch(es): >>> top-level repository: >>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/top-level/ >>> langtools: >>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/langtools/ >>> >>> (besides full webrevs, there are also webrevs showing the differences >>> between .00 and .01 available - see the "Delta webrev" link under >>> "Author's comments") >>> >>> Summary of changes: >>> -applied Eric's build changes >>> -moved CreateSymbols into make/src/classes/build/tools/symbolgenerator >>> -tried to improve the specification of base platforms in >>> CreateSymbols, per Maurizio's comment >>> -other cleanup in langtools per Maurizio's comments. >>> >>> Thanks, >>> Jan >>> >>> On 21.5.2015 12:31, Maurizio Cimadamore wrote: >>>> Hi Jan, >>>> great work - couple of comments below: >>>> >>>> * it seems like some of the routines in Arguments can be simplified >>>> using lambdas - especially lookupPlatformProvider and >>>> checkOptionAllowed >>>> * Why JDKPlatformProvider is not called JDKPlatformProvider*Factory* ? >>>> * JavacProcessingEnvironment.JoiningIterator seems to have >>>> commonalities >>>> with CompoundScopeIterator - any chance that we might refactor this a >>>> bit? >>>> * What's the rationale for giving an error if -platform is specified >>>> and >>>> a non-StandardFileManager is provided? Can't we simply swallow that, >>>> ignore the platform settings and issue a Lint 'options' warning? >>>> * Would it make sense for some of the classfile generation logic in >>>> CreateSymbols to be moved under the classfile API ? >>>> * I had hard time reconciling some of the comments in CreateSymbols >>>> with >>>> how the files were laid out. I think in the end, what you mean is that >>>> if you have platforms 7, 8, 9 - you should pick one baseline (i.e. 8) >>>> and then generate diffs for 9 and 7 against the 8 one. If that's the >>>> use >>>> case, I think the command line can be simplified a bit in order to >>>> explicitly state which of the platform is the baseline one, and the >>>> remaining parameters can be inferred from the tool (as the >>>> seem to be typically all >>>> identical >>>> but one which is set to - the one for the baseline). Maybe the >>>> inference logic should be different (i.e. use 8 as a baseline for 7 and >>>> 7 as a baseline for 6) - but - whatever the logic, I think it should be >>>> chosen once and for all, and live implicitly in the tool? Or are there >>>> reasons as to why it might be handy to customize the baselines? >>>> >>>> Maurizio >>>> >>>> On 21/05/15 08:01, Jan Lahoda wrote: >>>>> Hi, >>>>> >>>>> This is a patch adding a new option, -platform, to javac. >>>>> >>>>> Patch for the top-level repository is here: >>>>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >>>>> >>>>> Patch for the langtools repository is here: >>>>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >>>>> >>>>> These changes also require additional langtools changes as their >>>>> prerequisite: >>>>> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ >>>>> >>>>> Overall, one can imagine '-platform N' to have the same effect as >>>>> '-source N -target N -bootclasspath '. The possible values >>>>> for 'N' are pluggable in a limited way, though (see >>>>> langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). >>>>> >>>>> >>>>> Note that this patch only introduces N=7 and N=8, which correspond to >>>>> Open JDK 7 and 8 GA. >>>>> >>>>> A tricky problem to solve is where to get the APIs for platform N. The >>>>> proposal is to include history data in the textual format inside the >>>>> OpenJDK repositories (the input data), process them at build time and >>>>> create a lib/ct.sym file holding the data in the JDK image. javac >>>>> running with the -platform option then compiles against the lib/ct.sym >>>>> file. The input history data are placed >>>>> /make/data/symbols (the sym.txt files). This >>>>> patches only includes data for OpenJDK 7 and 8, and only for public >>>>> APIs (more or less Java SE and JDK @Exported APIs). >>>>> >>>>> The size of the history data is currently ~6MB in the JDK checkout and >>>>> ~650kB inside the .hg directory (the size could change significantly >>>>> if additional classes/elements, like non-public API classes, would >>>>> need to be included). The lib/ct.sym file is currently ~4.5MB. >>>>> >>>>> The ct.sym file is a zip file containing signature files. The >>>>> signature files are similar to classfiles (so javac can read them as >>>>> classfiles), but are missing some attributes, most notably the Code >>>>> attribute. On the top-level, the ct.sym contains directories named >>>>> "7", "78" and "8". When compiling for version 'N', the bootclasspath >>>>> for that version is obtained by using directories which have 'N' in >>>>> their name. >>>>> >>>>> The sigfiles for ct.sym are created by >>>>> /make/tools/symbolgenerator/CreateSymbols.java. >>>>> The same file can also be used to construct the sym.txt files. Concise >>>>> instructions are part of the CreateSymbols.java. >>>>> >>>>> I am sending this as one review, as the changes together make one >>>>> feature, but the langtools and top-level changes are independent to a >>>>> great degree: the langtools changes add the "-platform" javac; and the >>>>> top-level changes add the history data and ability to build the ct.sym >>>>> file. If desired, these could be pushed and/or reviewed independently. >>>>> >>>>> Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan >>>>> Bateman and others who have provided advices and help on the matter >>>>> before. >>>>> >>>>> Any insights/comments are wholeheartedly welcome. >>>>> >>>>> Thanks, >>>>> Jan >>>> >> From maurizio.cimadamore at oracle.com Wed May 27 09:59:38 2015 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 27 May 2015 10:59:38 +0100 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <5565906D.1050400@oracle.com> References: <555D82CC.9070105@oracle.com> <555DB419.6020301@oracle.com> <555F232E.1060105@oracle.com> <555F2692.5030002@oracle.com> <555F2D9F.2090505@oracle.com> <5565906D.1050400@oracle.com> Message-ID: <5565958A.1040807@oracle.com> Looks great. The only nitpick is that the comments in CreateSymbols don't mention the fact that a side effect of the sym.txt generation is the mentioned earlier in the same comments (so one might wonder where does that come from). Maurizio On 27/05/15 10:37, Jan Lahoda wrote: > Hi, > > I've uploaded another iteration, with these changes: > -the "symbols" file is now generated automatically (for the typical > OpenJDK case). > -fixed a minor issue in CreateSymbols that could cause putting class > description into wrong a file (the "break" -> "break OUTER;" change). > -jdk.management module has been split out from java.management > recently, so splitting the corresponding .sym.txt files into > java.management and jdk.management as well. > -updating the copyright year in CreateSymbols, as noted by Magnus. > > Webrevs: > -top-level: > http://cr.openjdk.java.net/~jlahoda/8072480/webrev.02/top-level/ > -langtools (no changes against the last webrev): > http://cr.openjdk.java.net/~jlahoda/8072480/webrev.02/langtools/ > > Delta webrevs against the previous iteration are included under > "Author comments". > > Thanks for the comments so far! > > Jan > > On 22.5.2015 15:22, Jan Lahoda wrote: >> On 22.5.2015 14:52, Maurizio Cimadamore wrote: >>> Excellent work. >>> >>> I think the comment in CreateSymbols could be made clearer w.r.t. Probe >>> - i.e. that Probe should be ran on top of the JDK N - i.e. >>> >>> /bin/java Probe --> classes-8 >>> /bin/java Probe --> classes-7 >>> /bin/java Probe --> classes-7 >>> >>> etc. >> >> Sure, will do. >> >> I'll also look at generating the make/data/symbols/symbols descriptions >> automatically, per our offline discussion. >> >> Thanks! >> >> Jan >> >>> >>> Maurizio >>> >>> On 22/05/15 13:38, Jan Lahoda wrote: >>>> Hi, >>>> >>>> I've uploaded a new iteration of the patch(es): >>>> top-level repository: >>>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/top-level/ >>>> langtools: >>>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/langtools/ >>>> >>>> (besides full webrevs, there are also webrevs showing the differences >>>> between .00 and .01 available - see the "Delta webrev" link under >>>> "Author's comments") >>>> >>>> Summary of changes: >>>> -applied Eric's build changes >>>> -moved CreateSymbols into make/src/classes/build/tools/symbolgenerator >>>> -tried to improve the specification of base platforms in >>>> CreateSymbols, per Maurizio's comment >>>> -other cleanup in langtools per Maurizio's comments. >>>> >>>> Thanks, >>>> Jan >>>> >>>> On 21.5.2015 12:31, Maurizio Cimadamore wrote: >>>>> Hi Jan, >>>>> great work - couple of comments below: >>>>> >>>>> * it seems like some of the routines in Arguments can be simplified >>>>> using lambdas - especially lookupPlatformProvider and >>>>> checkOptionAllowed >>>>> * Why JDKPlatformProvider is not called >>>>> JDKPlatformProvider*Factory* ? >>>>> * JavacProcessingEnvironment.JoiningIterator seems to have >>>>> commonalities >>>>> with CompoundScopeIterator - any chance that we might refactor this a >>>>> bit? >>>>> * What's the rationale for giving an error if -platform is specified >>>>> and >>>>> a non-StandardFileManager is provided? Can't we simply swallow that, >>>>> ignore the platform settings and issue a Lint 'options' warning? >>>>> * Would it make sense for some of the classfile generation logic in >>>>> CreateSymbols to be moved under the classfile API ? >>>>> * I had hard time reconciling some of the comments in CreateSymbols >>>>> with >>>>> how the files were laid out. I think in the end, what you mean is >>>>> that >>>>> if you have platforms 7, 8, 9 - you should pick one baseline (i.e. 8) >>>>> and then generate diffs for 9 and 7 against the 8 one. If that's the >>>>> use >>>>> case, I think the command line can be simplified a bit in order to >>>>> explicitly state which of the platform is the baseline one, and the >>>>> remaining parameters can be inferred from the tool (as the >>>>> seem to be typically all >>>>> identical >>>>> but one which is set to - the one for the baseline). Maybe the >>>>> inference logic should be different (i.e. use 8 as a baseline for >>>>> 7 and >>>>> 7 as a baseline for 6) - but - whatever the logic, I think it >>>>> should be >>>>> chosen once and for all, and live implicitly in the tool? Or are >>>>> there >>>>> reasons as to why it might be handy to customize the baselines? >>>>> >>>>> Maurizio >>>>> >>>>> On 21/05/15 08:01, Jan Lahoda wrote: >>>>>> Hi, >>>>>> >>>>>> This is a patch adding a new option, -platform, to javac. >>>>>> >>>>>> Patch for the top-level repository is here: >>>>>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >>>>>> >>>>>> Patch for the langtools repository is here: >>>>>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >>>>>> >>>>>> These changes also require additional langtools changes as their >>>>>> prerequisite: >>>>>> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ >>>>>> >>>>>> Overall, one can imagine '-platform N' to have the same effect as >>>>>> '-source N -target N -bootclasspath '. The possible >>>>>> values >>>>>> for 'N' are pluggable in a limited way, though (see >>>>>> langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). >>>>>> >>>>>> >>>>>> >>>>>> Note that this patch only introduces N=7 and N=8, which >>>>>> correspond to >>>>>> Open JDK 7 and 8 GA. >>>>>> >>>>>> A tricky problem to solve is where to get the APIs for platform >>>>>> N. The >>>>>> proposal is to include history data in the textual format inside the >>>>>> OpenJDK repositories (the input data), process them at build time >>>>>> and >>>>>> create a lib/ct.sym file holding the data in the JDK image. javac >>>>>> running with the -platform option then compiles against the >>>>>> lib/ct.sym >>>>>> file. The input history data are placed >>>>>> /make/data/symbols (the sym.txt files). This >>>>>> patches only includes data for OpenJDK 7 and 8, and only for public >>>>>> APIs (more or less Java SE and JDK @Exported APIs). >>>>>> >>>>>> The size of the history data is currently ~6MB in the JDK >>>>>> checkout and >>>>>> ~650kB inside the .hg directory (the size could change significantly >>>>>> if additional classes/elements, like non-public API classes, would >>>>>> need to be included). The lib/ct.sym file is currently ~4.5MB. >>>>>> >>>>>> The ct.sym file is a zip file containing signature files. The >>>>>> signature files are similar to classfiles (so javac can read them as >>>>>> classfiles), but are missing some attributes, most notably the Code >>>>>> attribute. On the top-level, the ct.sym contains directories named >>>>>> "7", "78" and "8". When compiling for version 'N', the bootclasspath >>>>>> for that version is obtained by using directories which have 'N' in >>>>>> their name. >>>>>> >>>>>> The sigfiles for ct.sym are created by >>>>>> /make/tools/symbolgenerator/CreateSymbols.java. >>>>>> >>>>>> The same file can also be used to construct the sym.txt files. >>>>>> Concise >>>>>> instructions are part of the CreateSymbols.java. >>>>>> >>>>>> I am sending this as one review, as the changes together make one >>>>>> feature, but the langtools and top-level changes are independent >>>>>> to a >>>>>> great degree: the langtools changes add the "-platform" javac; >>>>>> and the >>>>>> top-level changes add the history data and ability to build the >>>>>> ct.sym >>>>>> file. If desired, these could be pushed and/or reviewed >>>>>> independently. >>>>>> >>>>>> Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan >>>>>> Bateman and others who have provided advices and help on the matter >>>>>> before. >>>>>> >>>>>> Any insights/comments are wholeheartedly welcome. >>>>>> >>>>>> Thanks, >>>>>> Jan >>>>> >>> From jan.lahoda at oracle.com Wed May 27 12:23:12 2015 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Wed, 27 May 2015 14:23:12 +0200 Subject: JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version In-Reply-To: <5565958A.1040807@oracle.com> References: <555D82CC.9070105@oracle.com> <555DB419.6020301@oracle.com> <555F232E.1060105@oracle.com> <555F2692.5030002@oracle.com> <555F2D9F.2090505@oracle.com> <5565906D.1050400@oracle.com> <5565958A.1040807@oracle.com> Message-ID: <5565B730.5030602@oracle.com> Ah, yes, I did not realize that. Thanks, will fix. Thanks, Jan On 27.5.2015 11:59, Maurizio Cimadamore wrote: > Looks great. The only nitpick is that the comments in CreateSymbols > don't mention the fact that a side effect of the sym.txt generation is > the mentioned earlier in the same comments > (so one might wonder where does that come from). > > Maurizio > > On 27/05/15 10:37, Jan Lahoda wrote: >> Hi, >> >> I've uploaded another iteration, with these changes: >> -the "symbols" file is now generated automatically (for the typical >> OpenJDK case). >> -fixed a minor issue in CreateSymbols that could cause putting class >> description into wrong a file (the "break" -> "break OUTER;" change). >> -jdk.management module has been split out from java.management >> recently, so splitting the corresponding .sym.txt files into >> java.management and jdk.management as well. >> -updating the copyright year in CreateSymbols, as noted by Magnus. >> >> Webrevs: >> -top-level: >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.02/top-level/ >> -langtools (no changes against the last webrev): >> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.02/langtools/ >> >> Delta webrevs against the previous iteration are included under >> "Author comments". >> >> Thanks for the comments so far! >> >> Jan >> >> On 22.5.2015 15:22, Jan Lahoda wrote: >>> On 22.5.2015 14:52, Maurizio Cimadamore wrote: >>>> Excellent work. >>>> >>>> I think the comment in CreateSymbols could be made clearer w.r.t. Probe >>>> - i.e. that Probe should be ran on top of the JDK N - i.e. >>>> >>>> /bin/java Probe --> classes-8 >>>> /bin/java Probe --> classes-7 >>>> /bin/java Probe --> classes-7 >>>> >>>> etc. >>> >>> Sure, will do. >>> >>> I'll also look at generating the make/data/symbols/symbols descriptions >>> automatically, per our offline discussion. >>> >>> Thanks! >>> >>> Jan >>> >>>> >>>> Maurizio >>>> >>>> On 22/05/15 13:38, Jan Lahoda wrote: >>>>> Hi, >>>>> >>>>> I've uploaded a new iteration of the patch(es): >>>>> top-level repository: >>>>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/top-level/ >>>>> langtools: >>>>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.01/langtools/ >>>>> >>>>> (besides full webrevs, there are also webrevs showing the differences >>>>> between .00 and .01 available - see the "Delta webrev" link under >>>>> "Author's comments") >>>>> >>>>> Summary of changes: >>>>> -applied Eric's build changes >>>>> -moved CreateSymbols into make/src/classes/build/tools/symbolgenerator >>>>> -tried to improve the specification of base platforms in >>>>> CreateSymbols, per Maurizio's comment >>>>> -other cleanup in langtools per Maurizio's comments. >>>>> >>>>> Thanks, >>>>> Jan >>>>> >>>>> On 21.5.2015 12:31, Maurizio Cimadamore wrote: >>>>>> Hi Jan, >>>>>> great work - couple of comments below: >>>>>> >>>>>> * it seems like some of the routines in Arguments can be simplified >>>>>> using lambdas - especially lookupPlatformProvider and >>>>>> checkOptionAllowed >>>>>> * Why JDKPlatformProvider is not called >>>>>> JDKPlatformProvider*Factory* ? >>>>>> * JavacProcessingEnvironment.JoiningIterator seems to have >>>>>> commonalities >>>>>> with CompoundScopeIterator - any chance that we might refactor this a >>>>>> bit? >>>>>> * What's the rationale for giving an error if -platform is specified >>>>>> and >>>>>> a non-StandardFileManager is provided? Can't we simply swallow that, >>>>>> ignore the platform settings and issue a Lint 'options' warning? >>>>>> * Would it make sense for some of the classfile generation logic in >>>>>> CreateSymbols to be moved under the classfile API ? >>>>>> * I had hard time reconciling some of the comments in CreateSymbols >>>>>> with >>>>>> how the files were laid out. I think in the end, what you mean is >>>>>> that >>>>>> if you have platforms 7, 8, 9 - you should pick one baseline (i.e. 8) >>>>>> and then generate diffs for 9 and 7 against the 8 one. If that's the >>>>>> use >>>>>> case, I think the command line can be simplified a bit in order to >>>>>> explicitly state which of the platform is the baseline one, and the >>>>>> remaining parameters can be inferred from the tool (as the >>>>>> seem to be typically all >>>>>> identical >>>>>> but one which is set to - the one for the baseline). Maybe the >>>>>> inference logic should be different (i.e. use 8 as a baseline for >>>>>> 7 and >>>>>> 7 as a baseline for 6) - but - whatever the logic, I think it >>>>>> should be >>>>>> chosen once and for all, and live implicitly in the tool? Or are >>>>>> there >>>>>> reasons as to why it might be handy to customize the baselines? >>>>>> >>>>>> Maurizio >>>>>> >>>>>> On 21/05/15 08:01, Jan Lahoda wrote: >>>>>>> Hi, >>>>>>> >>>>>>> This is a patch adding a new option, -platform, to javac. >>>>>>> >>>>>>> Patch for the top-level repository is here: >>>>>>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/top-level/ >>>>>>> >>>>>>> Patch for the langtools repository is here: >>>>>>> http://cr.openjdk.java.net/~jlahoda/8072480/webrev.00/langtools/ >>>>>>> >>>>>>> These changes also require additional langtools changes as their >>>>>>> prerequisite: >>>>>>> http://cr.openjdk.java.net/~jlahoda/8080675/webrev.00/ >>>>>>> >>>>>>> Overall, one can imagine '-platform N' to have the same effect as >>>>>>> '-source N -target N -bootclasspath '. The possible >>>>>>> values >>>>>>> for 'N' are pluggable in a limited way, though (see >>>>>>> langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/PlatformProvider.java). >>>>>>> >>>>>>> >>>>>>> >>>>>>> Note that this patch only introduces N=7 and N=8, which >>>>>>> correspond to >>>>>>> Open JDK 7 and 8 GA. >>>>>>> >>>>>>> A tricky problem to solve is where to get the APIs for platform >>>>>>> N. The >>>>>>> proposal is to include history data in the textual format inside the >>>>>>> OpenJDK repositories (the input data), process them at build time >>>>>>> and >>>>>>> create a lib/ct.sym file holding the data in the JDK image. javac >>>>>>> running with the -platform option then compiles against the >>>>>>> lib/ct.sym >>>>>>> file. The input history data are placed >>>>>>> /make/data/symbols (the sym.txt files). This >>>>>>> patches only includes data for OpenJDK 7 and 8, and only for public >>>>>>> APIs (more or less Java SE and JDK @Exported APIs). >>>>>>> >>>>>>> The size of the history data is currently ~6MB in the JDK >>>>>>> checkout and >>>>>>> ~650kB inside the .hg directory (the size could change significantly >>>>>>> if additional classes/elements, like non-public API classes, would >>>>>>> need to be included). The lib/ct.sym file is currently ~4.5MB. >>>>>>> >>>>>>> The ct.sym file is a zip file containing signature files. The >>>>>>> signature files are similar to classfiles (so javac can read them as >>>>>>> classfiles), but are missing some attributes, most notably the Code >>>>>>> attribute. On the top-level, the ct.sym contains directories named >>>>>>> "7", "78" and "8". When compiling for version 'N', the bootclasspath >>>>>>> for that version is obtained by using directories which have 'N' in >>>>>>> their name. >>>>>>> >>>>>>> The sigfiles for ct.sym are created by >>>>>>> /make/tools/symbolgenerator/CreateSymbols.java. >>>>>>> >>>>>>> The same file can also be used to construct the sym.txt files. >>>>>>> Concise >>>>>>> instructions are part of the CreateSymbols.java. >>>>>>> >>>>>>> I am sending this as one review, as the changes together make one >>>>>>> feature, but the langtools and top-level changes are independent >>>>>>> to a >>>>>>> great degree: the langtools changes add the "-platform" javac; >>>>>>> and the >>>>>>> top-level changes add the history data and ability to build the >>>>>>> ct.sym >>>>>>> file. If desired, these could be pushed and/or reviewed >>>>>>> independently. >>>>>>> >>>>>>> Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan >>>>>>> Bateman and others who have provided advices and help on the matter >>>>>>> before. >>>>>>> >>>>>>> Any insights/comments are wholeheartedly welcome. >>>>>>> >>>>>>> Thanks, >>>>>>> Jan >>>>>> >>>> > From georgiy.rakov at oracle.com Wed May 27 15:36:02 2015 From: georgiy.rakov at oracle.com (Georgiy Rakov) Date: Wed, 27 May 2015 18:36:02 +0300 Subject: Field of wildcard parameterized class is passed to anonymous class created with diamond; JDK bug? In-Reply-To: <55532253.8050907@oracle.com> References: <5551FEBE.7000908@oracle.com> <5552CAE4.4050003@oracle.com> <55532253.8050907@oracle.com> Message-ID: <5565E462.8000003@oracle.com> I filed the issue for this case: https://bugs.openjdk.java.net/browse/JDK-8081318 Thank you, Gerogiy. On 13.05.2015 13:07, Maurizio Cimadamore wrote: > This is indeed long-standing javac behavior - also commented in the code: > > /** > * javac has a long-standing 'simplification' (see 6391995): > * given an actual argument type, the method check is performed > * on its upper bound. This leads to inconsistencies when an > * argument type is checked against itself. For example, given > * a type-variable T, it is not true that {@codeU(T)<: T}, > * so we need to guard against that. > */ > > At some point this should be cleaned up - but there could be > non-trivial compatibility concerns there. > > Maurizio > > On 13/05/15 04:54, Srikanth wrote: >> Hi Georgiy, >> >> Thanks for the test case. >> >> This seems to be long standing behaviour in javac inference that >> surfaces with <> only when combined with anonymous classes. >> >> With diamond and with or without anonymous classes, >> >> i.e in both >> >> newCls<>(a.f); >> newCls<>(a.f) {} >> >> >> the elided type is inferred to be jlO and hence we don't report an error. >> >> I will double check whether inference is doing the right thing here. I see >> that ECJ infers the elided type to be Cls >> >> I'll either post a concluding clarification or raise a suitable JBS ticket to >> follow up. >> >> Thanks! >> Srikanth >> On Tuesday 12 May 2015 06:53 PM, Georgiy Rakov wrote: >>> Hello, >>> >>> let's consider following example: >>> >>> classPar { >>> Uf; >>> } >>> >>> classCls { >>> Cls(Tt) {} >>> } >>> >>> public classTest70 { >>> public static voidtest() { >>> Par a =newPar<>(); >>> newCls<>(a.f) { }; >>> } >>> } >>> >>> JDK9b60 compiles it successfully however according to my >>> understanding compilation should have failed because: >>> >>> 1. The type of 'a' local variable is a parameterized type Par. >>> 2. According to following assertion from JLS 4.5.2 the type of the >>> field "f" of Par is a fresh capture variable: null-type <: CAP <: >>> Object: >>> >>> If any of the type arguments in the parameterization of Care >>> wildcards, then: >>> >>> o >>> >>> The types of the fields, methods, and constructors in >>> C|<|T_1 ,...,T_n |>|are the types of the fields, methods, >>> and constructors in the capture conversion of C|<|T_1 >>> ,...,T_n |>|(?5.1.10 >>> ). >>> >>> >>> 3. 'new Cls<>(a.f) { }' causes T to be inferred as capture variable >>> CAP presented in step 2. >>> 4. According to following new assertion presented in JDK-8073593 >>> issue comment >>> compilation >>> error should occur because superclass of the anonymous class is >>> inferred as a type parameterized by type variable that was not >>> declared as a type parameter (the capture variable CAP). >>> >>> ***/_*It is a compile-time error*_/ if the superclass or >>> superinterface type of the anonymous class, T, or any >>> subexpression of T, has one of the following forms: >>> - A /_*type variable (4.4) that was not declared as a type >>> parameter*_/ (such as /_*a type variable produced by capture >>> conversion*_/ (5.1.10)) >>> - An intersection type (4.9) >>> - A class or interface type, where the class or interface >>> declaration is not accessible from the class or interface in >>> which the expression appears.*** >>> The term "subexpression" includes type arguments of >>> parameterized types (4.5), bounds of wildcards (4.5.1), and >>> element types of array types (10.1). It excludes bounds of type >>> variables.*** >>> >>> Could you please tell if you agree that this is really a JDK bug. >>> >>> Thank you, >>> Georgiy. >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From aleksey.shipilev at oracle.com Thu May 28 21:22:50 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Fri, 29 May 2015 00:22:50 +0300 Subject: String concatenation tweaks In-Reply-To: <556475CF.8090406@univ-mlv.fr> References: <55014F7C.20201@oracle.com> <553139FA.20601@oracle.com> <55313D3A.10008@univ-mlv.fr> <55551C6F.4000704@oracle.com> <555DCC4D.8040505@oracle.com> <7CDF6C9C-90CE-4D93-9290-10D9CCC29BB9@univ-mlv.fr> <555EE8F7.5040007@oracle.com> <5561EF32.8080101@univ-mlv.fr> <556371A0.80600@oracle.com> <556475CF.8090406@univ-mlv.fr> Message-ID: <5567872A.2080902@oracle.com> On 05/26/2015 04:31 PM, Remi Forax wrote: > On 05/25/2015 09:01 PM, Aleksey Shipilev wrote: >> The performance is interesting. It seems to break OptimizeStringConcat, >> and so it's a performance win only on non-optimized chains, like >> string_string_long. The allocation pressure is slightly higher as well, >> seems to be because int[] from the collector is not scalarized. > > I wonder if the two things are not related, fail to unroll -> creation > of int[] -> non constant value for the StringBuilder constructor -> > break of OptimizeStringConcat optimization. Merged: http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/ It seems OptimizeStringConcat expects a particular C2 IR graph shape, and it might be hard to reproduce on MHs. Anyhow, your new FULL_MH now performs the same as INNER_SIZED when OptimizeStringConcat fails, both throughput-performance- and allocation-wise on small count of int arguments. Please note I added a simple regression test, and munged the code to make it pass. StringBuilder::append overloads are not present for every type, and also we need to bypass StringBuffers/CharSequences. It would seem INNER_SIZED is a good strategy to default to, and subsequent JDK improvements can be done after the infrastructure lands. The whole point for this change is to open the door for these improvements. Meanwhile, I put together a very rough JEP draft here, and I would appreciate comments and corrections: http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/jep.txt Thanks, -Aleksey -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From peter.levart at gmail.com Sun May 31 20:58:38 2015 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 31 May 2015 22:58:38 +0200 Subject: String concatenation tweaks In-Reply-To: <5567872A.2080902@oracle.com> References: <55014F7C.20201@oracle.com> <553139FA.20601@oracle.com> <55313D3A.10008@univ-mlv.fr> <55551C6F.4000704@oracle.com> <555DCC4D.8040505@oracle.com> <7CDF6C9C-90CE-4D93-9290-10D9CCC29BB9@univ-mlv.fr> <555EE8F7.5040007@oracle.com> <5561EF32.8080101@univ-mlv.fr> <556371A0.80600@oracle.com> <556475CF.8090406@univ-mlv.fr> <5567872A.2080902@oracle.com> Message-ID: <556B75FE.8060605@gmail.com> On 05/28/2015 11:22 PM, Aleksey Shipilev wrote: > On 05/26/2015 04:31 PM, Remi Forax wrote: >> On 05/25/2015 09:01 PM, Aleksey Shipilev wrote: >>> The performance is interesting. It seems to break OptimizeStringConcat, >>> and so it's a performance win only on non-optimized chains, like >>> string_string_long. The allocation pressure is slightly higher as well, >>> seems to be because int[] from the collector is not scalarized. >> I wonder if the two things are not related, fail to unroll -> creation >> of int[] -> non constant value for the StringBuilder constructor -> >> break of OptimizeStringConcat optimization. > Merged: > http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/ > > It seems OptimizeStringConcat expects a particular C2 IR graph shape, > and it might be hard to reproduce on MHs. Anyhow, your new FULL_MH now > performs the same as INNER_SIZED when OptimizeStringConcat fails, both > throughput-performance- and allocation-wise on small count of int arguments. > > Please note I added a simple regression test, and munged the code to > make it pass. StringBuilder::append overloads are not present for every > type, and also we need to bypass StringBuffers/CharSequences. > > It would seem INNER_SIZED is a good strategy to default to, and > subsequent JDK improvements can be done after the infrastructure lands. > The whole point for this change is to open the door for these > improvements. Meanwhile, I put together a very rough JEP draft here, and > I would appreciate comments and corrections: > http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/jep.txt > > Thanks, > -Aleksey Hi, This is a noble goal. I will just warn you about the possible initialization problems. String concatenation is a very rudimentary operation and might be used very early in the startup of the JVM. If it is used before the system class loader is initialized (before the main method is executed), you will be faced with the following issue at least: http://mail.openjdk.java.net/pipermail/mlvm-dev/2015-March/006386.html ...so we might need to fix these early java.lang.invoke initialization problems 1st. Regards, Peter -------------- next part -------------- An HTML attachment was scrubbed... URL: From peter.levart at gmail.com Sun May 31 21:06:18 2015 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 31 May 2015 23:06:18 +0200 Subject: String concatenation tweaks In-Reply-To: <556B75FE.8060605@gmail.com> References: <55014F7C.20201@oracle.com> <553139FA.20601@oracle.com> <55313D3A.10008@univ-mlv.fr> <55551C6F.4000704@oracle.com> <555DCC4D.8040505@oracle.com> <7CDF6C9C-90CE-4D93-9290-10D9CCC29BB9@univ-mlv.fr> <555EE8F7.5040007@oracle.com> <5561EF32.8080101@univ-mlv.fr> <556371A0.80600@oracle.com> <556475CF.8090406@univ-mlv.fr> <5567872A.2080902@oracle.com> <556B75FE.8060605@gmail.com> Message-ID: <556B77CA.4050307@gmail.com> On 05/31/2015 10:58 PM, Peter Levart wrote: > > > On 05/28/2015 11:22 PM, Aleksey Shipilev wrote: >> On 05/26/2015 04:31 PM, Remi Forax wrote: >>> On 05/25/2015 09:01 PM, Aleksey Shipilev wrote: >>>> The performance is interesting. It seems to break OptimizeStringConcat, >>>> and so it's a performance win only on non-optimized chains, like >>>> string_string_long. The allocation pressure is slightly higher as well, >>>> seems to be because int[] from the collector is not scalarized. >>> I wonder if the two things are not related, fail to unroll -> creation >>> of int[] -> non constant value for the StringBuilder constructor -> >>> break of OptimizeStringConcat optimization. >> Merged: >> http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/ >> >> It seems OptimizeStringConcat expects a particular C2 IR graph shape, >> and it might be hard to reproduce on MHs. Anyhow, your new FULL_MH now >> performs the same as INNER_SIZED when OptimizeStringConcat fails, both >> throughput-performance- and allocation-wise on small count of int arguments. >> >> Please note I added a simple regression test, and munged the code to >> make it pass. StringBuilder::append overloads are not present for every >> type, and also we need to bypass StringBuffers/CharSequences. >> >> It would seem INNER_SIZED is a good strategy to default to, and >> subsequent JDK improvements can be done after the infrastructure lands. >> The whole point for this change is to open the door for these >> improvements. Meanwhile, I put together a very rough JEP draft here, and >> I would appreciate comments and corrections: >> http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/jep.txt >> >> Thanks, >> -Aleksey > > Hi, > > This is a noble goal. I will just warn you about the possible > initialization problems. String concatenation is a very rudimentary > operation and might be used very early in the startup of the JVM. If > it is used before the system class loader is initialized (before the > main method is executed), you will be faced with the following issue > at least: > > http://mail.openjdk.java.net/pipermail/mlvm-dev/2015-March/006386.html > > ...so we might need to fix these early java.lang.invoke initialization > problems 1st. Not to mention that java.lang.invoke infrastructure (at least the part that is used to support invokedynamic etc.) should then *not* use string concatenation... > > Regards, Peter > -------------- next part -------------- An HTML attachment was scrubbed... URL: From peter.levart at gmail.com Sun May 31 21:33:50 2015 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 31 May 2015 23:33:50 +0200 Subject: String concatenation tweaks In-Reply-To: <556B77CA.4050307@gmail.com> References: <55014F7C.20201@oracle.com> <553139FA.20601@oracle.com> <55313D3A.10008@univ-mlv.fr> <55551C6F.4000704@oracle.com> <555DCC4D.8040505@oracle.com> <7CDF6C9C-90CE-4D93-9290-10D9CCC29BB9@univ-mlv.fr> <555EE8F7.5040007@oracle.com> <5561EF32.8080101@univ-mlv.fr> <556371A0.80600@oracle.com> <556475CF.8090406@univ-mlv.fr> <5567872A.2080902@oracle.com> <556B75FE.8060605@gmail.com> <556B77CA.4050307@gmail.com> Message-ID: <556B7E3E.8050707@gmail.com> On 05/31/2015 11:06 PM, Peter Levart wrote: > > > On 05/31/2015 10:58 PM, Peter Levart wrote: >> >> >> On 05/28/2015 11:22 PM, Aleksey Shipilev wrote: >>> On 05/26/2015 04:31 PM, Remi Forax wrote: >>>> On 05/25/2015 09:01 PM, Aleksey Shipilev wrote: >>>>> The performance is interesting. It seems to break OptimizeStringConcat, >>>>> and so it's a performance win only on non-optimized chains, like >>>>> string_string_long. The allocation pressure is slightly higher as well, >>>>> seems to be because int[] from the collector is not scalarized. >>>> I wonder if the two things are not related, fail to unroll -> creation >>>> of int[] -> non constant value for the StringBuilder constructor -> >>>> break of OptimizeStringConcat optimization. >>> Merged: >>> http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/ >>> >>> It seems OptimizeStringConcat expects a particular C2 IR graph shape, >>> and it might be hard to reproduce on MHs. Anyhow, your new FULL_MH now >>> performs the same as INNER_SIZED when OptimizeStringConcat fails, both >>> throughput-performance- and allocation-wise on small count of int arguments. >>> >>> Please note I added a simple regression test, and munged the code to >>> make it pass. StringBuilder::append overloads are not present for every >>> type, and also we need to bypass StringBuffers/CharSequences. >>> >>> It would seem INNER_SIZED is a good strategy to default to, and >>> subsequent JDK improvements can be done after the infrastructure lands. >>> The whole point for this change is to open the door for these >>> improvements. Meanwhile, I put together a very rough JEP draft here, and >>> I would appreciate comments and corrections: >>> http://cr.openjdk.java.net/~shade/scratch/string-concat-indy/jep.txt >>> >>> Thanks, >>> -Aleksey >> >> Hi, >> >> This is a noble goal. I will just warn you about the possible >> initialization problems. String concatenation is a very rudimentary >> operation and might be used very early in the startup of the JVM. If >> it is used before the system class loader is initialized (before the >> main method is executed), you will be faced with the following issue >> at least: >> >> http://mail.openjdk.java.net/pipermail/mlvm-dev/2015-March/006386.html >> >> ...so we might need to fix these early java.lang.invoke >> initialization problems 1st. > > Not to mention that java.lang.invoke infrastructure (at least the part > that is used to support invokedynamic etc.) should then *not* use > string concatenation... One way to tackle this is to have a javac option to emit classical StringBuilder-based code and then build the (java.base module at least) with this option. So only other modules and user code would use indy based concatenation. This will also eliminate worries about startup time. But code in java.base module would then not be able to benefit from possible improvements in indy based concatenation. Do we need a minimal java.kernel module which would include just java.lang.invoke and it's dependencies? Peter -------------- next part -------------- An HTML attachment was scrubbed... URL: