From jan.lahoda at oracle.com Mon Oct 2 15:35:33 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Mon, 2 Oct 2017 17:35:33 +0200 Subject: RFR JDK-8188225: AST could be improved in presence of var types. Message-ID: <59D25CC5.5080809@oracle.com> Hello, JShell produces not ideal errors related to local variable type inference in some cases: --- jshell> var i = () -> {}; | Error: | incompatible types: java.lang.Object is not a functional interface | var i = () -> {}; | ^------^ --- Better would be: --- jshell> var i = () -> {}; | Error: | cannot infer type for local variable i | (lambda expression needs an explicit target-type) | var i = () -> {}; | ^---------------^ --- (which is the error produced by javac) The AST model could also be improved for local variables whose type have been inferred (which also improves the jshell errors in some cases): - for "var i = 0;", the VariableTree.getType() will be null even after attribution, but for: "for (var i : Arrays.asList(0, 1)) {}", the VariableTree.getType() will be filled in by Attr. (The inferred type is also filled in for lambda parameters.) This is not only inconsistent, but also Attr.PostAttrAnalyzer.visitVarDef may fill in the type with an ErroneousTree (with a wrong position). The proposal here is to always fill in the type for consistency, and to consistently use NOPOS for the synthetic type position -for "var i = 0;" SourcePositions.getStartPosition does not return a proper starting position (the position of "var"), but rather the position of the synthetic type, if any (which can also be ErroneousTree) or the position of the variable name. The proposal here is to remember the real start of the variable and return it. Bug: https://bugs.openjdk.java.net/browse/JDK-8188225 Webrev: http://cr.openjdk.java.net/~jlahoda/8188225/webrev.00/index.html What do you think? Thanks, Jan From maurizio.cimadamore at oracle.com Mon Oct 2 18:06:46 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 2 Oct 2017 19:06:46 +0100 Subject: RFR 8063054: Incorrect raw type warning for method reference Message-ID: <0da5979f-2c3c-c3d2-f7f5-230bf139ac08@oracle.com> Hi, here's a patch for a problem with spurious raw type warnings generated when checking unbound method references: http://cr.openjdk.java.net/~mcimadamore/8063054/ This has actually been discussed few months ago, so I don't expect many surprises :-) http://mail.openjdk.java.net/pipermail/compiler-dev/2017-February/010815.html http://mail.openjdk.java.net/pipermail/compiler-dev/2017-March/010888.html Sorry for the delay. Cheers Maurizio -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsrbnd at gmail.com Mon Oct 2 18:40:52 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Mon, 2 Oct 2017 20:40:52 +0200 Subject: RFR 8063054: Incorrect raw type warning for method reference In-Reply-To: <0da5979f-2c3c-c3d2-f7f5-230bf139ac08@oracle.com> References: <0da5979f-2c3c-c3d2-f7f5-230bf139ac08@oracle.com> Message-ID: Looks good! Cheers, Bernard On 2 October 2017 at 20:06, Maurizio Cimadamore wrote: > Hi, > here's a patch for a problem with spurious raw type warnings generated when > checking unbound method references: > > http://cr.openjdk.java.net/~mcimadamore/8063054/ > > This has actually been discussed few months ago, so I don't expect many > surprises :-) > > http://mail.openjdk.java.net/pipermail/compiler-dev/2017-February/010815.html > http://mail.openjdk.java.net/pipermail/compiler-dev/2017-March/010888.html > > Sorry for the delay. > > Cheers > Maurizio > > From maurizio.cimadamore at oracle.com Tue Oct 3 15:59:41 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 3 Oct 2017 16:59:41 +0100 Subject: RFR JDK-8188225: AST could be improved in presence of var types. In-Reply-To: <59D25CC5.5080809@oracle.com> References: <59D25CC5.5080809@oracle.com> Message-ID: <5ffd68fa-6455-b412-351f-54778be3cf4a@oracle.com> Thanks for taking care of this, I have a couple of suggestion: * the routine for generating synthetic type tree should be shared. E.g. you need a method that takes a type and generates something that is suitable for a local variable or a lambda parameter - e.g. toSyntheticTypeTree(Type t) { ?? if (t.isErroneous()) { ?? ?? return make.at(Position.NOPOS).Erroneous(); ?? } else { ????? return make.at(Position.NOPOS).Type(t); ?? } } * secondly, while adding the startpos tree is fine - here it seems like we morally would like to override the getStartPosition for the synthetic type trees created above, so that the former position is returned (e.g. that of 'var'). So, I wonder if something like this could work: toSyntheticTypeTree(Type t, int preferredPos) { ?? if (t.isErroneous()) { ?? ?? return make.at(preferredPos).Erroneous(); ?? } else { ????? return make.at(preferredPos).Type(t); ?? } } Then, assuming the parser creates the local variable node with the correct pos (which it doesn't now), I think everything should work even w/o a dedicated field? Maurizio On 02/10/17 16:35, Jan Lahoda wrote: > Hello, > > JShell produces not ideal errors related to local variable type > inference in some cases: > --- > jshell> var i = () -> {}; > |? Error: > |? incompatible types: java.lang.Object is not a functional interface > |? var i = () -> {}; > |????????? ^------^ > --- > > Better would be: > --- > jshell> var i = () -> {}; > |? Error: > |? cannot infer type for local variable i > |??? (lambda expression needs an explicit target-type) > |? var i = () -> {}; > |? ^---------------^ > --- > > (which is the error produced by javac) > > The AST model could also be improved for local variables whose type > have been inferred (which also improves the jshell errors in some cases): > - for "var i = 0;", the VariableTree.getType() will be null even after > attribution, but for: "for (var i : Arrays.asList(0, 1)) {}", the > VariableTree.getType() will be filled in by Attr. (The inferred type > is also filled in for lambda parameters.) This is not only > inconsistent, but also Attr.PostAttrAnalyzer.visitVarDef may fill in > the type with an ErroneousTree (with a wrong position). The proposal > here is to always fill in the type for consistency, and to > consistently use NOPOS for the synthetic type position > > -for "var i = 0;" SourcePositions.getStartPosition does not return a > proper starting position (the position of "var"), but rather the > position of the synthetic type, if any (which can also be > ErroneousTree) or the position of the variable name. The proposal here > is to remember the real start of the variable and return it. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8188225 > Webrev: http://cr.openjdk.java.net/~jlahoda/8188225/webrev.00/index.html > > What do you think? > > Thanks, > ??? Jan From jan.lahoda at oracle.com Tue Oct 3 17:53:46 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Tue, 3 Oct 2017 19:53:46 +0200 Subject: RFR JDK-8188225: AST could be improved in presence of var types. In-Reply-To: <5ffd68fa-6455-b412-351f-54778be3cf4a@oracle.com> References: <59D25CC5.5080809@oracle.com> <5ffd68fa-6455-b412-351f-54778be3cf4a@oracle.com> Message-ID: <59D3CEAA.5010302@oracle.com> Hi Maurizio, Thanks for the comments - some responses inline. On 3.10.2017 17:59, Maurizio Cimadamore wrote: > Thanks for taking care of this, I have a couple of suggestion: > > * the routine for generating synthetic type tree should be shared. E.g. > you need a method that takes a type and generates something that is > suitable for a local variable or a lambda parameter - e.g. > > toSyntheticTypeTree(Type t) { > if (t.isErroneous()) { > return make.at(Position.NOPOS).Erroneous(); > } else { > return make.at(Position.NOPOS).Type(t); > } > } Sure, will do. > > * secondly, while adding the startpos tree is fine - here it seems like > we morally would like to override the getStartPosition for the synthetic > type trees created above, so that the former position is returned (e.g. > that of 'var'). So, I wonder if something like this could work: > > toSyntheticTypeTree(Type t, int preferredPos) { > if (t.isErroneous()) { > return make.at(preferredPos).Erroneous(); > } else { > return make.at(preferredPos).Type(t); > } > } > > Then, assuming the parser creates the local variable node with the > correct pos (which it doesn't now), I think everything should work even Hm, you mean put the starting position to the JCVariableDecl.pos? If that would be the value, we could surely avoid the field, but AFAIK the JCVariableDecl.pos usually points to the name of the variable, and I didn't want to add an inconsistency, or change that (as the position is useful for error reporting), Alternatives I was thinking of included playing tricks with modifiers (setting the position to modifiers (if there are no/empty modifiers) and filtering it in getStartPos), with nameexpr or having a subclass of JCVariableDecl for vars which would include the extra field. (I was also trying to have -1 as the position of the synthetic type to aid its detection, but it could still be detected by looking at the end position, so this is not that big deal.) Thanks, Jan > w/o a dedicated field? > > Maurizio > > > > > On 02/10/17 16:35, Jan Lahoda wrote: >> Hello, >> >> JShell produces not ideal errors related to local variable type >> inference in some cases: >> --- >> jshell> var i = () -> {}; >> | Error: >> | incompatible types: java.lang.Object is not a functional interface >> | var i = () -> {}; >> | ^------^ >> --- >> >> Better would be: >> --- >> jshell> var i = () -> {}; >> | Error: >> | cannot infer type for local variable i >> | (lambda expression needs an explicit target-type) >> | var i = () -> {}; >> | ^---------------^ >> --- >> >> (which is the error produced by javac) >> >> The AST model could also be improved for local variables whose type >> have been inferred (which also improves the jshell errors in some cases): >> - for "var i = 0;", the VariableTree.getType() will be null even after >> attribution, but for: "for (var i : Arrays.asList(0, 1)) {}", the >> VariableTree.getType() will be filled in by Attr. (The inferred type >> is also filled in for lambda parameters.) This is not only >> inconsistent, but also Attr.PostAttrAnalyzer.visitVarDef may fill in >> the type with an ErroneousTree (with a wrong position). The proposal >> here is to always fill in the type for consistency, and to >> consistently use NOPOS for the synthetic type position >> >> -for "var i = 0;" SourcePositions.getStartPosition does not return a >> proper starting position (the position of "var"), but rather the >> position of the synthetic type, if any (which can also be >> ErroneousTree) or the position of the variable name. The proposal here >> is to remember the real start of the variable and return it. >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8188225 >> Webrev: http://cr.openjdk.java.net/~jlahoda/8188225/webrev.00/index.html >> >> What do you think? >> >> Thanks, >> Jan > From maurizio.cimadamore at oracle.com Tue Oct 3 17:58:56 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 3 Oct 2017 18:58:56 +0100 Subject: RFR JDK-8188225: AST could be improved in presence of var types. In-Reply-To: <59D3CEAA.5010302@oracle.com> References: <59D25CC5.5080809@oracle.com> <5ffd68fa-6455-b412-351f-54778be3cf4a@oracle.com> <59D3CEAA.5010302@oracle.com> Message-ID: On 03/10/17 18:53, Jan Lahoda wrote: > Hi Maurizio, > > Thanks for the comments - some responses inline. > > On 3.10.2017 17:59, Maurizio Cimadamore wrote: >> Thanks for taking care of this, I have a couple of suggestion: >> >> * the routine for generating synthetic type tree should be shared. E.g. >> you need a method that takes a type and generates something that is >> suitable for a local variable or a lambda parameter - e.g. >> >> toSyntheticTypeTree(Type t) { >> ??? if (t.isErroneous()) { >> ?????? return make.at(Position.NOPOS).Erroneous(); >> ??? } else { >> ?????? return make.at(Position.NOPOS).Type(t); >> ??? } >> } > > Sure, will do. > >> >> * secondly, while adding the startpos tree is fine - here it seems like >> we morally would like to override the getStartPosition for the synthetic >> type trees created above, so that the former position is returned (e.g. >> that of 'var'). So, I wonder if something like this could work: >> >> toSyntheticTypeTree(Type t, int preferredPos) { >> ??? if (t.isErroneous()) { >> ?????? return make.at(preferredPos).Erroneous(); >> ??? } else { >> ?????? return make.at(preferredPos).Type(t); >> ??? } >> } >> >> Then, assuming the parser creates the local variable node with the >> correct pos (which it doesn't now), I think everything should work even > > Hm, you mean put the starting position to the JCVariableDecl.pos? If > that would be the value, we could surely avoid the field, but AFAIK > the JCVariableDecl.pos usually points to the name of the variable, and > I didn't want to add an inconsistency, or change that (as the position > is useful for error reporting), > > Alternatives I was thinking of included playing tricks with modifiers > (setting the position to modifiers (if there are no/empty modifiers) > and filtering it in getStartPos), with nameexpr or having a subclass > of JCVariableDecl for vars which would include the extra field. I see good points. I also thought about using a tree copier, but that also goes through TreeMaker, which makes it hard to e.g. create anon tree instances which override getStartPosition. No bother - your original solution is good enough, at least for now. I appreciate that the new pos field is just for var AST nodes. Maurizio > > (I was also trying to have -1 as the position of the synthetic type to > aid its detection, but it could still be detected by looking at the > end position, so this is not that big deal.) > > Thanks, > ??? Jan > >> w/o a dedicated field? >> >> Maurizio >> >> >> >> >> On 02/10/17 16:35, Jan Lahoda wrote: >>> Hello, >>> >>> JShell produces not ideal errors related to local variable type >>> inference in some cases: >>> --- >>> jshell> var i = () -> {}; >>> |? Error: >>> |? incompatible types: java.lang.Object is not a functional interface >>> |? var i = () -> {}; >>> |????????? ^------^ >>> --- >>> >>> Better would be: >>> --- >>> jshell> var i = () -> {}; >>> |? Error: >>> |? cannot infer type for local variable i >>> |??? (lambda expression needs an explicit target-type) >>> |? var i = () -> {}; >>> |? ^---------------^ >>> --- >>> >>> (which is the error produced by javac) >>> >>> The AST model could also be improved for local variables whose type >>> have been inferred (which also improves the jshell errors in some >>> cases): >>> - for "var i = 0;", the VariableTree.getType() will be null even after >>> attribution, but for: "for (var i : Arrays.asList(0, 1)) {}", the >>> VariableTree.getType() will be filled in by Attr. (The inferred type >>> is also filled in for lambda parameters.) This is not only >>> inconsistent, but also Attr.PostAttrAnalyzer.visitVarDef may fill in >>> the type with an ErroneousTree (with a wrong position). The proposal >>> here is to always fill in the type for consistency, and to >>> consistently use NOPOS for the synthetic type position >>> >>> -for "var i = 0;" SourcePositions.getStartPosition does not return a >>> proper starting position (the position of "var"), but rather the >>> position of the synthetic type, if any (which can also be >>> ErroneousTree) or the position of the variable name. The proposal here >>> is to remember the real start of the variable and return it. >>> >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8188225 >>> Webrev: >>> http://cr.openjdk.java.net/~jlahoda/8188225/webrev.00/index.html >>> >>> What do you think? >>> >>> Thanks, >>> ??? Jan >> From bsrbnd at gmail.com Tue Oct 3 21:05:09 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Tue, 3 Oct 2017 23:05:09 +0200 Subject: Complexity reduction when choosing the best inference leaf to be solved Message-ID: Hi, While exploring the implementation of the inference graph along with the solving system, I noticed that the complexity of the heuristic used to choose the best leaf to be solved could probably be reduced in three ways: 1) When an optimal leaf is found with only one ivar to be solved, there's no need to evaluate other subtrees. 2) When computing a subtree heuristic, if the path being evaluated appears to be worth than the best subtree so far, it isn't necessary to keep on evaluating this possibility. 3) Let 'n' be the number of inference graph nodes and 'v' be the number of variables to be solved (for example when inferring the types of lambda parameters). Retrieving all the nodes of a graph corresponding to a list of inference variables to be solved is currently in O(n*v) in the best case (only one ivar per node). I think this could be achieved in O(v) if the nodes where stored in a map in addition to the ordered list. You'll find in attachment a suggestion of patch for that. What do you think? Thanks, Bernard -------------- next part -------------- A non-text attachment was scrubbed... Name: InferenceGraph.patch Type: text/x-patch Size: 4994 bytes Desc: not available URL: From maurizio.cimadamore at oracle.com Tue Oct 3 23:03:19 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 4 Oct 2017 00:03:19 +0100 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: Message-ID: Quick question on (3) - who is using that new 'map' ? Is the plan to replace the findNode linear scan with a map lookup? I believe that method is not even used inside javac (leftover from previous code which should be removed). In any case, if the goal is to replace the findNode routine, I guess I'm a bit surprise that the data structure is a Map> rather than a Map - surely we cannot have the same inference variable belonging to more than one graph node? In other words, I'd expect the elements of conSubGraphHead.data to be disjoint. On (1) and (2), I'll have to check more closely, but as an high-level design, this BestLeafSolver is only called when there's a generic method call with one or more functional expressions and one of them is 'stuck' - so that some eager inference resolution has to happens, in which case the compiler needs to find a way to do 'as less damage as possible'. I'd expect this routine to be called rather infrequently, and not to be (too) performance sensitive; I don't think it ever appeared in any of the profiling runs we took in the past when troubleshooting inference performances. Maurizio On 03/10/17 22:05, B. Blaser wrote: > Hi, > > While exploring the implementation of the inference graph along with > the solving system, I noticed that the complexity of the heuristic > used to choose the best leaf to be solved could probably be reduced in > three ways: > > 1) When an optimal leaf is found with only one ivar to be solved, > there's no need to evaluate other subtrees. > > 2) When computing a subtree heuristic, if the path being evaluated > appears to be worth than the best subtree so far, it isn't necessary > to keep on evaluating this possibility. > > 3) Let 'n' be the number of inference graph nodes and 'v' be the > number of variables to be solved (for example when inferring the types > of lambda parameters). > > Retrieving all the nodes of a graph corresponding to a list of > inference variables to be solved is currently in O(n*v) in the best > case (only one ivar per node). I think this could be achieved in O(v) > if the nodes where stored in a map in addition to the ordered list. > > You'll find in attachment a suggestion of patch for that. > > What do you think? > > Thanks, > Bernard From vicente.romero at oracle.com Tue Oct 3 23:40:00 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Tue, 3 Oct 2017 19:40:00 -0400 Subject: Most specific method in diagnostic generation for overload resolution In-Reply-To: References: Message-ID: <77debdca-87d5-56fa-4b2e-ba4e250b9ac6@oracle.com> Hi Bernard, [1] is a link to the fix for the bug you reported. I used your email to mark it as contributed by you. Finally we made some minor adjustments to the code in order to avoid cloning the key set. Thanks! Vicente [1] http://hg.openjdk.java.net/jdk10/master/rev/2e947e1bd907 On 09/20/2017 10:56 AM, B. Blaser wrote: > Hi, > > Related to [1], I wrote a specialized map to store only the most > specific candidates during the diagnostic generation for overload > resolution, here under. > > It's then used in "Resolve.InapplicableSymbolsError.mapCandidates()" > when non-applicable methods are collected to generate the diagnostic. > > What do you think? > Bernard > > [1] http://mail.openjdk.java.net/pipermail/compiler-dev/2017-September/011062.html > > 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 > @@ -59,6 +59,7 @@ > import java.util.HashSet; > import java.util.Iterator; > import java.util.LinkedHashMap; > +import java.util.LinkedList; > import java.util.Map; > import java.util.Set; > import java.util.function.BiFunction; > @@ -3995,14 +3996,29 @@ > } > //where > private Map mapCandidates() { > - Map candidates = new LinkedHashMap<>(); > + MostSpecificMap candidates = new MostSpecificMap(); > for (Candidate c : resolveContext.candidates) { > if (c.isApplicable()) continue; > - candidates.put(c.sym, c.details); > + candidates.put(c); > } > return candidates; > } > > + @SuppressWarnings("serial") > + private class MostSpecificMap extends > LinkedHashMap { > + private void put(Candidate c) { > + new LinkedList<>(keySet()).stream() > + .filter( s -> !s.equals(c.sym) ) > + .filter( s -> c.sym.overrides(s, > (TypeSymbol)s.owner, types, false) ) > + .forEach( s -> remove(s) ); > + > + if (!keySet().stream() > + .filter( s -> !s.equals(c.sym) ) > + .anyMatch( s -> s.overrides(c.sym, > (TypeSymbol)c.sym.owner, types, false) )) > + put(c.sym, c.details); > + } > + } > + > Map filterCandidates(Map JCDiagnostic> candidatesMap) { > Map candidates = new LinkedHashMap<>(); > for (Map.Entry _entry : > candidatesMap.entrySet()) { From bsrbnd at gmail.com Wed Oct 4 10:08:07 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Wed, 4 Oct 2017 12:08:07 +0200 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: Message-ID: On 4 October 2017 at 01:03, Maurizio Cimadamore wrote: > Quick question on (3) - who is using that new 'map' ? Is the plan to replace > the findNode linear scan with a map lookup? I believe that method is not > even used inside javac (leftover from previous code which should be > removed). The loop in O(n*v) that I'm trying to improve is [loop], see the replacement in the patch. Note that I removed "findNode()" since it isn't used and which is replaced by the map if necessary. > In any case, if the goal is to replace the findNode routine, I guess I'm a > bit surprise that the data structure is a Map> rather > than a Map - surely we cannot have the same inference variable > belonging to more than one graph node? In other words, I'd expect the > elements of conSubGraphHead.data to be disjoint. That's what I thought, too. But with a "Map", I was surprised by a small set of failing tests because of more than one node per variable. Is there any problem elsewhere? > On (1) and (2), I'll have to check more closely, but as an high-level > design, this BestLeafSolver is only called when there's a generic method > call with one or more functional expressions and one of them is 'stuck' - so > that some eager inference resolution has to happens, in which case the > compiler needs to find a way to do 'as less damage as possible'. I'd expect > this routine to be called rather infrequently, and not to be (too) > performance sensitive; I don't think it ever appeared in any of the > profiling runs we took in the past when troubleshooting inference > performances. I think some quite simple and frequent cases could be improved by (1), something like: public class E { interface F { void f(X x, Y y, Z z); } T m(T t) { return null; } void n(F f, A a, B b, C c, D d) {} void o() { n( (x, y, z) -> {}, m(""), m(""), m(""), m("")); } } Here, when inferring the type of the lambda parameter 'x', we find immediately an optimal leaf 'X', there's no need neither to loop through all the other lambda ivars nor through the rest of the graph nodes, see [loop]. For (2), it's a bit more complex as it would involve an f-bounded type for 'X' bound to another ivar like 'A' which also depends on 'T' from argument 'a' (something like "X extends R", I think...), but the optimization is costless and could be useful in some cases. What do you think? Bernard [loop] http://hg.openjdk.java.net/jdk10/master/file/66774e1fc3a7/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java#l1409 > Maurizio > > > > > On 03/10/17 22:05, B. Blaser wrote: >> >> Hi, >> >> While exploring the implementation of the inference graph along with >> the solving system, I noticed that the complexity of the heuristic >> used to choose the best leaf to be solved could probably be reduced in >> three ways: >> >> 1) When an optimal leaf is found with only one ivar to be solved, >> there's no need to evaluate other subtrees. >> >> 2) When computing a subtree heuristic, if the path being evaluated >> appears to be worth than the best subtree so far, it isn't necessary >> to keep on evaluating this possibility. >> >> 3) Let 'n' be the number of inference graph nodes and 'v' be the >> number of variables to be solved (for example when inferring the types >> of lambda parameters). >> >> Retrieving all the nodes of a graph corresponding to a list of >> inference variables to be solved is currently in O(n*v) in the best >> case (only one ivar per node). I think this could be achieved in O(v) >> if the nodes where stored in a map in addition to the ordered list. >> >> You'll find in attachment a suggestion of patch for that. >> >> What do you think? >> >> Thanks, >> Bernard > > From bsrbnd at gmail.com Wed Oct 4 10:12:56 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Wed, 4 Oct 2017 12:12:56 +0200 Subject: Most specific method in diagnostic generation for overload resolution In-Reply-To: <77debdca-87d5-56fa-4b2e-ba4e250b9ac6@oracle.com> References: <77debdca-87d5-56fa-4b2e-ba4e250b9ac6@oracle.com> Message-ID: On 4 October 2017 at 01:40, Vicente Romero wrote: > Hi Bernard, > > [1] is a link to the fix for the bug you reported. I used your email to mark > it as contributed by you. Finally we made some minor adjustments to the code > in order to avoid cloning the key set. Perfect, thanks! Bernard > Thanks! > Vicente > > [1] http://hg.openjdk.java.net/jdk10/master/rev/2e947e1bd907 > > On 09/20/2017 10:56 AM, B. Blaser wrote: >> >> Hi, >> >> Related to [1], I wrote a specialized map to store only the most >> specific candidates during the diagnostic generation for overload >> resolution, here under. >> >> It's then used in "Resolve.InapplicableSymbolsError.mapCandidates()" >> when non-applicable methods are collected to generate the diagnostic. >> >> What do you think? >> Bernard >> >> [1] >> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-September/011062.html >> >> 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 >> @@ -59,6 +59,7 @@ >> import java.util.HashSet; >> import java.util.Iterator; >> import java.util.LinkedHashMap; >> +import java.util.LinkedList; >> import java.util.Map; >> import java.util.Set; >> import java.util.function.BiFunction; >> @@ -3995,14 +3996,29 @@ >> } >> //where >> private Map mapCandidates() { >> - Map candidates = new >> LinkedHashMap<>(); >> + MostSpecificMap candidates = new MostSpecificMap(); >> for (Candidate c : resolveContext.candidates) { >> if (c.isApplicable()) continue; >> - candidates.put(c.sym, c.details); >> + candidates.put(c); >> } >> return candidates; >> } >> >> + @SuppressWarnings("serial") >> + private class MostSpecificMap extends >> LinkedHashMap { >> + private void put(Candidate c) { >> + new LinkedList<>(keySet()).stream() >> + .filter( s -> !s.equals(c.sym) ) >> + .filter( s -> c.sym.overrides(s, >> (TypeSymbol)s.owner, types, false) ) >> + .forEach( s -> remove(s) ); >> + >> + if (!keySet().stream() >> + .filter( s -> !s.equals(c.sym) ) >> + .anyMatch( s -> s.overrides(c.sym, >> (TypeSymbol)c.sym.owner, types, false) )) >> + put(c.sym, c.details); >> + } >> + } >> + >> Map filterCandidates(Map> JCDiagnostic> candidatesMap) { >> Map candidates = new >> LinkedHashMap<>(); >> for (Map.Entry _entry : >> candidatesMap.entrySet()) { > > From maurizio.cimadamore at oracle.com Wed Oct 4 11:55:01 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 4 Oct 2017 12:55:01 +0100 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: Message-ID: On 04/10/17 11:08, B. Blaser wrote: > That's what I thought, too. But with a "Map", I was > surprised by a small set of failing tests because of more than one > node per variable. Is there any problem elsewhere? I think we need to look at those tests - do you have a pointer to what they were? Thanks Maurizio From bsrbnd at gmail.com Wed Oct 4 15:03:26 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Wed, 4 Oct 2017 17:03:26 +0200 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: Message-ID: On 4 October 2017 at 13:55, Maurizio Cimadamore wrote: > > > On 04/10/17 11:08, B. Blaser wrote: >> >> That's what I thought, too. But with a "Map", I was >> surprised by a small set of failing tests because of more than one >> node per variable. Is there any problem elsewhere? > > I think we need to look at those tests - do you have a pointer to what they > were? I don't remember exactly, but probably in "test/tools/javac/lambda". My first idea was to replace the node list with a "LinkedHashMap" to have both benefits of an ordered list and a map. So, simply replacing the list by the map and re-running the tests should reveal the problem (I put an "Assert.check(map.remove(t) != null)" when removing a node which made some tests fail). Bernard > Thanks > Maurizio From maurizio.cimadamore at oracle.com Wed Oct 4 16:04:54 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 4 Oct 2017 17:04:54 +0100 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: Message-ID: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> Ok, I'll add some extra assertions to the code and then check it more closely. There are situations in which type variables are cloned - and sometimes you can have different clones of the same var in the same inference context - e.g. in situation like these g(m(), m()) That said, two type var clone should not be .equals, nor ==, so that would not explain as to why multiple nodes containing the 'same' inference vars were found in an inference graph. Maurizio On 04/10/17 16:03, B. Blaser wrote: > On 4 October 2017 at 13:55, Maurizio Cimadamore > wrote: >> >> On 04/10/17 11:08, B. Blaser wrote: >>> That's what I thought, too. But with a "Map", I was >>> surprised by a small set of failing tests because of more than one >>> node per variable. Is there any problem elsewhere? >> I think we need to look at those tests - do you have a pointer to what they >> were? > I don't remember exactly, but probably in "test/tools/javac/lambda". > My first idea was to replace the node list with a "LinkedHashMap Node>" to have both benefits of an ordered list and a map. So, simply > replacing the list by the map and re-running the tests should reveal > the problem (I put an "Assert.check(map.remove(t) != null)" when > removing a node which made some tests fail). > > Bernard > > >> Thanks >> Maurizio From bsrbnd at gmail.com Wed Oct 4 17:29:44 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Wed, 4 Oct 2017 19:29:44 +0200 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> Message-ID: I think one of the failing tests was "tools/javac/lambda/8016177/T8016177f.java". But I tried to re-do the initial fix for point (3) using a "LinkedHashMap" instead of an "ArrayList", as attached, and all "tools/javac/lambda/" are passing successfully! Now, it should be possible to re-incorporate points (1) and (2) with the new version of (3). Cheers, Bernard On 4 October 2017 at 18:04, Maurizio Cimadamore wrote: > Ok, I'll add some extra assertions to the code and then check it more > closely. > > There are situations in which type variables are cloned - and sometimes you > can have different clones of the same var in the same inference context - > e.g. in situation like these > > g(m(), m()) > > That said, two type var clone should not be .equals, nor ==, so that would > not explain as to why multiple nodes containing the 'same' inference vars > were found in an inference graph. > > Maurizio > > > > On 04/10/17 16:03, B. Blaser wrote: >> >> On 4 October 2017 at 13:55, Maurizio Cimadamore >> wrote: >>> >>> >>> On 04/10/17 11:08, B. Blaser wrote: >>>> >>>> That's what I thought, too. But with a "Map", I was >>>> surprised by a small set of failing tests because of more than one >>>> node per variable. Is there any problem elsewhere? >>> >>> I think we need to look at those tests - do you have a pointer to what >>> they >>> were? >> >> I don't remember exactly, but probably in "test/tools/javac/lambda". >> My first idea was to replace the node list with a "LinkedHashMap> Node>" to have both benefits of an ordered list and a map. So, simply >> replacing the list by the map and re-running the tests should reveal >> the problem (I put an "Assert.check(map.remove(t) != null)" when >> removing a node which made some tests fail). >> >> Bernard >> >> >>> Thanks >>> Maurizio > > -------------- next part -------------- A non-text attachment was scrubbed... Name: InferenceGraph_pt3.patch Type: text/x-patch Size: 5531 bytes Desc: not available URL: From bsrbnd at gmail.com Thu Oct 5 07:56:17 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Thu, 5 Oct 2017 09:56:17 +0200 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> Message-ID: On 4 October 2017 at 19:29, B. Blaser wrote: > I think one of the failing tests was > "tools/javac/lambda/8016177/T8016177f.java". > > But I tried to re-do the initial fix for point (3) using a > "LinkedHashMap" instead of an "ArrayList", as > attached, and all "tools/javac/lambda/" are passing successfully! > > Now, it should be possible to re-incorporate points (1) and (2) with > the new version of (3). Notice also that deleting a node from the graph (which is done at every solving step [1]) is improved, too. The list removal being in O(n) vs O(1) for the map as used in the last patch for point (3). What do you think? Bernard [1] http://hg.openjdk.java.net/jdk10/master/file/d4f959806fe9/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java#l1687 > Cheers, > Bernard > > > On 4 October 2017 at 18:04, Maurizio Cimadamore > wrote: >> Ok, I'll add some extra assertions to the code and then check it more >> closely. >> >> There are situations in which type variables are cloned - and sometimes you >> can have different clones of the same var in the same inference context - >> e.g. in situation like these >> >> g(m(), m()) >> >> That said, two type var clone should not be .equals, nor ==, so that would >> not explain as to why multiple nodes containing the 'same' inference vars >> were found in an inference graph. >> >> Maurizio >> >> >> >> On 04/10/17 16:03, B. Blaser wrote: >>> >>> On 4 October 2017 at 13:55, Maurizio Cimadamore >>> wrote: >>>> >>>> >>>> On 04/10/17 11:08, B. Blaser wrote: >>>>> >>>>> That's what I thought, too. But with a "Map", I was >>>>> surprised by a small set of failing tests because of more than one >>>>> node per variable. Is there any problem elsewhere? >>>> >>>> I think we need to look at those tests - do you have a pointer to what >>>> they >>>> were? >>> >>> I don't remember exactly, but probably in "test/tools/javac/lambda". >>> My first idea was to replace the node list with a "LinkedHashMap>> Node>" to have both benefits of an ordered list and a map. So, simply >>> replacing the list by the map and re-running the tests should reveal >>> the problem (I put an "Assert.check(map.remove(t) != null)" when >>> removing a node which made some tests fail). >>> >>> Bernard >>> >>> >>>> Thanks >>>> Maurizio >> >> From jan.lahoda at oracle.com Thu Oct 5 08:12:11 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Thu, 5 Oct 2017 10:12:11 +0200 Subject: RFR 8063054: Incorrect raw type warning for method reference In-Reply-To: References: <0da5979f-2c3c-c3d2-f7f5-230bf139ac08@oracle.com> Message-ID: <59D5E95B.6060608@oracle.com> Looks good to me too. Jan On 2.10.2017 20:40, B. Blaser wrote: > Looks good! > > Cheers, > Bernard > > > On 2 October 2017 at 20:06, Maurizio Cimadamore > wrote: >> Hi, >> here's a patch for a problem with spurious raw type warnings generated when >> checking unbound method references: >> >> http://cr.openjdk.java.net/~mcimadamore/8063054/ >> >> This has actually been discussed few months ago, so I don't expect many >> surprises :-) >> >> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-February/010815.html >> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-March/010888.html >> >> Sorry for the delay. >> >> Cheers >> Maurizio >> >> From jan.lahoda at oracle.com Thu Oct 5 08:15:37 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Thu, 5 Oct 2017 10:15:37 +0200 Subject: RFR JDK-8188225: AST could be improved in presence of var types. In-Reply-To: References: <59D25CC5.5080809@oracle.com> <5ffd68fa-6455-b412-351f-54778be3cf4a@oracle.com> <59D3CEAA.5010302@oracle.com> Message-ID: <59D5EA29.4090305@oracle.com> Hi, An updated patch that has a method to generate the synthetic type trees is here: http://cr.openjdk.java.net/~jlahoda/8188225/webrev.01/ Thanks for any feedback, Jan On 3.10.2017 19:58, Maurizio Cimadamore wrote: > > > On 03/10/17 18:53, Jan Lahoda wrote: >> Hi Maurizio, >> >> Thanks for the comments - some responses inline. >> >> On 3.10.2017 17:59, Maurizio Cimadamore wrote: >>> Thanks for taking care of this, I have a couple of suggestion: >>> >>> * the routine for generating synthetic type tree should be shared. E.g. >>> you need a method that takes a type and generates something that is >>> suitable for a local variable or a lambda parameter - e.g. >>> >>> toSyntheticTypeTree(Type t) { >>> if (t.isErroneous()) { >>> return make.at(Position.NOPOS).Erroneous(); >>> } else { >>> return make.at(Position.NOPOS).Type(t); >>> } >>> } >> >> Sure, will do. >> >>> >>> * secondly, while adding the startpos tree is fine - here it seems like >>> we morally would like to override the getStartPosition for the synthetic >>> type trees created above, so that the former position is returned (e.g. >>> that of 'var'). So, I wonder if something like this could work: >>> >>> toSyntheticTypeTree(Type t, int preferredPos) { >>> if (t.isErroneous()) { >>> return make.at(preferredPos).Erroneous(); >>> } else { >>> return make.at(preferredPos).Type(t); >>> } >>> } >>> >>> Then, assuming the parser creates the local variable node with the >>> correct pos (which it doesn't now), I think everything should work even >> >> Hm, you mean put the starting position to the JCVariableDecl.pos? If >> that would be the value, we could surely avoid the field, but AFAIK >> the JCVariableDecl.pos usually points to the name of the variable, and >> I didn't want to add an inconsistency, or change that (as the position >> is useful for error reporting), >> >> Alternatives I was thinking of included playing tricks with modifiers >> (setting the position to modifiers (if there are no/empty modifiers) >> and filtering it in getStartPos), with nameexpr or having a subclass >> of JCVariableDecl for vars which would include the extra field. > I see good points. I also thought about using a tree copier, but that > also goes through TreeMaker, which makes it hard to e.g. create anon > tree instances which override getStartPosition. > > No bother - your original solution is good enough, at least for now. I > appreciate that the new pos field is just for var AST nodes. > > Maurizio >> >> (I was also trying to have -1 as the position of the synthetic type to >> aid its detection, but it could still be detected by looking at the >> end position, so this is not that big deal.) >> >> Thanks, >> Jan >> >>> w/o a dedicated field? >>> >>> Maurizio >>> >>> >>> >>> >>> On 02/10/17 16:35, Jan Lahoda wrote: >>>> Hello, >>>> >>>> JShell produces not ideal errors related to local variable type >>>> inference in some cases: >>>> --- >>>> jshell> var i = () -> {}; >>>> | Error: >>>> | incompatible types: java.lang.Object is not a functional interface >>>> | var i = () -> {}; >>>> | ^------^ >>>> --- >>>> >>>> Better would be: >>>> --- >>>> jshell> var i = () -> {}; >>>> | Error: >>>> | cannot infer type for local variable i >>>> | (lambda expression needs an explicit target-type) >>>> | var i = () -> {}; >>>> | ^---------------^ >>>> --- >>>> >>>> (which is the error produced by javac) >>>> >>>> The AST model could also be improved for local variables whose type >>>> have been inferred (which also improves the jshell errors in some >>>> cases): >>>> - for "var i = 0;", the VariableTree.getType() will be null even after >>>> attribution, but for: "for (var i : Arrays.asList(0, 1)) {}", the >>>> VariableTree.getType() will be filled in by Attr. (The inferred type >>>> is also filled in for lambda parameters.) This is not only >>>> inconsistent, but also Attr.PostAttrAnalyzer.visitVarDef may fill in >>>> the type with an ErroneousTree (with a wrong position). The proposal >>>> here is to always fill in the type for consistency, and to >>>> consistently use NOPOS for the synthetic type position >>>> >>>> -for "var i = 0;" SourcePositions.getStartPosition does not return a >>>> proper starting position (the position of "var"), but rather the >>>> position of the synthetic type, if any (which can also be >>>> ErroneousTree) or the position of the variable name. The proposal here >>>> is to remember the real start of the variable and return it. >>>> >>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8188225 >>>> Webrev: >>>> http://cr.openjdk.java.net/~jlahoda/8188225/webrev.00/index.html >>>> >>>> What do you think? >>>> >>>> Thanks, >>>> Jan >>> > From maurizio.cimadamore at oracle.com Thu Oct 5 08:32:16 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 5 Oct 2017 09:32:16 +0100 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> Message-ID: <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> Please, send me a patch with all your fixed, including the new version of (3) and I'll take a look/run some tests. Cheers Maurizio On 05/10/17 08:56, B. Blaser wrote: > On 4 October 2017 at 19:29, B. Blaser wrote: >> I think one of the failing tests was >> "tools/javac/lambda/8016177/T8016177f.java". >> >> But I tried to re-do the initial fix for point (3) using a >> "LinkedHashMap" instead of an "ArrayList", as >> attached, and all "tools/javac/lambda/" are passing successfully! >> >> Now, it should be possible to re-incorporate points (1) and (2) with >> the new version of (3). > Notice also that deleting a node from the graph (which is done at > every solving step [1]) is improved, too. > The list removal being in O(n) vs O(1) for the map as used in the last > patch for point (3). > > What do you think? > > Bernard > > > [1] http://hg.openjdk.java.net/jdk10/master/file/d4f959806fe9/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java#l1687 > >> Cheers, >> Bernard >> >> >> On 4 October 2017 at 18:04, Maurizio Cimadamore >> wrote: >>> Ok, I'll add some extra assertions to the code and then check it more >>> closely. >>> >>> There are situations in which type variables are cloned - and sometimes you >>> can have different clones of the same var in the same inference context - >>> e.g. in situation like these >>> >>> g(m(), m()) >>> >>> That said, two type var clone should not be .equals, nor ==, so that would >>> not explain as to why multiple nodes containing the 'same' inference vars >>> were found in an inference graph. >>> >>> Maurizio >>> >>> >>> >>> On 04/10/17 16:03, B. Blaser wrote: >>>> On 4 October 2017 at 13:55, Maurizio Cimadamore >>>> wrote: >>>>> >>>>> On 04/10/17 11:08, B. Blaser wrote: >>>>>> That's what I thought, too. But with a "Map", I was >>>>>> surprised by a small set of failing tests because of more than one >>>>>> node per variable. Is there any problem elsewhere? >>>>> I think we need to look at those tests - do you have a pointer to what >>>>> they >>>>> were? >>>> I don't remember exactly, but probably in "test/tools/javac/lambda". >>>> My first idea was to replace the node list with a "LinkedHashMap>>> Node>" to have both benefits of an ordered list and a map. So, simply >>>> replacing the list by the map and re-running the tests should reveal >>>> the problem (I put an "Assert.check(map.remove(t) != null)" when >>>> removing a node which made some tests fail). >>>> >>>> Bernard >>>> >>>> >>>>> Thanks >>>>> Maurizio >>> From maurizio.cimadamore at oracle.com Thu Oct 5 13:29:55 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 5 Oct 2017 14:29:55 +0100 Subject: RFR 8172443: Change use of tree.pos to line:col in rawDiagnostics Message-ID: <43e73ff3-b10d-8f8e-69d1-f15e77d8626b@oracle.com> Hi, this is a fix to our raw diagnostic machinery that will allow for more robust compiler negative tests. Currently, when a functional expression is found in a diagnostic, it can sometimes be represented using the absoluted cursor position of the expression in the source file. This makes the golden files for such tests extremely unreliable, as simply adding/removing chars from lines before the functional expression would result in golden file mismatches. This is extremely annoying when e.g. the jtreg header of a test must be change for some reason (e.g. to add an extra bug id). The solution is to use a more robust encoding with line:col - so that there's less dependencies on what happens on previous lines. http://cr.openjdk.java.net/~mcimadamore/8172443/ Cheers Maurizio From vicente.romero at oracle.com Thu Oct 5 13:49:20 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 5 Oct 2017 09:49:20 -0400 Subject: RFR 8172443: Change use of tree.pos to line:col in rawDiagnostics In-Reply-To: <43e73ff3-b10d-8f8e-69d1-f15e77d8626b@oracle.com> References: <43e73ff3-b10d-8f8e-69d1-f15e77d8626b@oracle.com> Message-ID: <4d520b3a-e764-83aa-87ea-c87c1d804022@oracle.com> Hi, +100 to this effort, that will save us a lot of time. Regarding the patch, sometimes new lines need to be added to a test, sometimes in the jtreg header, sometimes somewhere else. How bad would be to use the column number only instead of line:col? Thanks, Vicente On 10/05/2017 09:29 AM, Maurizio Cimadamore wrote: > Hi, > this is a fix to our raw diagnostic machinery that will allow for more > robust compiler negative tests. Currently, when a functional > expression is found in a diagnostic, it can sometimes be represented > using the absoluted cursor position of the expression in the source > file. This makes the golden files for such tests extremely unreliable, > as simply adding/removing chars from lines before the functional > expression would result in golden file mismatches. This is extremely > annoying when e.g. the jtreg header of a test must be change for some > reason (e.g. to add an extra bug id). > > The solution is to use a more robust encoding with line:col - so that > there's less dependencies on what happens on previous lines. > > http://cr.openjdk.java.net/~mcimadamore/8172443/ > > Cheers > Maurizio > From maurizio.cimadamore at oracle.com Thu Oct 5 13:51:56 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 5 Oct 2017 14:51:56 +0100 Subject: RFR 8172443: Change use of tree.pos to line:col in rawDiagnostics In-Reply-To: <4d520b3a-e764-83aa-87ea-c87c1d804022@oracle.com> References: <43e73ff3-b10d-8f8e-69d1-f15e77d8626b@oracle.com> <4d520b3a-e764-83aa-87ea-c87c1d804022@oracle.com> Message-ID: <9c9b29e3-238c-5fc6-bb28-beb167c7eff8@oracle.com> On 05/10/17 14:49, Vicente Romero wrote: > Hi, > > +100 to this effort, that will save us a lot of time. Regarding the > patch, sometimes new lines need to be added to a test, sometimes in > the jtreg header, sometimes somewhere else. How bad would be to use > the column number only instead of line:col? I understand the concern. I think the goal of this patch is to fix the #1 offender. As you say there could be other offenders. But getting rid of them all is hard - if you just use 'col' you basically lose uniqueness, which makes looking at the golden file more obscure, I think. Maurizio > > Thanks, > Vicente > > On 10/05/2017 09:29 AM, Maurizio Cimadamore wrote: >> Hi, >> this is a fix to our raw diagnostic machinery that will allow for >> more robust compiler negative tests. Currently, when a functional >> expression is found in a diagnostic, it can sometimes be represented >> using the absoluted cursor position of the expression in the source >> file. This makes the golden files for such tests extremely >> unreliable, as simply adding/removing chars from lines before the >> functional expression would result in golden file mismatches. This is >> extremely annoying when e.g. the jtreg header of a test must be >> change for some reason (e.g. to add an extra bug id). >> >> The solution is to use a more robust encoding with line:col - so that >> there's less dependencies on what happens on previous lines. >> >> http://cr.openjdk.java.net/~mcimadamore/8172443/ >> >> Cheers >> Maurizio >> > From vicente.romero at oracle.com Thu Oct 5 14:05:08 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 5 Oct 2017 10:05:08 -0400 Subject: RFR 8172443: Change use of tree.pos to line:col in rawDiagnostics In-Reply-To: <9c9b29e3-238c-5fc6-bb28-beb167c7eff8@oracle.com> References: <43e73ff3-b10d-8f8e-69d1-f15e77d8626b@oracle.com> <4d520b3a-e764-83aa-87ea-c87c1d804022@oracle.com> <9c9b29e3-238c-5fc6-bb28-beb167c7eff8@oracle.com> Message-ID: On 10/05/2017 09:51 AM, Maurizio Cimadamore wrote: > > > On 05/10/17 14:49, Vicente Romero wrote: >> Hi, >> >> +100 to this effort, that will save us a lot of time. Regarding the >> patch, sometimes new lines need to be added to a test, sometimes in >> the jtreg header, sometimes somewhere else. How bad would be to use >> the column number only instead of line:col? > I understand the concern. I think the goal of this patch is to fix the > #1 offender. As you say there could be other offenders. But getting > rid of them all is hard - if you just use 'col' you basically lose > uniqueness, which makes looking at the golden file more obscure, I think. well it's true that uniqueness could be a problem for errors reported at statements that spans more than one line, but I'm not sure if it is worthy to still keep a source of brittleness because of that. I mean what could be the probability of introducing a change that will swap two identical column positions in the diagnostics and still produce the same diagnostics such that we won't detect it. In the worst case we can add the line if we see that the particular statement we are generating the diagnostics for spans more than one line and use only the column for all other cases Vicente > > Maurizio >> >> Thanks, >> Vicente >> >> On 10/05/2017 09:29 AM, Maurizio Cimadamore wrote: >>> Hi, >>> this is a fix to our raw diagnostic machinery that will allow for >>> more robust compiler negative tests. Currently, when a functional >>> expression is found in a diagnostic, it can sometimes be represented >>> using the absoluted cursor position of the expression in the source >>> file. This makes the golden files for such tests extremely >>> unreliable, as simply adding/removing chars from lines before the >>> functional expression would result in golden file mismatches. This >>> is extremely annoying when e.g. the jtreg header of a test must be >>> change for some reason (e.g. to add an extra bug id). >>> >>> The solution is to use a more robust encoding with line:col - so >>> that there's less dependencies on what happens on previous lines. >>> >>> http://cr.openjdk.java.net/~mcimadamore/8172443/ >>> >>> Cheers >>> Maurizio >>> >> > From maurizio.cimadamore at oracle.com Thu Oct 5 14:12:18 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 5 Oct 2017 15:12:18 +0100 Subject: RFR 8172443: Change use of tree.pos to line:col in rawDiagnostics In-Reply-To: References: <43e73ff3-b10d-8f8e-69d1-f15e77d8626b@oracle.com> <4d520b3a-e764-83aa-87ea-c87c1d804022@oracle.com> <9c9b29e3-238c-5fc6-bb28-beb167c7eff8@oracle.com> Message-ID: On 05/10/17 15:05, Vicente Romero wrote: > > > On 10/05/2017 09:51 AM, Maurizio Cimadamore wrote: >> >> >> On 05/10/17 14:49, Vicente Romero wrote: >>> Hi, >>> >>> +100 to this effort, that will save us a lot of time. Regarding the >>> patch, sometimes new lines need to be added to a test, sometimes in >>> the jtreg header, sometimes somewhere else. How bad would be to use >>> the column number only instead of line:col? >> I understand the concern. I think the goal of this patch is to fix >> the #1 offender. As you say there could be other offenders. But >> getting rid of them all is hard - if you just use 'col' you basically >> lose uniqueness, which makes looking at the golden file more obscure, >> I think. > > well it's true that uniqueness could be a problem for errors reported > at statements that spans more than one line, but I'm not sure if it is > worthy to still keep a source of brittleness because of that. I mean > what could be the probability of introducing a change that will swap > two identical column positions in the diagnostics and still produce > the same diagnostics such that we won't detect it. In the worst case > we can add the line if we see that the particular statement we are > generating the diagnostics for spans more than one line and use only > the column for all other cases I suggest with stick with the proposed approach and then see how bad it is in the real world? Maurizio > > Vicente > >> >> Maurizio >>> >>> Thanks, >>> Vicente >>> >>> On 10/05/2017 09:29 AM, Maurizio Cimadamore wrote: >>>> Hi, >>>> this is a fix to our raw diagnostic machinery that will allow for >>>> more robust compiler negative tests. Currently, when a functional >>>> expression is found in a diagnostic, it can sometimes be >>>> represented using the absoluted cursor position of the expression >>>> in the source file. This makes the golden files for such tests >>>> extremely unreliable, as simply adding/removing chars from lines >>>> before the functional expression would result in golden file >>>> mismatches. This is extremely annoying when e.g. the jtreg header >>>> of a test must be change for some reason (e.g. to add an extra bug >>>> id). >>>> >>>> The solution is to use a more robust encoding with line:col - so >>>> that there's less dependencies on what happens on previous lines. >>>> >>>> http://cr.openjdk.java.net/~mcimadamore/8172443/ >>>> >>>> Cheers >>>> Maurizio >>>> >>> >> > From vicente.romero at oracle.com Thu Oct 5 14:27:39 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 5 Oct 2017 10:27:39 -0400 Subject: RFR 8172443: Change use of tree.pos to line:col in rawDiagnostics In-Reply-To: References: <43e73ff3-b10d-8f8e-69d1-f15e77d8626b@oracle.com> <4d520b3a-e764-83aa-87ea-c87c1d804022@oracle.com> <9c9b29e3-238c-5fc6-bb28-beb167c7eff8@oracle.com> Message-ID: On 10/05/2017 10:12 AM, Maurizio Cimadamore wrote: > > > On 05/10/17 15:05, Vicente Romero wrote: >> >> >> On 10/05/2017 09:51 AM, Maurizio Cimadamore wrote: >>> >>> >>> On 05/10/17 14:49, Vicente Romero wrote: >>>> Hi, >>>> >>>> +100 to this effort, that will save us a lot of time. Regarding the >>>> patch, sometimes new lines need to be added to a test, sometimes in >>>> the jtreg header, sometimes somewhere else. How bad would be to use >>>> the column number only instead of line:col? >>> I understand the concern. I think the goal of this patch is to fix >>> the #1 offender. As you say there could be other offenders. But >>> getting rid of them all is hard - if you just use 'col' you >>> basically lose uniqueness, which makes looking at the golden file >>> more obscure, I think. >> >> well it's true that uniqueness could be a problem for errors reported >> at statements that spans more than one line, but I'm not sure if it >> is worthy to still keep a source of brittleness because of that. I >> mean what could be the probability of introducing a change that will >> swap two identical column positions in the diagnostics and still >> produce the same diagnostics such that we won't detect it. In the >> worst case we can add the line if we see that the particular >> statement we are generating the diagnostics for spans more than one >> line and use only the column for all other cases > I suggest with stick with the proposed approach and then see how bad > it is in the real world? I think that the proposed approach will be better than the current situation, that's for sure, but I think that this is the right moment to consider if the proposed approach can be still better. If you want to go for it with the current version, I'm OK with that but you know how long it takes for stuff like this to be revisited. > > Maurizio Vicente >> >> Vicente >> >>> >>> Maurizio >>>> >>>> Thanks, >>>> Vicente >>>> >>>> On 10/05/2017 09:29 AM, Maurizio Cimadamore wrote: >>>>> Hi, >>>>> this is a fix to our raw diagnostic machinery that will allow for >>>>> more robust compiler negative tests. Currently, when a functional >>>>> expression is found in a diagnostic, it can sometimes be >>>>> represented using the absoluted cursor position of the expression >>>>> in the source file. This makes the golden files for such tests >>>>> extremely unreliable, as simply adding/removing chars from lines >>>>> before the functional expression would result in golden file >>>>> mismatches. This is extremely annoying when e.g. the jtreg header >>>>> of a test must be change for some reason (e.g. to add an extra bug >>>>> id). >>>>> >>>>> The solution is to use a more robust encoding with line:col - so >>>>> that there's less dependencies on what happens on previous lines. >>>>> >>>>> http://cr.openjdk.java.net/~mcimadamore/8172443/ >>>>> >>>>> Cheers >>>>> Maurizio >>>>> >>>> >>> >> > From vicente.romero at oracle.com Thu Oct 5 14:28:34 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 5 Oct 2017 10:28:34 -0400 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> Message-ID: <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> On 10/05/2017 04:32 AM, Maurizio Cimadamore wrote: > Please, send me a patch with all your fixed, including the new version > of (3) and I'll take a look/run some tests. +1 yes please share the last full version > > Cheers > Maurizio Vicente > > > On 05/10/17 08:56, B. Blaser wrote: >> On 4 October 2017 at 19:29, B. Blaser wrote: >>> I think one of the failing tests was >>> "tools/javac/lambda/8016177/T8016177f.java". >>> >>> But I tried to re-do the initial fix for point (3) using a >>> "LinkedHashMap" instead of an "ArrayList", as >>> attached, and all "tools/javac/lambda/" are passing successfully! >>> >>> Now, it should be possible to re-incorporate points (1) and (2) with >>> the new version of (3). >> Notice also that deleting a node from the graph (which is done at >> every solving step [1]) is improved, too. >> The list removal being in O(n) vs O(1) for the map as used in the last >> patch for point (3). >> >> What do you think? >> >> Bernard >> >> >> [1] >> http://hg.openjdk.java.net/jdk10/master/file/d4f959806fe9/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java#l1687 >> >>> Cheers, >>> Bernard >>> >>> >>> On 4 October 2017 at 18:04, Maurizio Cimadamore >>> wrote: >>>> Ok, I'll add some extra assertions to the code and then check it more >>>> closely. >>>> >>>> There are situations in which type variables are cloned - and >>>> sometimes you >>>> can have different clones of the same var in the same inference >>>> context - >>>> e.g. in situation like these >>>> >>>> g(m(), m()) >>>> >>>> That said, two type var clone should not be .equals, nor ==, so >>>> that would >>>> not explain as to why multiple nodes containing the 'same' >>>> inference vars >>>> were found in an inference graph. >>>> >>>> Maurizio >>>> >>>> >>>> >>>> On 04/10/17 16:03, B. Blaser wrote: >>>>> On 4 October 2017 at 13:55, Maurizio Cimadamore >>>>> wrote: >>>>>> >>>>>> On 04/10/17 11:08, B. Blaser wrote: >>>>>>> That's what I thought, too. But with a "Map", I was >>>>>>> surprised by a small set of failing tests because of more than one >>>>>>> node per variable. Is there any problem elsewhere? >>>>>> I think we need to look at those tests - do you have a pointer to >>>>>> what >>>>>> they >>>>>> were? >>>>> I don't remember exactly, but probably in "test/tools/javac/lambda". >>>>> My first idea was to replace the node list with a >>>>> "LinkedHashMap>>>> Node>" to have both benefits of an ordered list and a map. So, simply >>>>> replacing the list by the map and re-running the tests should reveal >>>>> the problem (I put an "Assert.check(map.remove(t) != null)" when >>>>> removing a node which made some tests fail). >>>>> >>>>> Bernard >>>>> >>>>> >>>>>> Thanks >>>>>> Maurizio >>>> > From maurizio.cimadamore at oracle.com Thu Oct 5 14:40:36 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 5 Oct 2017 15:40:36 +0100 Subject: RFR 8172443: Change use of tree.pos to line:col in rawDiagnostics In-Reply-To: References: <43e73ff3-b10d-8f8e-69d1-f15e77d8626b@oracle.com> <4d520b3a-e764-83aa-87ea-c87c1d804022@oracle.com> <9c9b29e3-238c-5fc6-bb28-beb167c7eff8@oracle.com> Message-ID: <64293708-fd6d-3290-6b2a-109769547297@oracle.com> On 05/10/17 15:27, Vicente Romero wrote: > > > On 10/05/2017 10:12 AM, Maurizio Cimadamore wrote: >> >> >> On 05/10/17 15:05, Vicente Romero wrote: >>> >>> >>> On 10/05/2017 09:51 AM, Maurizio Cimadamore wrote: >>>> >>>> >>>> On 05/10/17 14:49, Vicente Romero wrote: >>>>> Hi, >>>>> >>>>> +100 to this effort, that will save us a lot of time. Regarding >>>>> the patch, sometimes new lines need to be added to a test, >>>>> sometimes in the jtreg header, sometimes somewhere else. How bad >>>>> would be to use the column number only instead of line:col? >>>> I understand the concern. I think the goal of this patch is to fix >>>> the #1 offender. As you say there could be other offenders. But >>>> getting rid of them all is hard - if you just use 'col' you >>>> basically lose uniqueness, which makes looking at the golden file >>>> more obscure, I think. >>> >>> well it's true that uniqueness could be a problem for errors >>> reported at statements that spans more than one line, but I'm not >>> sure if it is worthy to still keep a source of brittleness because >>> of that. I mean what could be the probability of introducing a >>> change that will swap two identical column positions in the >>> diagnostics and still produce the same diagnostics such that we >>> won't detect it. In the worst case we can add the line if we see >>> that the particular statement we are generating the diagnostics for >>> spans more than one line and use only the column for all other cases >> I suggest with stick with the proposed approach and then see how bad >> it is in the real world? > > I think that the proposed approach will be better than the current > situation, that's for sure, but I think that this is the right moment > to consider if the proposed approach can be still better. If you want > to go for it with the current version, I'm OK with that but you know > how long it takes for stuff like this to be revisited. I believe the ultimate fix for these kind of issues would be to revisit the code so that instead of generating line or column info, we generate a position that is relative to the start of the enclosing statement. In a way this generalizes over the 'using only col' idea, and works even for functional expressions scattered across multiple lines (but part of the same statement). That said, doing that would not only require changes to the raw diagnostic backend (as done here), but would need deeper changes in how functional expression trees are communicated to the diagnostic backend. Right now we just pass trees as diagnostic arguments. Trees do not provide any contextual info (e.g. what is the parent of the tree?) - so to do this kind of treatment (and also the treatment you suggest where we only use column 'if needed') requires a contextual info that the current diag arguments do not have. While this is all solvable, as with all fixes/enhancements, it's about trying to achieve some kind of compromise between complexity and benefits. Having fixed many source pos related issues, I can say with confidence that this patch addresses almost all of them. When line number changes in a test file (e.g. because more stuff is added), your golden file will have to change anyway, as all the errors generated _after_ the insertion are going to have stale info in the golden file. That's why I did not prioritize the 'vertical' adjustments so much (as they are typically breaking anyway - modulo few lucky cases). Maurizio > >> >> Maurizio > > Vicente > >>> >>> Vicente >>> >>>> >>>> Maurizio >>>>> >>>>> Thanks, >>>>> Vicente >>>>> >>>>> On 10/05/2017 09:29 AM, Maurizio Cimadamore wrote: >>>>>> Hi, >>>>>> this is a fix to our raw diagnostic machinery that will allow for >>>>>> more robust compiler negative tests. Currently, when a functional >>>>>> expression is found in a diagnostic, it can sometimes be >>>>>> represented using the absoluted cursor position of the expression >>>>>> in the source file. This makes the golden files for such tests >>>>>> extremely unreliable, as simply adding/removing chars from lines >>>>>> before the functional expression would result in golden file >>>>>> mismatches. This is extremely annoying when e.g. the jtreg header >>>>>> of a test must be change for some reason (e.g. to add an extra >>>>>> bug id). >>>>>> >>>>>> The solution is to use a more robust encoding with line:col - so >>>>>> that there's less dependencies on what happens on previous lines. >>>>>> >>>>>> http://cr.openjdk.java.net/~mcimadamore/8172443/ >>>>>> >>>>>> Cheers >>>>>> Maurizio >>>>>> >>>>> >>>> >>> >> > From jonathan.gibbons at oracle.com Thu Oct 5 15:00:12 2017 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Thu, 5 Oct 2017 08:00:12 -0700 Subject: RFR 8172443: Change use of tree.pos to line:col in rawDiagnostics In-Reply-To: <64293708-fd6d-3290-6b2a-109769547297@oracle.com> References: <43e73ff3-b10d-8f8e-69d1-f15e77d8626b@oracle.com> <4d520b3a-e764-83aa-87ea-c87c1d804022@oracle.com> <9c9b29e3-238c-5fc6-bb28-beb167c7eff8@oracle.com> <64293708-fd6d-3290-6b2a-109769547297@oracle.com> Message-ID: <4fa72c5d-d046-4e31-b149-b0d846626463@oracle.com> On 10/5/17 7:40 AM, Maurizio Cimadamore wrote: > > > On 05/10/17 15:27, Vicente Romero wrote: >> >> >> On 10/05/2017 10:12 AM, Maurizio Cimadamore wrote: >>> >>> >>> On 05/10/17 15:05, Vicente Romero wrote: >>>> >>>> >>>> On 10/05/2017 09:51 AM, Maurizio Cimadamore wrote: >>>>> >>>>> >>>>> On 05/10/17 14:49, Vicente Romero wrote: >>>>>> Hi, >>>>>> >>>>>> +100 to this effort, that will save us a lot of time. Regarding >>>>>> the patch, sometimes new lines need to be added to a test, >>>>>> sometimes in the jtreg header, sometimes somewhere else. How bad >>>>>> would be to use the column number only instead of line:col? >>>>> I understand the concern. I think the goal of this patch is to fix >>>>> the #1 offender. As you say there could be other offenders. But >>>>> getting rid of them all is hard - if you just use 'col' you >>>>> basically lose uniqueness, which makes looking at the golden file >>>>> more obscure, I think. >>>> >>>> well it's true that uniqueness could be a problem for errors >>>> reported at statements that spans more than one line, but I'm not >>>> sure if it is worthy to still keep a source of brittleness because >>>> of that. I mean what could be the probability of introducing a >>>> change that will swap two identical column positions in the >>>> diagnostics and still produce the same diagnostics such that we >>>> won't detect it. In the worst case we can add the line if we see >>>> that the particular statement we are generating the diagnostics for >>>> spans more than one line and use only the column for all other cases >>> I suggest with stick with the proposed approach and then see how bad >>> it is in the real world? >> >> I think that the proposed approach will be better than the current >> situation, that's for sure, but I think that this is the right moment >> to consider if the proposed approach can be still better. If you want >> to go for it with the current version, I'm OK with that but you know >> how long it takes for stuff like this to be revisited. > I believe the ultimate fix for these kind of issues would be to > revisit the code so that instead of generating line or column info, we > generate a position that is relative to the start of the enclosing > statement. In a way this generalizes over the 'using only col' idea, > and works even for functional expressions scattered across multiple > lines (but part of the same statement). > > That said, doing that would not only require changes to the raw > diagnostic backend (as done here), but would need deeper changes in > how functional expression trees are communicated to the diagnostic > backend. Right now we just pass trees as diagnostic arguments. Trees > do not provide any contextual info (e.g. what is the parent of the > tree?) - so to do this kind of treatment (and also the treatment you > suggest where we only use column 'if needed') requires a contextual > info that the current diag arguments do not have. > > While this is all solvable, as with all fixes/enhancements, it's about > trying to achieve some kind of compromise between complexity and > benefits. Having fixed many source pos related issues, I can say with > confidence that this patch addresses almost all of them. > > When line number changes in a test file (e.g. because more stuff is > added), your golden file will have to change anyway, as all the errors > generated _after_ the insertion are going to have stale info in the > golden file. That's why I did not prioritize the 'vertical' > adjustments so much (as they are typically breaking anyway - modulo > few lucky cases). > > Maurizio I agree with Vicente's concern, but also agree with Maurizio's response. As to Vicente's comment "but you know how long it takes for stuff like this to be revisited", I'm sure it will be revisited if the pain is high enough, as demonstrated by this round of fixup. >> >>> >>> Maurizio >> >> Vicente >> >>>> >>>> Vicente >>>> >>>>> >>>>> Maurizio >>>>>> >>>>>> Thanks, >>>>>> Vicente >>>>>> >>>>>> On 10/05/2017 09:29 AM, Maurizio Cimadamore wrote: >>>>>>> Hi, >>>>>>> this is a fix to our raw diagnostic machinery that will allow >>>>>>> for more robust compiler negative tests. Currently, when a >>>>>>> functional expression is found in a diagnostic, it can sometimes >>>>>>> be represented using the absoluted cursor position of the >>>>>>> expression in the source file. This makes the golden files for >>>>>>> such tests extremely unreliable, as simply adding/removing chars >>>>>>> from lines before the functional expression would result in >>>>>>> golden file mismatches. This is extremely annoying when e.g. the >>>>>>> jtreg header of a test must be change for some reason (e.g. to >>>>>>> add an extra bug id). >>>>>>> >>>>>>> The solution is to use a more robust encoding with line:col - so >>>>>>> that there's less dependencies on what happens on previous lines. >>>>>>> >>>>>>> http://cr.openjdk.java.net/~mcimadamore/8172443/ >>>>>>> >>>>>>> Cheers >>>>>>> Maurizio >>>>>>> >>>>>> >>>>> >>>> >>> >> > From maurizio.cimadamore at oracle.com Thu Oct 5 15:33:34 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 5 Oct 2017 16:33:34 +0100 Subject: RFR 8172443: Change use of tree.pos to line:col in rawDiagnostics In-Reply-To: <43e73ff3-b10d-8f8e-69d1-f15e77d8626b@oracle.com> References: <43e73ff3-b10d-8f8e-69d1-f15e77d8626b@oracle.com> Message-ID: Hi, I managed to find a cheap way to address the concerns w/o altering how diagnostic arguments are communicated to the backend - revised webrev here: http://cr.openjdk.java.net/~mcimadamore/8172443_v2/ Basically we compare the expression line number with the root diagnostic line number, and if they are the same we omit that one. There's only one case where line number is needed: http://cr.openjdk.java.net/~mcimadamore/8172443_v2/test/langtools/tools/javac/T8024207/FlowCrashTest.out.udiff.html Cheers Maurizio On 05/10/17 14:29, Maurizio Cimadamore wrote: > Hi, > this is a fix to our raw diagnostic machinery that will allow for more > robust compiler negative tests. Currently, when a functional > expression is found in a diagnostic, it can sometimes be represented > using the absoluted cursor position of the expression in the source > file. This makes the golden files for such tests extremely unreliable, > as simply adding/removing chars from lines before the functional > expression would result in golden file mismatches. This is extremely > annoying when e.g. the jtreg header of a test must be change for some > reason (e.g. to add an extra bug id). > > The solution is to use a more robust encoding with line:col - so that > there's less dependencies on what happens on previous lines. > > http://cr.openjdk.java.net/~mcimadamore/8172443/ > > Cheers > Maurizio > From maurizio.cimadamore at oracle.com Thu Oct 5 15:44:18 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 5 Oct 2017 16:44:18 +0100 Subject: RFR JDK-8188225: AST could be improved in presence of var types. In-Reply-To: <59D5EA29.4090305@oracle.com> References: <59D25CC5.5080809@oracle.com> <5ffd68fa-6455-b412-351f-54778be3cf4a@oracle.com> <59D3CEAA.5010302@oracle.com> <59D5EA29.4090305@oracle.com> Message-ID: <98026a5b-0bf9-eb81-a55e-fb0db9092470@oracle.com> Looks good. Maurizio On 05/10/17 09:15, Jan Lahoda wrote: > Hi, > > An updated patch that has a method to generate the synthetic type > trees is here: > > http://cr.openjdk.java.net/~jlahoda/8188225/webrev.01/ > > Thanks for any feedback, > ??? Jan > > On 3.10.2017 19:58, Maurizio Cimadamore wrote: >> >> >> On 03/10/17 18:53, Jan Lahoda wrote: >>> Hi Maurizio, >>> >>> Thanks for the comments - some responses inline. >>> >>> On 3.10.2017 17:59, Maurizio Cimadamore wrote: >>>> Thanks for taking care of this, I have a couple of suggestion: >>>> >>>> * the routine for generating synthetic type tree should be shared. >>>> E.g. >>>> you need a method that takes a type and generates something that is >>>> suitable for a local variable or a lambda parameter - e.g. >>>> >>>> toSyntheticTypeTree(Type t) { >>>> ??? if (t.isErroneous()) { >>>> ?????? return make.at(Position.NOPOS).Erroneous(); >>>> ??? } else { >>>> ?????? return make.at(Position.NOPOS).Type(t); >>>> ??? } >>>> } >>> >>> Sure, will do. >>> >>>> >>>> * secondly, while adding the startpos tree is fine - here it seems >>>> like >>>> we morally would like to override the getStartPosition for the >>>> synthetic >>>> type trees created above, so that the former position is returned >>>> (e.g. >>>> that of 'var'). So, I wonder if something like this could work: >>>> >>>> toSyntheticTypeTree(Type t, int preferredPos) { >>>> ??? if (t.isErroneous()) { >>>> ?????? return make.at(preferredPos).Erroneous(); >>>> ??? } else { >>>> ?????? return make.at(preferredPos).Type(t); >>>> ??? } >>>> } >>>> >>>> Then, assuming the parser creates the local variable node with the >>>> correct pos (which it doesn't now), I think everything should work >>>> even >>> >>> Hm, you mean put the starting position to the JCVariableDecl.pos? If >>> that would be the value, we could surely avoid the field, but AFAIK >>> the JCVariableDecl.pos usually points to the name of the variable, and >>> I didn't want to add an inconsistency, or change that (as the position >>> is useful for error reporting), >>> >>> Alternatives I was thinking of included playing tricks with modifiers >>> (setting the position to modifiers (if there are no/empty modifiers) >>> and filtering it in getStartPos), with nameexpr or having a subclass >>> of JCVariableDecl for vars which would include the extra field. >> I see good points. I also thought about using a tree copier, but that >> also goes through TreeMaker, which makes it hard to e.g. create anon >> tree instances which override getStartPosition. >> >> No bother - your original solution is good enough, at least for now. I >> appreciate that the new pos field is just for var AST nodes. >> >> Maurizio >>> >>> (I was also trying to have -1 as the position of the synthetic type to >>> aid its detection, but it could still be detected by looking at the >>> end position, so this is not that big deal.) >>> >>> Thanks, >>> ??? Jan >>> >>>> w/o a dedicated field? >>>> >>>> Maurizio >>>> >>>> >>>> >>>> >>>> On 02/10/17 16:35, Jan Lahoda wrote: >>>>> Hello, >>>>> >>>>> JShell produces not ideal errors related to local variable type >>>>> inference in some cases: >>>>> --- >>>>> jshell> var i = () -> {}; >>>>> |? Error: >>>>> |? incompatible types: java.lang.Object is not a functional interface >>>>> |? var i = () -> {}; >>>>> |????????? ^------^ >>>>> --- >>>>> >>>>> Better would be: >>>>> --- >>>>> jshell> var i = () -> {}; >>>>> |? Error: >>>>> |? cannot infer type for local variable i >>>>> |??? (lambda expression needs an explicit target-type) >>>>> |? var i = () -> {}; >>>>> |? ^---------------^ >>>>> --- >>>>> >>>>> (which is the error produced by javac) >>>>> >>>>> The AST model could also be improved for local variables whose type >>>>> have been inferred (which also improves the jshell errors in some >>>>> cases): >>>>> - for "var i = 0;", the VariableTree.getType() will be null even >>>>> after >>>>> attribution, but for: "for (var i : Arrays.asList(0, 1)) {}", the >>>>> VariableTree.getType() will be filled in by Attr. (The inferred type >>>>> is also filled in for lambda parameters.) This is not only >>>>> inconsistent, but also Attr.PostAttrAnalyzer.visitVarDef may fill in >>>>> the type with an ErroneousTree (with a wrong position). The proposal >>>>> here is to always fill in the type for consistency, and to >>>>> consistently use NOPOS for the synthetic type position >>>>> >>>>> -for "var i = 0;" SourcePositions.getStartPosition does not return a >>>>> proper starting position (the position of "var"), but rather the >>>>> position of the synthetic type, if any (which can also be >>>>> ErroneousTree) or the position of the variable name. The proposal >>>>> here >>>>> is to remember the real start of the variable and return it. >>>>> >>>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8188225 >>>>> Webrev: >>>>> http://cr.openjdk.java.net/~jlahoda/8188225/webrev.00/index.html >>>>> >>>>> What do you think? >>>>> >>>>> Thanks, >>>>> ??? Jan >>>> >> From vicente.romero at oracle.com Thu Oct 5 15:48:22 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 5 Oct 2017 11:48:22 -0400 Subject: RFR 8172443: Change use of tree.pos to line:col in rawDiagnostics In-Reply-To: <64293708-fd6d-3290-6b2a-109769547297@oracle.com> References: <43e73ff3-b10d-8f8e-69d1-f15e77d8626b@oracle.com> <4d520b3a-e764-83aa-87ea-c87c1d804022@oracle.com> <9c9b29e3-238c-5fc6-bb28-beb167c7eff8@oracle.com> <64293708-fd6d-3290-6b2a-109769547297@oracle.com> Message-ID: <1f77ad16-0728-5dab-f1d2-4b79dadc8417@oracle.com> On 10/05/2017 10:40 AM, Maurizio Cimadamore wrote: > > > On 05/10/17 15:27, Vicente Romero wrote: >> >> >> On 10/05/2017 10:12 AM, Maurizio Cimadamore wrote: >>> >>> >>> On 05/10/17 15:05, Vicente Romero wrote: >>>> >>>> >>>> On 10/05/2017 09:51 AM, Maurizio Cimadamore wrote: >>>>> >>>>> >>>>> On 05/10/17 14:49, Vicente Romero wrote: >>>>>> Hi, >>>>>> >>>>>> +100 to this effort, that will save us a lot of time. Regarding >>>>>> the patch, sometimes new lines need to be added to a test, >>>>>> sometimes in the jtreg header, sometimes somewhere else. How bad >>>>>> would be to use the column number only instead of line:col? >>>>> I understand the concern. I think the goal of this patch is to fix >>>>> the #1 offender. As you say there could be other offenders. But >>>>> getting rid of them all is hard - if you just use 'col' you >>>>> basically lose uniqueness, which makes looking at the golden file >>>>> more obscure, I think. >>>> >>>> well it's true that uniqueness could be a problem for errors >>>> reported at statements that spans more than one line, but I'm not >>>> sure if it is worthy to still keep a source of brittleness because >>>> of that. I mean what could be the probability of introducing a >>>> change that will swap two identical column positions in the >>>> diagnostics and still produce the same diagnostics such that we >>>> won't detect it. In the worst case we can add the line if we see >>>> that the particular statement we are generating the diagnostics for >>>> spans more than one line and use only the column for all other cases >>> I suggest with stick with the proposed approach and then see how bad >>> it is in the real world? >> >> I think that the proposed approach will be better than the current >> situation, that's for sure, but I think that this is the right moment >> to consider if the proposed approach can be still better. If you want >> to go for it with the current version, I'm OK with that but you know >> how long it takes for stuff like this to be revisited. > I believe the ultimate fix for these kind of issues would be to > revisit the code so that instead of generating line or column info, we > generate a position that is relative to the start of the enclosing > statement. In a way this generalizes over the 'using only col' idea, > and works even for functional expressions scattered across multiple > lines (but part of the same statement). > > That said, doing that would not only require changes to the raw > diagnostic backend (as done here), but would need deeper changes in > how functional expression trees are communicated to the diagnostic > backend. Right now we just pass trees as diagnostic arguments. Trees > do not provide any contextual info (e.g. what is the parent of the > tree?) - so to do this kind of treatment (and also the treatment you > suggest where we only use column 'if needed') requires a contextual > info that the current diag arguments do not have. > > While this is all solvable, as with all fixes/enhancements, it's about > trying to achieve some kind of compromise between complexity and > benefits. Having fixed many source pos related issues, I can say with > confidence that this patch addresses almost all of them. > > When line number changes in a test file (e.g. because more stuff is > added), your golden file will have to change anyway, as all the errors > generated _after_ the insertion are going to have stale info in the > golden file. That's why I did not prioritize the 'vertical' > adjustments so much (as they are typically breaking anyway - modulo > few lucky cases). yes this is a real concern and will invalidate the golden file anyway as the line numbers generated there are absolute, and I think it is enough discussion for this small feature, so go for it. > > Maurizio Vicente >> >>> >>> Maurizio >> >> Vicente >> >>>> >>>> Vicente >>>> >>>>> >>>>> Maurizio >>>>>> >>>>>> Thanks, >>>>>> Vicente >>>>>> >>>>>> On 10/05/2017 09:29 AM, Maurizio Cimadamore wrote: >>>>>>> Hi, >>>>>>> this is a fix to our raw diagnostic machinery that will allow >>>>>>> for more robust compiler negative tests. Currently, when a >>>>>>> functional expression is found in a diagnostic, it can sometimes >>>>>>> be represented using the absoluted cursor position of the >>>>>>> expression in the source file. This makes the golden files for >>>>>>> such tests extremely unreliable, as simply adding/removing chars >>>>>>> from lines before the functional expression would result in >>>>>>> golden file mismatches. This is extremely annoying when e.g. the >>>>>>> jtreg header of a test must be change for some reason (e.g. to >>>>>>> add an extra bug id). >>>>>>> >>>>>>> The solution is to use a more robust encoding with line:col - so >>>>>>> that there's less dependencies on what happens on previous lines. >>>>>>> >>>>>>> http://cr.openjdk.java.net/~mcimadamore/8172443/ >>>>>>> >>>>>>> Cheers >>>>>>> Maurizio >>>>>>> >>>>>> >>>>> >>>> >>> >> > From vicente.romero at oracle.com Thu Oct 5 15:54:07 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 5 Oct 2017 11:54:07 -0400 Subject: RFR 8172443: Change use of tree.pos to line:col in rawDiagnostics In-Reply-To: References: <43e73ff3-b10d-8f8e-69d1-f15e77d8626b@oracle.com> Message-ID: thanks for taking a look at this, approved Vicente On 10/05/2017 11:33 AM, Maurizio Cimadamore wrote: > Hi, > I managed to find a cheap way to address the concerns w/o altering how > diagnostic arguments are communicated to the backend - revised webrev > here: > > http://cr.openjdk.java.net/~mcimadamore/8172443_v2/ > > Basically we compare the expression line number with the root > diagnostic line number, and if they are the same we omit that one. > > There's only one case where line number is needed: > > http://cr.openjdk.java.net/~mcimadamore/8172443_v2/test/langtools/tools/javac/T8024207/FlowCrashTest.out.udiff.html > > > Cheers > Maurizio > > > On 05/10/17 14:29, Maurizio Cimadamore wrote: >> Hi, >> this is a fix to our raw diagnostic machinery that will allow for >> more robust compiler negative tests. Currently, when a functional >> expression is found in a diagnostic, it can sometimes be represented >> using the absoluted cursor position of the expression in the source >> file. This makes the golden files for such tests extremely >> unreliable, as simply adding/removing chars from lines before the >> functional expression would result in golden file mismatches. This is >> extremely annoying when e.g. the jtreg header of a test must be >> change for some reason (e.g. to add an extra bug id). >> >> The solution is to use a more robust encoding with line:col - so that >> there's less dependencies on what happens on previous lines. >> >> http://cr.openjdk.java.net/~mcimadamore/8172443/ >> >> Cheers >> Maurizio >> > From bsrbnd at gmail.com Thu Oct 5 18:26:57 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Thu, 5 Oct 2017 20:26:57 +0200 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> Message-ID: On 5 October 2017 at 16:28, Vicente Romero wrote: > > > On 10/05/2017 04:32 AM, Maurizio Cimadamore wrote: >> >> Please, send me a patch with all your fixed, including the new version of >> (3) and I'll take a look/run some tests. > > > +1 yes please share the last full version Here it is, in attachment. Note that there's another possibility for pt (2), using "return noPath" instead of "throw", but I think this would probably be slower. I did only some quick tests with this last full version, so please let me know if you encounter any problem with it. I think the example I gave previously is really faster with (1) and (3); we pick immediately, in O(1), 'X' then 'Y' and finally 'Z'. Please let me know about the test results. Cheers, Bernard >> Cheers >> Maurizio > > > Vicente -------------- next part -------------- A non-text attachment was scrubbed... Name: InferenceGraph_throw.patch Type: text/x-patch Size: 7960 bytes Desc: not available URL: From maurizio.cimadamore at oracle.com Fri Oct 6 14:39:21 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 6 Oct 2017 15:39:21 +0100 Subject: RFR 8169345: javac crash when local from enclosing context is captured multiple times Message-ID: Hi, this patch fixes an issue regarding how Lower handles captured variables from enclosing scopes. Quoting from my analysis in JBS [1]: class Main { ????void test () { ????????Object o = new Object(); ????????class Local1 { ????????????Object test1() { return o; } ????????} ????????class Local2 { ?????????????void test2() { ??????????????????Object o = new Object(); ??????????????????class Local3 extends Local1 { ??????????????????????Object test3() { return o; } ???????????????????} ?????????????} ????????} ????} } Here, class Local3 captures 'o' from: * Main::test (this capture is necessary, as the superclass constructor (for Local1) will need to take that 'b' * Local2::test2 (this capture is necessary as that's the variable referenced to by the Local3::test3 method) This ends up breaking many invariants inside Lower, as: * Lower represents all captured variables using a simple encoding such as 'val' $ 'varname' - meaning that both captured variables above end up as 'val$o'. This will cause issues when looking up the variable - which is currently done with a named scope lookup (find first). * Lower.initField assumes that there's only one (synthetic) parameter named 'val$o' in the lowered constructor declaration and it also assumes that there's only one (synthetic) field in the local with the same name. This correspondency allows Lower to generate the synthetic field initializer by relying on scope properties. Here's the webrev: http://cr.openjdk.java.net/~mcimadamore/8169345/ Note - this has been briefly discussed in [2]. Cheers Maurizio [1] - https://bugs.openjdk.java.net/browse/JDK-8169345 [2] - http://mail.openjdk.java.net/pipermail/compiler-dev/2017-February/010790.html From vicente.romero at oracle.com Fri Oct 6 16:46:01 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Fri, 6 Oct 2017 12:46:01 -0400 Subject: RFR 8169345: javac crash when local from enclosing context is captured multiple times In-Reply-To: References: Message-ID: Looks good, Thanks, Vicente On 10/06/2017 10:39 AM, Maurizio Cimadamore wrote: > Hi, > this patch fixes an issue regarding how Lower handles captured > variables from enclosing scopes. Quoting from my analysis in JBS [1]: > > class Main { > ????void test () { > ????????Object o = new Object(); > ????????class Local1 { > ????????????Object test1() { return o; } > ????????} > ????????class Local2 { > ?????????????void test2() { > ??????????????????Object o = new Object(); > ??????????????????class Local3 extends Local1 { > ??????????????????????Object test3() { return o; } > ???????????????????} > ?????????????} > ????????} > ????} > } > > Here, class Local3 captures 'o' from: > > * Main::test (this capture is necessary, as the superclass constructor > (for Local1) will need to take that 'b' > * Local2::test2 (this capture is necessary as that's the variable > referenced to by the Local3::test3 method) > > This ends up breaking many invariants inside Lower, as: > > * Lower represents all captured variables using a simple encoding such > as 'val' $ 'varname' - meaning that both captured variables above end > up as 'val$o'. This will cause issues when looking up the variable - > which is currently done with a named scope lookup (find first). > > * Lower.initField assumes that there's only one (synthetic) parameter > named 'val$o' in the lowered constructor declaration and it also > assumes that there's only one (synthetic) field in the local with the > same name. This correspondency allows Lower to generate the synthetic > field initializer by relying on scope properties. > > > Here's the webrev: > > http://cr.openjdk.java.net/~mcimadamore/8169345/ > > Note - this has been briefly discussed in [2]. > > Cheers > Maurizio > > [1] - https://bugs.openjdk.java.net/browse/JDK-8169345 > [2] - > http://mail.openjdk.java.net/pipermail/compiler-dev/2017-February/010790.html > > From bsrbnd at gmail.com Sat Oct 7 14:59:41 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Sat, 7 Oct 2017 16:59:41 +0200 Subject: RFR 8169345: javac crash when local from enclosing context is captured multiple times In-Reply-To: References: Message-ID: Looks good to me, too. I noticed you used an index to differentiate the proxies which is better than simply incorporating the name of the owner as I suggested in [3] as some name clash might also occur... Thanks, Bernard [3] http://mail.openjdk.java.net/pipermail/compiler-dev/2017-February/010794.html On 6 October 2017 at 18:46, Vicente Romero wrote: > Looks good, > > Thanks, > Vicente > > > On 10/06/2017 10:39 AM, Maurizio Cimadamore wrote: >> >> Hi, >> this patch fixes an issue regarding how Lower handles captured variables >> from enclosing scopes. Quoting from my analysis in JBS [1]: >> >> class Main { >> void test () { >> Object o = new Object(); >> class Local1 { >> Object test1() { return o; } >> } >> class Local2 { >> void test2() { >> Object o = new Object(); >> class Local3 extends Local1 { >> Object test3() { return o; } >> } >> } >> } >> } >> } >> >> Here, class Local3 captures 'o' from: >> >> * Main::test (this capture is necessary, as the superclass constructor >> (for Local1) will need to take that 'b' >> * Local2::test2 (this capture is necessary as that's the variable >> referenced to by the Local3::test3 method) >> >> This ends up breaking many invariants inside Lower, as: >> >> * Lower represents all captured variables using a simple encoding such as >> 'val' $ 'varname' - meaning that both captured variables above end up as >> 'val$o'. This will cause issues when looking up the variable - which is >> currently done with a named scope lookup (find first). >> >> * Lower.initField assumes that there's only one (synthetic) parameter >> named 'val$o' in the lowered constructor declaration and it also assumes >> that there's only one (synthetic) field in the local with the same name. >> This correspondency allows Lower to generate the synthetic field initializer >> by relying on scope properties. >> >> >> Here's the webrev: >> >> http://cr.openjdk.java.net/~mcimadamore/8169345/ >> >> Note - this has been briefly discussed in [2]. >> >> Cheers >> Maurizio >> >> [1] - https://bugs.openjdk.java.net/browse/JDK-8169345 >> [2] - >> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-February/010790.html >> >> > From bsrbnd at gmail.com Mon Oct 9 18:00:04 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Mon, 9 Oct 2017 20:00:04 +0200 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> Message-ID: Hi, On 5 October 2017 at 20:26, B. Blaser wrote: > On 5 October 2017 at 16:28, Vicente Romero wrote: >> >> >> On 10/05/2017 04:32 AM, Maurizio Cimadamore wrote: >>> >>> Please, send me a patch with all your fixed, including the new version of >>> (3) and I'll take a look/run some tests. >> >> >> +1 yes please share the last full version > > Here it is, in attachment. > > Note that there's another possibility for pt (2), using "return > noPath" instead of "throw", but I think this would probably be slower. > > I did only some quick tests with this last full version, so please let > me know if you encounter any problem with it. > > I think the example I gave previously is really faster with (1) and > (3); we pick immediately, in O(1), 'X' then 'Y' and finally 'Z'. Here are two more examples showing the benefits of pt (2), this time. The first one uses 'T' via the actual arguments of 'n()' to build nodes with multiple ivars and the second one uses 'List' to build dependent nodes of single ivar. When inferring the type of the lambda parameters in the example below, we first try the non-optimal node [T, B] of size 2. Then we try node [C] of size 1 but depending on [T, A] and [T, B]. When examining the first dependency [T, A] we can immediately conclude that this possibility is worse than the best known so far, discarding it with the first 'throw' and without evaluating the second dependency [T, B]: import java.util.Map; import java.util.List; import java.util.function.BiConsumer; public class H { T m(T t) { return t; } > void n(BiConsumer f, A a, B b, C c) {} void o() { n( (x, y) -> {}, m(""), m(""), null); } } This next example shows another benefit of pt (2) when inferring the type of the lambda parameters. We first examine node [B] which depends on [T] having then a full cost of 2. Then, we start evaluating [C] which depends on [A] + [T] and [B] + [T]. When computing the full cost of [A], we can immediately discard this possibility (via the second 'throw'), the latter being worse than the best known so far: public class H { List m(T t) { return null; } > void n(BiConsumer f, A a, B b, C c) {} void o() { n( (x, y) -> {}, m(""), m(""), null); } } Cheers, Bernard > Please let me know about the test results. > > Cheers, > Bernard > >>> Cheers >>> Maurizio >> >> >> Vicente From bsrbnd at gmail.com Mon Oct 9 21:37:31 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Mon, 9 Oct 2017 23:37:31 +0200 Subject: Choosing the best inference leaf is non-deterministic Message-ID: Hi, While working on [1], I noticed that choosing the best inference leaf to be solved is non-deterministic because 'computeTreeToLeafs()' iterates on the node dependencies [2] which are stored in an 'HashSet' with unpredictable iteration order. I think this is a bit dangerous and could lead to unreproducible errors as the leaves' solving order within a subtree is unpredictable. I suggest to use a 'TreeSet' instead with predictable iteration order even if the operations are in O(log(n)) vs O(1) for the 'HashSet'. This shouldn't make too much difference with a low average number of dependencies per node. What do you think? Thanks, Bernard [1] http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011156.html [2] http://hg.openjdk.java.net/jdk10/master/file/6cb6ef406e97/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java#l1382 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java @@ -59,6 +59,7 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; +import java.util.TreeSet; import java.util.Map; import java.util.Optional; import java.util.Properties; @@ -1705,11 +1706,11 @@ class Node extends GraphUtils.TarjanNode, Node> implements DottableNode, Node> { /** node dependencies */ - Set deps; + TreeSet deps; Node(Type ivar) { super(ListBuffer.of(ivar)); - this.deps = new HashSet<>(); + this.deps = new TreeSet<>(); } @Override @@ -1780,7 +1781,7 @@ addDependencies(n.deps); } //update deps - Set deps2 = new HashSet<>(); + TreeSet deps2 = new TreeSet<>(); for (Node d : deps) { if (data.contains(d.data.first())) { deps2.add(this); From maurizio.cimadamore at oracle.com Tue Oct 10 00:02:58 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 10 Oct 2017 01:02:58 +0100 Subject: Choosing the best inference leaf is non-deterministic In-Reply-To: References: Message-ID: Sure - we had other issues in this vein - determinism trumps every other possible use case in this area; dependencies should be stored in a data structure that preserves insertion order. That said, since the algorithm for creating an inference graph is deterministic - and we end up adding same elements in same order - while I buy that the iteration order of the dependencies will not reflect the insertion order, shouldn't it at least be stable? But then, I note that InferenceGraph.Node doesn't override equals/hashcode, so that's definitively a possible cause for non-determinism - if default Object.hash changes, items will be inserted in the set in different ways, leading to different iteration orders. Maurizio On 09/10/17 22:37, B. Blaser wrote: > Hi, > > While working on [1], I noticed that choosing the best inference leaf > to be solved is non-deterministic because 'computeTreeToLeafs()' > iterates on the node dependencies [2] which are stored in an 'HashSet' > with unpredictable iteration order. > > I think this is a bit dangerous and could lead to unreproducible > errors as the leaves' solving order within a subtree is unpredictable. > I suggest to use a 'TreeSet' instead with predictable iteration order > even if the operations are in O(log(n)) vs O(1) for the 'HashSet'. > This shouldn't make too much difference with a low average number of > dependencies per node. > > What do you think? > > Thanks, > Bernard > > [1] http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011156.html > [2] http://hg.openjdk.java.net/jdk10/master/file/6cb6ef406e97/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java#l1382 > > > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java > b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java > @@ -59,6 +59,7 @@ > import java.util.EnumSet; > import java.util.HashMap; > import java.util.HashSet; > +import java.util.TreeSet; > import java.util.Map; > import java.util.Optional; > import java.util.Properties; > @@ -1705,11 +1706,11 @@ > class Node extends > GraphUtils.TarjanNode, Node> implements > DottableNode, Node> { > > /** node dependencies */ > - Set deps; > + TreeSet deps; > > Node(Type ivar) { > super(ListBuffer.of(ivar)); > - this.deps = new HashSet<>(); > + this.deps = new TreeSet<>(); > } > > @Override > @@ -1780,7 +1781,7 @@ > addDependencies(n.deps); > } > //update deps > - Set deps2 = new HashSet<>(); > + TreeSet deps2 = new TreeSet<>(); > for (Node d : deps) { > if (data.contains(d.data.first())) { > deps2.add(this); From bsrbnd at gmail.com Tue Oct 10 09:26:52 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Tue, 10 Oct 2017 11:26:52 +0200 Subject: Choosing the best inference leaf is non-deterministic In-Reply-To: References: Message-ID: This is stable enough until we find a failing example;-) If you run twice the second example given in [1], you'll see that the nodes aren't always solved in the same order... While there isn't any problem in this case, this non-deterministic behavior is definitively unsafe, which is probably due to the fact that the default 'hashCode()' might depend on the reference (memory location), see [3]. The 'TreeSet' I suggested yesterday isn't probably a good solution neither as it uses the comparison method defined to compute the acyclic graph. So, something derived from 'LinkedHashMap' would be better to preserve the insertion order and to access the elements in O(1). Or, at least, overriding 'hashCode()' with something more stable while not preserving the insertion order (a sequential index assigned to each node when the inference graph is created, for example). What do you think? Bernard [3] https://docs.oracle.com/javase/9/docs/api/java/lang/Object.html#hashCode-- On 10 October 2017 at 02:02, Maurizio Cimadamore wrote: > Sure - we had other issues in this vein - determinism trumps every other > possible use case in this area; dependencies should be stored in a data > structure that preserves insertion order. > > That said, since the algorithm for creating an inference graph is > deterministic - and we end up adding same elements in same order - while I > buy that the iteration order of the dependencies will not reflect the > insertion order, shouldn't it at least be stable? > > But then, I note that InferenceGraph.Node doesn't override equals/hashcode, > so that's definitively a possible cause for non-determinism - if default > Object.hash changes, items will be inserted in the set in different ways, > leading to different iteration orders. > > Maurizio > > > > On 09/10/17 22:37, B. Blaser wrote: >> >> Hi, >> >> While working on [1], I noticed that choosing the best inference leaf >> to be solved is non-deterministic because 'computeTreeToLeafs()' >> iterates on the node dependencies [2] which are stored in an 'HashSet' >> with unpredictable iteration order. >> >> I think this is a bit dangerous and could lead to unreproducible >> errors as the leaves' solving order within a subtree is unpredictable. >> I suggest to use a 'TreeSet' instead with predictable iteration order >> even if the operations are in O(log(n)) vs O(1) for the 'HashSet'. >> This shouldn't make too much difference with a low average number of >> dependencies per node. >> >> What do you think? >> >> Thanks, >> Bernard >> >> [1] >> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011156.html >> [2] >> http://hg.openjdk.java.net/jdk10/master/file/6cb6ef406e97/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java#l1382 >> >> >> diff --git >> a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >> @@ -59,6 +59,7 @@ >> import java.util.EnumSet; >> import java.util.HashMap; >> import java.util.HashSet; >> +import java.util.TreeSet; >> import java.util.Map; >> import java.util.Optional; >> import java.util.Properties; >> @@ -1705,11 +1706,11 @@ >> class Node extends >> GraphUtils.TarjanNode, Node> implements >> DottableNode, Node> { >> >> /** node dependencies */ >> - Set deps; >> + TreeSet deps; >> >> Node(Type ivar) { >> super(ListBuffer.of(ivar)); >> - this.deps = new HashSet<>(); >> + this.deps = new TreeSet<>(); >> } >> >> @Override >> @@ -1780,7 +1781,7 @@ >> addDependencies(n.deps); >> } >> //update deps >> - Set deps2 = new HashSet<>(); >> + TreeSet deps2 = new TreeSet<>(); >> for (Node d : deps) { >> if (data.contains(d.data.first())) { >> deps2.add(this); > > From maurizio.cimadamore at oracle.com Tue Oct 10 09:45:13 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 10 Oct 2017 10:45:13 +0100 Subject: Choosing the best inference leaf is non-deterministic In-Reply-To: References: Message-ID: <1b7b6fc8-6604-f300-93b7-1d61b83eb7d7@oracle.com> On 10/10/17 10:26, B. Blaser wrote: > This is stable enough until we find a failing example;-) > > If you run twice the second example given in [1], you'll see that the > nodes aren't always solved in the same order... > > While there isn't any problem in this case, this non-deterministic > behavior is definitively unsafe, which is probably due to the fact > that the default 'hashCode()' might depend on the reference (memory > location), see [3]. > > The 'TreeSet' I suggested yesterday isn't probably a good solution > neither as it uses the comparison method defined to compute the > acyclic graph. > > So, something derived from 'LinkedHashMap' would be better to preserve > the insertion order and to access the elements in O(1). Or, at least, > overriding 'hashCode()' with something more stable while not > preserving the insertion order (a sequential index assigned to each > node when the inference graph is created, for example). > > What do you think? I think we need to understand the source of non-determinism. If that is simply caused by nodes not having stable equals and hashcode, we might as well add those methods, and make the problem go away w/o any extra memory cost. Iteration order could still be non-deterministic in multi-threaded scenario, but that's not a concern with this part of javac. Or, we could look into a more robust data structure - typically LinkedHashSet is used in such cases, which is probably more robust longer term. Or we could do both :-) Maurizio > > Bernard > > [3] https://docs.oracle.com/javase/9/docs/api/java/lang/Object.html#hashCode-- > > > On 10 October 2017 at 02:02, Maurizio Cimadamore > wrote: >> Sure - we had other issues in this vein - determinism trumps every other >> possible use case in this area; dependencies should be stored in a data >> structure that preserves insertion order. >> >> That said, since the algorithm for creating an inference graph is >> deterministic - and we end up adding same elements in same order - while I >> buy that the iteration order of the dependencies will not reflect the >> insertion order, shouldn't it at least be stable? >> >> But then, I note that InferenceGraph.Node doesn't override equals/hashcode, >> so that's definitively a possible cause for non-determinism - if default >> Object.hash changes, items will be inserted in the set in different ways, >> leading to different iteration orders. >> >> Maurizio >> >> >> >> On 09/10/17 22:37, B. Blaser wrote: >>> Hi, >>> >>> While working on [1], I noticed that choosing the best inference leaf >>> to be solved is non-deterministic because 'computeTreeToLeafs()' >>> iterates on the node dependencies [2] which are stored in an 'HashSet' >>> with unpredictable iteration order. >>> >>> I think this is a bit dangerous and could lead to unreproducible >>> errors as the leaves' solving order within a subtree is unpredictable. >>> I suggest to use a 'TreeSet' instead with predictable iteration order >>> even if the operations are in O(log(n)) vs O(1) for the 'HashSet'. >>> This shouldn't make too much difference with a low average number of >>> dependencies per node. >>> >>> What do you think? >>> >>> Thanks, >>> Bernard >>> >>> [1] >>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011156.html >>> [2] >>> http://hg.openjdk.java.net/jdk10/master/file/6cb6ef406e97/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java#l1382 >>> >>> >>> diff --git >>> a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>> @@ -59,6 +59,7 @@ >>> import java.util.EnumSet; >>> import java.util.HashMap; >>> import java.util.HashSet; >>> +import java.util.TreeSet; >>> import java.util.Map; >>> import java.util.Optional; >>> import java.util.Properties; >>> @@ -1705,11 +1706,11 @@ >>> class Node extends >>> GraphUtils.TarjanNode, Node> implements >>> DottableNode, Node> { >>> >>> /** node dependencies */ >>> - Set deps; >>> + TreeSet deps; >>> >>> Node(Type ivar) { >>> super(ListBuffer.of(ivar)); >>> - this.deps = new HashSet<>(); >>> + this.deps = new TreeSet<>(); >>> } >>> >>> @Override >>> @@ -1780,7 +1781,7 @@ >>> addDependencies(n.deps); >>> } >>> //update deps >>> - Set deps2 = new HashSet<>(); >>> + TreeSet deps2 = new TreeSet<>(); >>> for (Node d : deps) { >>> if (data.contains(d.data.first())) { >>> deps2.add(this); >> From bsrbnd at gmail.com Tue Oct 10 20:43:00 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Tue, 10 Oct 2017 22:43:00 +0200 Subject: Choosing the best inference leaf is non-deterministic In-Reply-To: <1b7b6fc8-6604-f300-93b7-1d61b83eb7d7@oracle.com> References: <1b7b6fc8-6604-f300-93b7-1d61b83eb7d7@oracle.com> Message-ID: On 10 October 2017 at 11:45, Maurizio Cimadamore wrote: > > > On 10/10/17 10:26, B. Blaser wrote: >> >> This is stable enough until we find a failing example;-) >> >> If you run twice the second example given in [1], you'll see that the >> nodes aren't always solved in the same order... >> >> While there isn't any problem in this case, this non-deterministic >> behavior is definitively unsafe, which is probably due to the fact >> that the default 'hashCode()' might depend on the reference (memory >> location), see [3]. >> >> The 'TreeSet' I suggested yesterday isn't probably a good solution >> neither as it uses the comparison method defined to compute the >> acyclic graph. >> >> So, something derived from 'LinkedHashMap' would be better to preserve >> the insertion order and to access the elements in O(1). Or, at least, >> overriding 'hashCode()' with something more stable while not >> preserving the insertion order (a sequential index assigned to each >> node when the inference graph is created, for example). >> >> What do you think? > > I think we need to understand the source of non-determinism. If that is > simply caused by nodes not having stable equals and hashcode, we might as > well add those methods, and make the problem go away w/o any extra memory > cost. Iteration order could still be non-deterministic in multi-threaded > scenario, but that's not a concern with this part of javac. > > Or, we could look into a more robust data structure - typically > LinkedHashSet is used in such cases, which is probably more robust longer > term. I think 'LinkedHashSet' is exactly what we need here, as next. Thanks! Bernard diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java @@ -59,6 +59,7 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Optional; import java.util.Properties; @@ -1705,11 +1706,11 @@ class Node extends GraphUtils.TarjanNode, Node> implements DottableNode, Node> { /** node dependencies */ - Set deps; + LinkedHashSet deps; Node(Type ivar) { super(ListBuffer.of(ivar)); - this.deps = new HashSet<>(); + this.deps = new LinkedHashSet<>(); } @Override @@ -1780,7 +1781,7 @@ addDependencies(n.deps); } //update deps - Set deps2 = new HashSet<>(); + LinkedHashSet deps2 = new LinkedHashSet<>(); for (Node d : deps) { if (data.contains(d.data.first())) { deps2.add(this); > Or we could do both :-) > > Maurizio > >> >> Bernard >> >> [3] >> https://docs.oracle.com/javase/9/docs/api/java/lang/Object.html#hashCode-- From georgiy.rakov at oracle.com Wed Oct 11 15:57:50 2017 From: georgiy.rakov at oracle.com (Georgiy Rakov) Date: Wed, 11 Oct 2017 21:27:50 +0530 Subject: LVTI: as per spec upward projection couldn't have resulted in a '? extends' parameterization Message-ID: <3f1b3dd9-77e0-2378-21bc-80ea82d47445@oracle.com> HelloDan, let's consider following code: class C0 {} ??? class C1 extends C0 {} ??? ??? class C2 extends C1 {} public class Shell { ??? void set(T t) {} ??? T get() {return null;} ??? public static void main(String args[]) { ??? ??? Shell y = new Shell(); ??? ??? var z = y; //upward projection is applied here ??? ??? z = new Shell(); //compilation succeeds ??? ??? z = new Shell(); //compilation succeeds ??? ??? z = new C0();??????? //obviously compilation error ??? ??? C0 c0 = z.get(); //compilation succeeds ??? ??? C1 c1 = z.get(); //compilation succeeds ??? ??? C2 c2 = z.get(); //compilation error ??? } } When compiling this code by javac from jdk10 build 25 we receive following output: Shell.java:16: error: incompatible types: C0 cannot be converted to Shell ??????????????? z = new C0();??????? //obviously compilation error ??????????????????? ^ Shell.java:20: error: incompatible types: CAP#1 cannot be converted to C2 ??????????????? C2 c2 = z.get(); //compilation error ???????????????????????????? ^ ? where CAP#1 is a fresh type-variable: ??? CAP#1 extends C1 from capture of ? extends C1 2 errors From this output and the fact which lines compile and which don't it follows that the type of 'z' variable was inferred as Shell. However according to spec [1] this couldn't have happened because of the following reasoning. 1. Let's consider assertion below from [1]: *If /LocalVariableType/ is |var|, then let /T/ be the type of the initializer expression when treated as if it did not appear in an assignment context, and were thus a standalone expression (15.2 ). The type of the local variable is the upward projection of /T/ with respect to all synthetic type variables mentioned by /T/ (4.10.5 ).* ** according to this assertion:* *type_of(z) = upward_projection(type_of(y)) = upward_projection(capture_conversion(Shell)) = upward_projection(Shell) where CAP is a capture variable with following bounds: NULL_TYPE <: CAP <: glb(C0, C1) => NULL_TYPE <: CAP <: C1 2. When applying upward projection to Shell, T is Shell and restricted type variables include just CAP. 3. During upward projection assertions below from [1] are touched:** ** *If T is a parameterized class type or a parameterized interface type, G, then the result is G, where, for 1 ? i ? n, Ai' is derived from Ai as follows: ? ... ? If Ai is a type that mentions a restricted type variable, then Ai' is a wildcard. Let U be the upward projection of Ai. There are three cases: * Here we have just A1 which is CAP so U=upward_projection(A1)=upward_projection(CAP)=upward_projection(C1)=C1 4. Afterwards following assertion from [1] is touched: *If /U/ is not |Object|, and if either the declared bound of the ith parameter of /G/, /Bi/, mentions a type parameter of /G/, or /Bi/ is not a subtype of /U/, then /Ai'/ is an upper-bounded wildcard, /|? extends| U/.* ** Here we have just B1 which is C1, so: **a. "*/U/ is not |Object|*" is _true_ since U is C1; b. "*the declared bound of the ith parameter of /G/, /Bi/, mentions a type parameter of /G/*" is _false_ since B1 is C1 - no type parameters are mentioned; c. "*/Bi/ is not a subtype of /U/*" is _false_ because both B1 and U are C1 so B1 is a subtype of U since a class is always a subtype of itself. For this reason A1' cannot be defined by this assertion as ? extends C1 which would make upward projection to result in Shell, so none of other assertions can do either. This looks like a spec issue because the result of upper projection provided by javac looks reasonable. Is it really a spec issue? It's not quite clear why "*/Bi/ is not a subtype of /U/*" was added to the specification. Some examples clarifying this point would be highly appreciated. [1] http://cr.openjdk.java.net/~dlsmith/local-var-inference.html Thank you, Georgiy -------------- next part -------------- An HTML attachment was scrubbed... URL: From daniel.smith at oracle.com Wed Oct 11 20:39:54 2017 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 11 Oct 2017 14:39:54 -0600 Subject: LVTI: as per spec upward projection couldn't have resulted in a '? extends' parameterization In-Reply-To: <3f1b3dd9-77e0-2378-21bc-80ea82d47445@oracle.com> References: <3f1b3dd9-77e0-2378-21bc-80ea82d47445@oracle.com> Message-ID: <845EA5E9-1BF1-45FF-96AB-68DCE9A1F990@oracle.com> Hey, thanks for careful testing of these rules. I'm sure they can use some scrutiny! > On Oct 11, 2017, at 9:57 AM, Georgiy Rakov wrote: > > 4. Afterwards following assertion from [1] is touched: > If U is not Object, and if either the declared bound of the ith parameter of G, Bi, mentions a type parameter of G, or Bi is not a subtype of U, then Ai' is an upper-bounded wildcard, ? extends U. > Here we have just B1 which is C1, so: > a. "U is not Object" is true since U is C1; > b. "the declared bound of the ith parameter of G, Bi, mentions a type parameter of G" is false since B1 is C1 - no type parameters are mentioned; > c. "Bi is not a subtype of U" is false because both B1 and U are C1 so B1 is a subtype of U since a class is always a subtype of itself. > > For this reason A1' cannot be defined by this assertion as ? extends C1 which would make upward projection to result in Shell, so none of other assertions can do either. You are right that this rule does not apply. What you are missing is that, per the subsequent rules, the type is Shell Subsequently, all reads of 'z' have type capture(Shell) = Shell where CAP extends C1 In other words, there is no need to mention C1 in the type, because it is implicit from the declaration-site bound of T in Shell. > It's not quite clear why "Bi is not a subtype of U" was added to the specification. Some examples clarifying this point would be highly appreciated. Ideally, we'd like an upper bound and a lower bound: ? extends upward(Ai) super downward(Ai) However, wildcards aren't expressive enough to have both upper and lower bounds, so we have to pick one. The heuristic is: if the upper bound is "meaningful", use that. If the upper bound is not meaningful, use the lower bound instead (or nothing, if there is no lower bound). The definition of "meaningful" is, loosely, "something that may affect the upper bound of the capture of the result". If Bi is a subtype of of U, then U will not affect the upper bound of the capture of the result, because capture will just do a glb(Bi, U) = Bi. ?Dan -------------- next part -------------- An HTML attachment was scrubbed... URL: From joe.darcy at oracle.com Thu Oct 12 00:57:32 2017 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Wed, 11 Oct 2017 17:57:32 -0700 Subject: Interim JDK 10 RFR of 8187951: Update javax.lang.model.SourceVersion for "var" name In-Reply-To: References: <1f9b858d-4e43-8c9d-cbc1-60c728380bdc@oracle.com> <67ca68b6-46f3-1be6-5607-c59ce97407e3@oracle.com> <72dda0f6-7317-c538-8d4d-6029c872602c@oracle.com> Message-ID: <59DEBDFC.6060405@oracle.com> Hi Jon, Catching up post-JavaOne... On 9/29/2017 11:12 AM, Jonathan Gibbons wrote: > > Joe, > > I guess I would ask, who are these methods targeted at? > > Both isIdentifier and isKeyword are fuzzy at best. > > isIdentifier does not take the appropriate Unicode standard into > account, although it is probably "good enough". > Right; specifically it doesn't use the Unicode standard that was in force at the time of the earlier releases. Each major JDK platform release generally bumps the supported Unicode version and set of identifier characters expands. To be 100% accurate the isIdentifier check on release (N - k) for some k > 0 would need the Unicode tables used on JDK (N - k). That information is not available via the platform APIs. > isKeyword has certainly become more complex in 9 and after, and anyone > who really needs this info (e.g. IDEs) is probably already doing it > for themselves, properly. > > Do you have any reasonable use-cases for a fuzzy definition of > isKeyword, or should we just deprecate it words the Big Bit Bucket in > the sky? > My thought was for annotation processor authors to have some easy ways to verify a name was valid to use on a given source version, etc. I agree tools like IDEs will need more precise implementations of such checks, but I think there is still benefit in providing less formal checking too. -Joe -------------- next part -------------- An HTML attachment was scrubbed... URL: From volker.simonis at gmail.com Thu Oct 12 10:33:33 2017 From: volker.simonis at gmail.com (Volker Simonis) Date: Thu, 12 Oct 2017 03:33:33 -0700 Subject: Interim JDK 10 RFR of 8187951: Update javax.lang.model.SourceVersion for "var" name In-Reply-To: <59DEBDFC.6060405@oracle.com> References: <1f9b858d-4e43-8c9d-cbc1-60c728380bdc@oracle.com> <67ca68b6-46f3-1be6-5607-c59ce97407e3@oracle.com> <72dda0f6-7317-c538-8d4d-6029c872602c@oracle.com> <59DEBDFC.6060405@oracle.com> Message-ID: Hi Joe, I just have a quick question regarding the overall development approach for jdk 10 (aka jdk 18.3). As Mark has wrote several times (e.g. [1]) "every feature must be complete before it's integrated". Your change clearly belongs to "JEP 286: Local-Variable Type Inference" which doesn't seem to be complete until now. So from my understanding of Mark's "Accelerating the JDK release cadence" proposal [2], where he writes that "..the bar to target a JEP to a specific release will, however, be higher since the work must be Feature Complete in order to go in..", this requires "at the very least, all necessary code, specification text, and unit tests" [1]. While JEP 286 has already been targeted for JDK 10, I can only find a specification attached to the JEP issue but no full implementation and unit tests. Maybe the implementation is already in the Amber repository (I can't really judge) but I saw that 'lvti' branch in Amber was created just two weeks ago. So to cut a long story short: according to the new development model, shouldn't the complete JEP 286 be developed and tested in its own repo or branch and only integrated into jdk10 once it is "feature complete" ? Thanks, Volker [1] http://mail.openjdk.java.net/pipermail/jdk-dev/2017-October/000001.html [2] http://mail.openjdk.java.net/pipermail/discuss/2017-September/004281.html On Wed, Oct 11, 2017 at 5:57 PM, Joseph D. Darcy wrote: > Hi Jon, > > Catching up post-JavaOne... > > On 9/29/2017 11:12 AM, Jonathan Gibbons wrote: > > Joe, > > I guess I would ask, who are these methods targeted at? > > Both isIdentifier and isKeyword are fuzzy at best. > > isIdentifier does not take the appropriate Unicode standard into account, > although it is probably "good enough". > > > Right; specifically it doesn't use the Unicode standard that was in force at > the time of the earlier releases. Each major JDK platform release generally > bumps the supported Unicode version and set of identifier characters > expands. To be 100% accurate the isIdentifier check on release (N - k) for > some k > 0 would need the Unicode tables used on JDK (N - k). That > information is not available via the platform APIs. > > isKeyword has certainly become more complex in 9 and after, and anyone who > really needs this info (e.g. IDEs) is probably already doing it for > themselves, properly. > > Do you have any reasonable use-cases for a fuzzy definition of isKeyword, or > should we just deprecate it words the Big Bit Bucket in the sky? > > > My thought was for annotation processor authors to have some easy ways to > verify a name was valid to use on a given source version, etc. > > I agree tools like IDEs will need more precise implementations of such > checks, but I think there is still benefit in providing less formal checking > too. > > -Joe > From maurizio.cimadamore at oracle.com Thu Oct 12 13:57:57 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 12 Oct 2017 14:57:57 +0100 Subject: Interim JDK 10 RFR of 8187951: Update javax.lang.model.SourceVersion for "var" name In-Reply-To: References: <1f9b858d-4e43-8c9d-cbc1-60c728380bdc@oracle.com> <67ca68b6-46f3-1be6-5607-c59ce97407e3@oracle.com> <72dda0f6-7317-c538-8d4d-6029c872602c@oracle.com> <59DEBDFC.6060405@oracle.com> Message-ID: <402cdc14-4d45-78f9-7904-f521d276e127@oracle.com> On 12/10/17 11:33, Volker Simonis wrote: > Hi Joe, > > I just have a quick question regarding the overall development > approach for jdk 10 (aka jdk 18.3). > > As Mark has wrote several times (e.g. [1]) "every feature must be > complete before it's integrated". Your change clearly belongs to "JEP > 286: Local-Variable Type Inference" which doesn't seem to be complete > until now. So from my understanding of Mark's "Accelerating the JDK > release cadence" proposal [2], where he writes that "..the bar to > target a JEP to a specific release will, however, be higher since the > work must be Feature Complete in order to go in..", this requires "at > the very least, all necessary code, specification text, and unit > tests" [1]. > > While JEP 286 has already been targeted for JDK 10, I can only find a > specification attached to the JEP issue but no full implementation and > unit tests. Maybe the implementation is already in the Amber > repository (I can't really judge) but I saw that 'lvti' branch in > Amber was created just two weeks ago. Hi Volker, the lvti prototype has been available for several months now; it has been first discussed here [1]. Then, when we create project Amber, lvti was one of the first branch to be created [2]. What you see (2 weeks ago) is the re-creation of same branch when we moved to a consolidated amber repo - which we did by moving contents over from old non-consolidated amber repo to the new one. Both repos are still available for people to see [3]. Unit tests are available (and have been for quite some time) [4], and the spec text has also been available for some time [5], although it has recently been rebased and improved (as part of the CSR process). Ultimately, I think this feature was "complete" when it was integrated into JDK 10 [6], by some reasonable definition of complete. For every feature there's always a small tail of things that have been missed, or that need to be adjusted/tweaked based on feedback - JEP 286 is no exception to this. Cheers Maurizio [1] - http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html [2] - http://mail.openjdk.java.net/pipermail/amber-dev/2017-March/000019.html [3] - http://hg.openjdk.java.net/amber/ [4] - http://hg.openjdk.java.net/amber/amber10-old/langtools/file/940ff165a2c3/test/tools/javac/diags/examples/LocalNonDenotable.java [5] - http://mail.openjdk.java.net/pipermail/amber-spec-experts/2017-March/000015.html [6] -http://hg.openjdk.java.net/jdk10/master/rev/48ec75306997 > > So to cut a long story short: according to the new development model, > shouldn't the complete JEP 286 be developed and tested in its own repo > or branch and only integrated into jdk10 once it is "feature complete" > ? > > Thanks, > Volker > > [1] http://mail.openjdk.java.net/pipermail/jdk-dev/2017-October/000001.html > [2] http://mail.openjdk.java.net/pipermail/discuss/2017-September/004281.html > > On Wed, Oct 11, 2017 at 5:57 PM, Joseph D. Darcy wrote: >> Hi Jon, >> >> Catching up post-JavaOne... >> >> On 9/29/2017 11:12 AM, Jonathan Gibbons wrote: >> >> Joe, >> >> I guess I would ask, who are these methods targeted at? >> >> Both isIdentifier and isKeyword are fuzzy at best. >> >> isIdentifier does not take the appropriate Unicode standard into account, >> although it is probably "good enough". >> >> >> Right; specifically it doesn't use the Unicode standard that was in force at >> the time of the earlier releases. Each major JDK platform release generally >> bumps the supported Unicode version and set of identifier characters >> expands. To be 100% accurate the isIdentifier check on release (N - k) for >> some k > 0 would need the Unicode tables used on JDK (N - k). That >> information is not available via the platform APIs. >> >> isKeyword has certainly become more complex in 9 and after, and anyone who >> really needs this info (e.g. IDEs) is probably already doing it for >> themselves, properly. >> >> Do you have any reasonable use-cases for a fuzzy definition of isKeyword, or >> should we just deprecate it words the Big Bit Bucket in the sky? >> >> >> My thought was for annotation processor authors to have some easy ways to >> verify a name was valid to use on a given source version, etc. >> >> I agree tools like IDEs will need more precise implementations of such >> checks, but I think there is still benefit in providing less formal checking >> too. >> >> -Joe >> From jan.lahoda at oracle.com Thu Oct 12 15:04:33 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Thu, 12 Oct 2017 17:04:33 +0200 Subject: RFR: JDK-8187681: Compiling for target 9 while also using --patch-module Message-ID: <59DF8481.7010103@oracle.com> Hello, I'd like to ask for a review for: Bug: https://bugs.openjdk.java.net/browse/JDK-8187681 Webrev: http://cr.openjdk.java.net/~jlahoda/8187681/webrev.00/ The patch is basically to remove the limitation on use of --patch-module for a system module in combination with --release. Thanks, Jan From maurizio.cimadamore at oracle.com Thu Oct 12 15:24:03 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 12 Oct 2017 16:24:03 +0100 Subject: RFR: JDK-8187681: Compiling for target 9 while also using --patch-module In-Reply-To: <59DF8481.7010103@oracle.com> References: <59DF8481.7010103@oracle.com> Message-ID: Looks good Maurizio On 12/10/17 16:04, Jan Lahoda wrote: > Hello, > > I'd like to ask for a review for: > Bug: https://bugs.openjdk.java.net/browse/JDK-8187681 > Webrev: http://cr.openjdk.java.net/~jlahoda/8187681/webrev.00/ > > The patch is basically to remove the limitation on use of > --patch-module for a system module in combination with --release. > > Thanks, > ??? Jan From maurizio.cimadamore at oracle.com Thu Oct 12 15:26:30 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 12 Oct 2017 16:26:30 +0100 Subject: RFR: JDK-8187681: Compiling for target 9 while also using --patch-module In-Reply-To: References: <59DF8481.7010103@oracle.com> Message-ID: <330badc4-4175-b349-8556-bb446adbc909@oracle.com> Whoops - hit send too fast - wanted to ask a question; do you also plan to remove similar restriction for -source ? I've hit that a couple of times, and currently this restriction is preventing me from running langtools tests on a patched compiler; that is, I can patch the VM to run the tests and that works, but I can't pass same set of patches to the javac used by jtreg, as that will result in errors whenever a test has e.g. -source 8 flag set. Maurizio On 12/10/17 16:24, Maurizio Cimadamore wrote: > Looks good > > Maurizio > > > On 12/10/17 16:04, Jan Lahoda wrote: >> Hello, >> >> I'd like to ask for a review for: >> Bug: https://bugs.openjdk.java.net/browse/JDK-8187681 >> Webrev: http://cr.openjdk.java.net/~jlahoda/8187681/webrev.00/ >> >> The patch is basically to remove the limitation on use of >> --patch-module for a system module in combination with --release. >> >> Thanks, >> ??? Jan > From jan.lahoda at oracle.com Thu Oct 12 15:48:37 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Thu, 12 Oct 2017 17:48:37 +0200 Subject: RFR: JDK-8187681: Compiling for target 9 while also using --patch-module In-Reply-To: <330badc4-4175-b349-8556-bb446adbc909@oracle.com> References: <59DF8481.7010103@oracle.com> <330badc4-4175-b349-8556-bb446adbc909@oracle.com> Message-ID: <59DF8ED5.30501@oracle.com> On 12.10.2017 17:26, Maurizio Cimadamore wrote: > Whoops - hit send too fast - wanted to ask a question; do you also plan > to remove similar restriction for -source ? I've hit that a couple of > times, and currently this restriction is preventing me from running > langtools tests on a patched compiler; that is, I can patch the VM to > run the tests and that works, but I can't pass same set of patches to > the javac used by jtreg, as that will result in errors whenever a test > has e.g. -source 8 flag set. I am afraid this is more involved. The restriction removed here is mostly for consistency with restricting --add-exports for system modules with --release, which is mostly for safety. So this is mostly deleting a check. Allowing --patch-module with -source < 9 is more complex, as it means actually changing the file manager to reflect the option for StandardLocation.PLATFORM_CLASS_PATH (and check there's no -bootclasspath, combined with --patch-module, as that would not make much sense). But might still be possible. Jon, any comment? Thanks, Jan > > Maurizio > > > > On 12/10/17 16:24, Maurizio Cimadamore wrote: >> Looks good >> >> Maurizio >> >> >> On 12/10/17 16:04, Jan Lahoda wrote: >>> Hello, >>> >>> I'd like to ask for a review for: >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8187681 >>> Webrev: http://cr.openjdk.java.net/~jlahoda/8187681/webrev.00/ >>> >>> The patch is basically to remove the limitation on use of >>> --patch-module for a system module in combination with --release. >>> >>> Thanks, >>> Jan >> > From volker.simonis at gmail.com Thu Oct 12 16:51:36 2017 From: volker.simonis at gmail.com (Volker Simonis) Date: Thu, 12 Oct 2017 09:51:36 -0700 Subject: Interim JDK 10 RFR of 8187951: Update javax.lang.model.SourceVersion for "var" name In-Reply-To: <402cdc14-4d45-78f9-7904-f521d276e127@oracle.com> References: <1f9b858d-4e43-8c9d-cbc1-60c728380bdc@oracle.com> <67ca68b6-46f3-1be6-5607-c59ce97407e3@oracle.com> <72dda0f6-7317-c538-8d4d-6029c872602c@oracle.com> <59DEBDFC.6060405@oracle.com> <402cdc14-4d45-78f9-7904-f521d276e127@oracle.com> Message-ID: Hi Maurizio, thanks a lot for the detailed information. The integration indeed makes more sense now. I just asked because we had our first JCP JDK 18.3 EG meeting today and I try to understand how the JEP process and the JSR JCP process work together (JEP 286 is currently the only JEP targeted for Java 18.3 so I had to beat on you :). In general (and this is not related to your JEP anymore which seems in good shape) I think it would be nice if every JEP which is proposed to be targeted contains some information about where the implementation / test / specification can be found (binaries to easily test the new feature would always be a plus of corse :) Thanks, Volker On Thu, Oct 12, 2017 at 6:57 AM, Maurizio Cimadamore wrote: > > > On 12/10/17 11:33, Volker Simonis wrote: >> >> Hi Joe, >> >> I just have a quick question regarding the overall development >> approach for jdk 10 (aka jdk 18.3). >> >> As Mark has wrote several times (e.g. [1]) "every feature must be >> complete before it's integrated". Your change clearly belongs to "JEP >> 286: Local-Variable Type Inference" which doesn't seem to be complete >> until now. So from my understanding of Mark's "Accelerating the JDK >> release cadence" proposal [2], where he writes that "..the bar to >> target a JEP to a specific release will, however, be higher since the >> work must be Feature Complete in order to go in..", this requires "at >> the very least, all necessary code, specification text, and unit >> tests" [1]. >> >> While JEP 286 has already been targeted for JDK 10, I can only find a >> specification attached to the JEP issue but no full implementation and >> unit tests. Maybe the implementation is already in the Amber >> repository (I can't really judge) but I saw that 'lvti' branch in >> Amber was created just two weeks ago. > > Hi Volker, > the lvti prototype has been available for several months now; it has been > first discussed here [1]. Then, when we create project Amber, lvti was one > of the first branch to be created [2]. What you see (2 weeks ago) is the > re-creation of same branch when we moved to a consolidated amber repo - > which we did by moving contents over from old non-consolidated amber repo to > the new one. Both repos are still available for people to see [3]. > > Unit tests are available (and have been for quite some time) [4], and the > spec text has also been available for some time [5], although it has > recently been rebased and improved (as part of the CSR process). > > Ultimately, I think this feature was "complete" when it was integrated into > JDK 10 [6], by some reasonable definition of complete. For every feature > there's always a small tail of things that have been missed, or that need to > be adjusted/tweaked based on feedback - JEP 286 is no exception to this. > > Cheers > Maurizio > > [1] - > http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html > [2] - > http://mail.openjdk.java.net/pipermail/amber-dev/2017-March/000019.html > [3] - http://hg.openjdk.java.net/amber/ > [4] - > http://hg.openjdk.java.net/amber/amber10-old/langtools/file/940ff165a2c3/test/tools/javac/diags/examples/LocalNonDenotable.java > [5] - > http://mail.openjdk.java.net/pipermail/amber-spec-experts/2017-March/000015.html > [6] -http://hg.openjdk.java.net/jdk10/master/rev/48ec75306997 > > > >> >> So to cut a long story short: according to the new development model, >> shouldn't the complete JEP 286 be developed and tested in its own repo >> or branch and only integrated into jdk10 once it is "feature complete" >> ? >> >> Thanks, >> Volker >> >> [1] >> http://mail.openjdk.java.net/pipermail/jdk-dev/2017-October/000001.html >> [2] >> http://mail.openjdk.java.net/pipermail/discuss/2017-September/004281.html >> >> On Wed, Oct 11, 2017 at 5:57 PM, Joseph D. Darcy >> wrote: >>> >>> Hi Jon, >>> >>> Catching up post-JavaOne... >>> >>> On 9/29/2017 11:12 AM, Jonathan Gibbons wrote: >>> >>> Joe, >>> >>> I guess I would ask, who are these methods targeted at? >>> >>> Both isIdentifier and isKeyword are fuzzy at best. >>> >>> isIdentifier does not take the appropriate Unicode standard into account, >>> although it is probably "good enough". >>> >>> >>> Right; specifically it doesn't use the Unicode standard that was in force >>> at >>> the time of the earlier releases. Each major JDK platform release >>> generally >>> bumps the supported Unicode version and set of identifier characters >>> expands. To be 100% accurate the isIdentifier check on release (N - k) >>> for >>> some k > 0 would need the Unicode tables used on JDK (N - k). That >>> information is not available via the platform APIs. >>> >>> isKeyword has certainly become more complex in 9 and after, and anyone >>> who >>> really needs this info (e.g. IDEs) is probably already doing it for >>> themselves, properly. >>> >>> Do you have any reasonable use-cases for a fuzzy definition of isKeyword, >>> or >>> should we just deprecate it words the Big Bit Bucket in the sky? >>> >>> >>> My thought was for annotation processor authors to have some easy ways to >>> verify a name was valid to use on a given source version, etc. >>> >>> I agree tools like IDEs will need more precise implementations of such >>> checks, but I think there is still benefit in providing less formal >>> checking >>> too. >>> >>> -Joe >>> > From georgiy.rakov at oracle.com Thu Oct 12 17:53:56 2017 From: georgiy.rakov at oracle.com (Georgiy Rakov) Date: Thu, 12 Oct 2017 23:23:56 +0530 Subject: LVTI: as per spec upward projection couldn't have resulted in a '? extends' parameterization In-Reply-To: <845EA5E9-1BF1-45FF-96AB-68DCE9A1F990@oracle.com> References: <3f1b3dd9-77e0-2378-21bc-80ea82d47445@oracle.com> <845EA5E9-1BF1-45FF-96AB-68DCE9A1F990@oracle.com> Message-ID: <51917551-b55c-7839-efdd-15b017474b43@oracle.com> Thanks for quick response and clarifications. Now two more questions are presented below. 1) Let's consider the code from the original letter. class C0 {} ??? class C1 extends C0 {} ??? ??? class C2 extends C1 {} public class Shell { ??? void set(T t) {} ??? T get() {return null;} ??? public static void main(String args[]) { ??? ??? Shell y = new Shell(); ??? ??? var z = y; //upward projection is applied here ??? ??? z = new Shell(); //compilation succeeds ??? ??? z = new Shell(); //compilation succeeds ??? ??? z = new C0();??????? //obviously compilation error ??????? ... javac output following error message on line "z = new C0();": Shell.java:16: error: incompatible types: C0 cannot be converted to Shell ??????????????? z = new C0();??????? //obviously compilation error According to this error message javac assumes type of 'z' to be Shell. It seems that this is at least a cosmetic defect since type of 'z' is Shell as it's been clarified. Should a JBS issue be filed on javac for this reason? 2) The next question relates to further applying rules for calculation of upward projection of Shell presented in the original letter. As it's been clarified the assertion (1) from [1] presented below doesn't apply so we proceed to the the next assertion (2) from [1]: (1) If U is not Object, and if either the declared bound of the ith parameter of G, Bi, mentions a type parameter of G, or Bi is not a subtype of U, then Ai' is an upper-bounded wildcard, ? extends U. (2) Otherwise, if the downward projection of Ai is L, then Ai' is a lower-bounded wildcard, ? super L. (3) Otherwise, the downward projection of Ai is undefined and Ai' is an unbounded wildcard, ?. Which leads us to downward projection rules from [1]: The downward projection of a type T with respect to a set of restricted type variables is a partial function, defined as follows: (4) ?? If T does not mention any restricted type variable, then the result is T. (5) ?? If T is a restricted type variable, then if T has a lower bound, and if the downward projection of that bound is L, the result is L; if T has no lower bound, or if the downward projection of that bound is undefined, then the result is undefined. Here T is 'CAP extends C1 super NULL_TYPE' as per capture conversion and restricted type variable include just the same CAP. Rule (4) doesn't apply so according to rule (5): downward_projection(CAP) = downward_projection(NULL_TYPE) = NULL_TYPE, NULL_TYPE doesn't mention any restricted type variable so downward projection of NULL_TYPE is NULL_TYPE according to rule (4). Thus rule (2) results in ? super NULL_TYPE. Is this understand correctly that '? super NULL_TYPE' is effectively equal to '?' (simple wildcard) because both of these wildcrads define the same set of types since NULL_TYPE's super types are all reference types and any reference type extends Object directly or not? According to this reasoning it's rule (2) which makes upward_projection(Shell) to result in 'Shell'. Is this correct? If it is should spec be clarified on this because the reduction of '? super NULL_TYPE' to '?' is not explicitly specified by JLS and it might be not obvious that it's applied? Or should spec just specify that the downward projection of NULL_TYPE is undefined? In this case it would be rule (3) which would make upward_projection(Shell) to result in Shell. [1] http://cr.openjdk.java.net/~dlsmith/local-var-inference.html Thank you, Georgiy. On 12.10.2017 2:09, Dan Smith wrote: > Hey, thanks for careful testing of these rules. I'm sure they can use > some scrutiny! > >> On Oct 11, 2017, at 9:57 AM, Georgiy Rakov > > wrote: >> >> 4. Afterwards following assertion from [1] is touched: >> >> *If /U/ is not |Object|, and if either the declared bound of the >> ith parameter of /G/, /Bi/, mentions a type parameter of /G/, or >> /Bi/ is not a subtype of /U/, then /Ai'/ is an upper-bounded >> wildcard, /|? extends| U/.* >> ** >> >> Here we have just B1 which is C1, so: >> **a. "*/U/ is not |Object|*" is _true_ since U is C1; >> b. "*the declared bound of the ith parameter of /G/, /Bi/, mentions a >> type parameter of /G/*" is _false_ since B1 is C1 - no type >> parameters are mentioned; >> c. "*/Bi/ is not a subtype of /U/*" is _false_ because both B1 and U >> are C1 so B1 is a subtype of U since a class is always a subtype of >> itself. >> >> For this reason A1' cannot be defined by this assertion as ? extends >> C1 which would make upward projection to result in Shell> C1>, so none of other assertions can do either. > > You are right that this rule does not apply. > > What you are missing is that, per the subsequent rules, the type is > Shell > > Subsequently, all reads of 'z' have type > capture(Shell) = Shell where CAP extends C1 > > In other words, there is no need to mention C1 in the type, because it > is implicit from the declaration-site bound of T in Shell. > >> It's not quite clear why "*/Bi/ is not a subtype of /U/*" was added >> to the specification. Some examples clarifying this point would be >> highly appreciated. > > Ideally, we'd like an upper bound and a lower bound: > ? extends upward(Ai) super downward(Ai) > > However, wildcards aren't expressive enough to have both upper and > lower bounds, so we have to pick one. The heuristic is: if the upper > bound is "meaningful", use that. If the upper bound is not meaningful, > use the lower bound instead (or nothing, if there is no lower bound). > The definition of "meaningful" is, loosely, "something that may affect > the upper bound of the capture of the result". > > If Bi is a subtype of of U, then U will not affect the upper bound of > the capture of the result, because capture will just do a glb(Bi, U) = Bi. > > ?Dan -------------- next part -------------- An HTML attachment was scrubbed... URL: From vicente.romero at oracle.com Thu Oct 12 19:04:07 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 12 Oct 2017 15:04:07 -0400 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> Message-ID: <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> Hi, Sorry for the delay on coming into this. This is one of the most magical parts of the compiler, and I'm not referring to the algorithms but to the general problem. Which is the one I think we need to understand before trying to optimize the current implementation. Because it could be the case that the current implementation is not optimal, and we end up making a sub-optimal implementation to run faster. The general problem or situation here is that we start from a directed graph representing the dependencies between inference variables. From this graph a directed acyclic graph is obtained by joining strongly connected components into "meta" or "fat" nodes. This is the point where we start. Now I think that the problem we want to solve is: given a directed acyclic graph and a list of inference variables find the resolution "path" with minimal, or minimum if possible, number of instantiations. Such a path should be an ordered list containing one or more nodes. The first node must be a leaf. Given the nature of the instantiation process, once we instantiate a variable, all nodes containing that variable will be instantiated. A node with all of its variables instantiated, let's call it instantiated node, can be removed from the graph as it won't be adding any information. There is a cost associated to every node, and that cost could be the number of variables, still, to be instantiated in the node. I think that there are two main strategies here: * aggressive * conservative In an aggressive strategy I would expect that if cost(n1) == cost(n2) and n1 and n2 are leafs, then we don't have another criteria to propose a resolution order between n1 and n2, so we can pick any of them. Of course I'm also assuming that n1 and n2 contain at least one of the variables we want to solve. This means that a solution to the aggressive strategy could be: 1. Add all leaves, having at least one of the variables we want to solve, to a priority queue, ordered by cost. I wonder if there could be a case for which no leaf has the variables we want to solve. I guess that in that case we would add all the leaves to the queue ordered by cost. 2. While there are elements in the queue 3. Get the first node, solve the contained variables and remove it from the graph along with all instantiated nodes. Check what other nodes in the graph are now leaves and add them to the queue following the same criteria. The aggressive strategy should be close to the minimum instantiations with the benefit that finding the instantiation path is rather simple and I think that would give the right order and result in most / all cases. Now let's take a look at the conservative strategy, we want the absolute minimum instantiations. So we have a graph, we have cost and we want to optimize. This seems to me a variation of a classical max flow problem. The cost is in the vertex instead of in the edges, we want to minimize instead of maximize, but doing a couple of adaptations here and there we can get to the classical problem. First we can update the cost to be Integer.MAX_VALUE - cost, or any other value greater or equal to the number of variables. We need to add a source and a sink node, implementation could do this implicitly. And add an edge from the source to every non-leaf node with at least one of the variables we want to solve. There will be no cost associated to this edge. In addition we will add an edge from every leaf node to the sink. If we want to represent the cost in the edges then the cost of every edge from a leaf to the sink will be the cost of the corresponding leaf. The path with minimum instantiations will be the solution to the max flow problem. I assume that if there is no non-leaf node that contains all the variables we want to solve, then we will have to instantiate the nodes following the path, starting from the leaf. The we can remove from the graph instantiated nodes and once we have consumed the last node in the path if there are still variables to be solved, we can apply the max flow algorithm again, this time with far less nodes and do this till there are no more variables to be solved. This is my interpretation of this problem and how I think we should discuss if this interpretation is correct, or if there is a better one, before considering optimizing the current implementation which doesn't fit very well into any of these descriptions strategies. Comments? Vicente On 10/09/2017 02:00 PM, B. Blaser wrote: > Hi, > > On 5 October 2017 at 20:26, B. Blaser wrote: >> On 5 October 2017 at 16:28, Vicente Romero wrote: >>> >>> On 10/05/2017 04:32 AM, Maurizio Cimadamore wrote: >>>> Please, send me a patch with all your fixed, including the new version of >>>> (3) and I'll take a look/run some tests. >>> >>> +1 yes please share the last full version >> Here it is, in attachment. >> >> Note that there's another possibility for pt (2), using "return >> noPath" instead of "throw", but I think this would probably be slower. >> >> I did only some quick tests with this last full version, so please let >> me know if you encounter any problem with it. >> >> I think the example I gave previously is really faster with (1) and >> (3); we pick immediately, in O(1), 'X' then 'Y' and finally 'Z'. > Here are two more examples showing the benefits of pt (2), this time. > The first one uses 'T' via the actual arguments of 'n()' to build > nodes with multiple ivars and the second one uses 'List' to build > dependent nodes of single ivar. > > When inferring the type of the lambda parameters in the example below, > we first try the non-optimal node [T, B] of size 2. Then we try node > [C] of size 1 but depending on [T, A] and [T, B]. When examining the > first dependency [T, A] we can immediately conclude that this > possibility is worse than the best known so far, discarding it with > the first 'throw' and without evaluating the second dependency [T, B]: > > import java.util.Map; > import java.util.List; > import java.util.function.BiConsumer; > > public class H { > T m(T t) { return t; } > > > void n(BiConsumer f, A a, B b, C c) {} > > void o() { > n( (x, y) -> {}, m(""), m(""), null); > } > } > > This next example shows another benefit of pt (2) when inferring the > type of the lambda parameters. We first examine node [B] which depends > on [T] having then a full cost of 2. Then, we start evaluating [C] > which depends on [A] + [T] and [B] + [T]. When computing the full cost > of [A], we can immediately discard this possibility (via the second > 'throw'), the latter being worse than the best known so far: > > public class H { > List m(T t) { return null; } > > > void n(BiConsumer f, A a, B b, C c) {} > > void o() { > n( (x, y) -> {}, m(""), m(""), null); > } > } > > Cheers, > Bernard > > >> Please let me know about the test results. >> >> Cheers, >> Bernard >> >>>> Cheers >>>> Maurizio >>> >>> Vicente -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Thu Oct 12 19:56:56 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 12 Oct 2017 20:56:56 +0100 Subject: LVTI: as per spec upward projection couldn't have resulted in a '? extends' parameterization In-Reply-To: <51917551-b55c-7839-efdd-15b017474b43@oracle.com> References: <3f1b3dd9-77e0-2378-21bc-80ea82d47445@oracle.com> <845EA5E9-1BF1-45FF-96AB-68DCE9A1F990@oracle.com> <51917551-b55c-7839-efdd-15b017474b43@oracle.com> Message-ID: On 12/10/17 18:53, Georgiy Rakov wrote: > According to this error message javac assumes type of 'z' to be > Shell. It seems that this is at least a cosmetic defect > since type of 'z' is Shell as it's been clarified. > Should a JBS issue be filed on javac for this reason? Hi, based on Dan's explanation this would seem as a cosmetic issue indeed. The compiler impl is based off an earlier version of this spec which did not include this rule. That said, I can't? think of a case in which the difference will be visible. As Dan said, Shell will be captured and the capture variable it leads to will be the same, so membership-wise no difference can be observed. Dan, can you think of cases in which some weird difference would pop up? Maurizio From maurizio.cimadamore at oracle.com Thu Oct 12 20:16:52 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 12 Oct 2017 21:16:52 +0100 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> Message-ID: <9b392574-0f51-be26-ceeb-1fa82a9e7dcc@oracle.com> On 12/10/17 20:04, Vicente Romero wrote: > This is my interpretation of this problem and how I think we should > discuss if this interpretation is correct, or if there is a better > one, before considering optimizing the current implementation which > doesn't fit very well into any of these descriptions strategies. I think your interpretation of the problem is correct. This is the dual of the max flow problem, with some variations (as you note). I'm not sure about the aggressive strategy you propose; it seems like it could get fooled quite easily if a flow with an high overall cost is 'hidden' behind a leaf with an initial very low cost. As per your point (2), yes it will typically be the case that the var to instantiate is not a leaf, which is why we try to come up with the best set of variables to instantiate eagerly - knowing that each (redundant) eager instantiation could potentially lead to spurious error messages. That said, this part is outside the spec - as section 18.5.2.2 says this: "1 A subset of constraints is selected in C, satisfying the property that, for each constraint, no input variable can influence an output variable of another constraint in C. The terms /input variable/ and /output variable/ are defined below. An inference variable ? /can influence/ an inference variable ? if ? depends on the resolution of ? (?18.4 ), or vice versa; or if there exists a third inference variable ? such that ? can influence ? and ? can influence ?. 2 The selected constraint(s) are removed from C. 3 The input variables ?1, ..., ?m of all the selected constraint(s) are resolved."" Here javac is playing some tricks that are totally outside of the spec - note that the spec requires that all input inference variables in the node to be unstuck should be solved at once - but that's not what javac does - as javac calls solveAny to do the heuristic trick: http://hg.openjdk.java.net/jdk10/master/file/tip/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java#l635 I think that, instead of investing resources on making these tricks more optimal, we should probably try to bring the compiler closer to what the spec has to say in this matter (or at least try and see what breaks, if anything). Cheers Maurizio -------------- next part -------------- An HTML attachment was scrubbed... URL: From vicente.romero at oracle.com Thu Oct 12 21:27:02 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 12 Oct 2017 17:27:02 -0400 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: <9b392574-0f51-be26-ceeb-1fa82a9e7dcc@oracle.com> References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> <9b392574-0f51-be26-ceeb-1fa82a9e7dcc@oracle.com> Message-ID: <09308a0b-4d1a-608e-7477-fc5bf142492b@oracle.com> On 10/12/2017 04:16 PM, Maurizio Cimadamore wrote: > > > > On 12/10/17 20:04, Vicente Romero wrote: >> This is my interpretation of this problem and how I think we should >> discuss if this interpretation is correct, or if there is a better >> one, before considering optimizing the current implementation which >> doesn't fit very well into any of these descriptions strategies. > I think your interpretation of the problem is correct. This is the > dual of the max flow problem, with some variations (as you note). I'm > not sure about the aggressive strategy you propose; it seems like it > could get fooled quite easily if a flow with an high overall cost is > 'hidden' behind a leaf with an initial very low cost. As per your > point (2), yes it will typically be the case that the var to > instantiate is not a leaf, which is why we try to come up with the > best set of variables to instantiate eagerly - knowing that each > (redundant) eager instantiation could potentially lead to spurious > error messages. > > That said, this part is outside the spec - as section 18.5.2.2 says this: > > "1 A subset of constraints is selected in C, satisfying the property > that, for each constraint, no input variable can influence an output > variable of another constraint in C. The terms /input variable/ and > /output variable/ are defined below. An inference variable ? /can > influence/ an inference variable ? if ? depends on the resolution of ? > (?18.4 > ), > or vice versa; or if there exists a third inference variable ? such > that ? can influence ? and ? can influence ?. > > 2 The selected constraint(s) are removed from C. > > 3 The input variables ?1, ..., ?m of all the selected constraint(s) > are resolved."" > > Here javac is playing some tricks that are totally outside of the spec > - note that the spec requires that all input inference variables in > the node to be unstuck should be solved at once - but that's not what > javac does - as javac calls solveAny to do the heuristic trick: > > http://hg.openjdk.java.net/jdk10/master/file/tip/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java#l635 > > I think that, instead of investing resources on making these tricks > more optimal, we should probably try to bring the compiler closer to > what the spec has to say in this matter (or at least try and see what > breaks, if anything). Or this is probably one of those cases in which the spec should mimic what javac is doing > > Cheers > Maurizio > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From daniel.smith at oracle.com Thu Oct 12 22:31:55 2017 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 12 Oct 2017 16:31:55 -0600 Subject: LVTI: as per spec upward projection couldn't have resulted in a '? extends' parameterization In-Reply-To: References: <3f1b3dd9-77e0-2378-21bc-80ea82d47445@oracle.com> <845EA5E9-1BF1-45FF-96AB-68DCE9A1F990@oracle.com> <51917551-b55c-7839-efdd-15b017474b43@oracle.com> Message-ID: <546D60F2-3BF8-4F8A-B14D-BF93AB36B221@oracle.com> > On Oct 12, 2017, at 1:56 PM, Maurizio Cimadamore wrote: > > > > On 12/10/17 18:53, Georgiy Rakov wrote: >> According to this error message javac assumes type of 'z' to be Shell. It seems that this is at least a cosmetic defect since type of 'z' is Shell as it's been clarified. >> Should a JBS issue be filed on javac for this reason? > Hi, > based on Dan's explanation this would seem as a cosmetic issue indeed. The compiler impl is based off an earlier version of this spec which did not include this rule. That said, I can't think of a case in which the difference will be visible. As Dan said, Shell will be captured and the capture variable it leads to will be the same, so membership-wise no difference can be observed. > > Dan, can you think of cases in which some weird difference would pop up? > > Maurizio I was thinking this may just be an artifact of the weird way javac represents wildcards and their implicit bounds. You may get different results from subtyping depending on whether Shell or Shell appears in a type, but it's hard to be sure due to anomalies in how wildcards and capture vars and specified and implemented. Any difference you observe is probably a bug, under the type system cleanup umbrella. And it may be impossible to exploit any difference between the two types, because upward projection will not place the type in an "invariant" position, and type equivalence testing is typically where you'd see a difference. ?Dan From daniel.smith at oracle.com Thu Oct 12 22:41:11 2017 From: daniel.smith at oracle.com (Dan Smith) Date: Thu, 12 Oct 2017 16:41:11 -0600 Subject: LVTI: as per spec upward projection couldn't have resulted in a '? extends' parameterization In-Reply-To: <51917551-b55c-7839-efdd-15b017474b43@oracle.com> References: <3f1b3dd9-77e0-2378-21bc-80ea82d47445@oracle.com> <845EA5E9-1BF1-45FF-96AB-68DCE9A1F990@oracle.com> <51917551-b55c-7839-efdd-15b017474b43@oracle.com> Message-ID: <444CE28E-417A-4C44-8C5E-C38F3B273632@oracle.com> > On Oct 12, 2017, at 11:53 AM, Georgiy Rakov wrote: > > Here T is 'CAP extends C1 super NULL_TYPE' as per capture conversion and restricted type variable include just the same CAP. > > Rule (4) doesn't apply so according to rule (5): downward_projection(CAP) = downward_projection(NULL_TYPE) = NULL_TYPE, NULL_TYPE doesn't mention any restricted type variable so downward projection of NULL_TYPE is NULL_TYPE according to rule (4). Yep, this is a problem. The rules were designed based on a model in which capture variables don't use the null type as their lower bound, but just don't have lower bounds when not needed (like all other type variables). But, yes, it seems that the longstanding behavior of JLS is to claim the null type is a lower bound (per 5.1.10). I'll fix the downward projection rules. The intent is that the downward projection of CAP is undefined. ?Dan From jarthana at in.ibm.com Fri Oct 13 06:11:08 2017 From: jarthana at in.ibm.com (Jayaprakash Arthanareeswaran) Date: Fri, 13 Oct 2017 06:11:08 +0000 Subject: Module loses its package after compilation when the package has nothing but a compilation unit with package declaration. Message-ID: An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Fri Oct 13 09:08:15 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 13 Oct 2017 10:08:15 +0100 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: <09308a0b-4d1a-608e-7477-fc5bf142492b@oracle.com> References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> <9b392574-0f51-be26-ceeb-1fa82a9e7dcc@oracle.com> <09308a0b-4d1a-608e-7477-fc5bf142492b@oracle.com> Message-ID: On 12/10/17 22:27, Vicente Romero wrote: > > > On 10/12/2017 04:16 PM, Maurizio Cimadamore wrote: >> >> >> >> On 12/10/17 20:04, Vicente Romero wrote: >>> This is my interpretation of this problem and how I think we should >>> discuss if this interpretation is correct, or if there is a better >>> one, before considering optimizing the current implementation which >>> doesn't fit very well into any of these descriptions strategies. >> I think your interpretation of the problem is correct. This is the >> dual of the max flow problem, with some variations (as you note). I'm >> not sure about the aggressive strategy you propose; it seems like it >> could get fooled quite easily if a flow with an high overall cost is >> 'hidden' behind a leaf with an initial very low cost. As per your >> point (2), yes it will typically be the case that the var to >> instantiate is not a leaf, which is why we try to come up with the >> best set of variables to instantiate eagerly - knowing that each >> (redundant) eager instantiation could potentially lead to spurious >> error messages. >> >> That said, this part is outside the spec - as section 18.5.2.2 says this: >> >> "1 A subset of constraints is selected in C, satisfying the property >> that, for each constraint, no input variable can influence an output >> variable of another constraint in C. The terms /input variable/ and >> /output variable/ are defined below. An inference variable ? /can >> influence/ an inference variable ? if ? depends on the resolution of >> ? (?18.4 >> ), >> or vice versa; or if there exists a third inference variable ? such >> that ? can influence ? and ? can influence ?. >> >> 2 The selected constraint(s) are removed from C. >> >> 3 The input variables ?1, ..., ?m of all the selected constraint(s) >> are resolved."" >> >> Here javac is playing some tricks that are totally outside of the >> spec - note that the spec requires that all input inference variables >> in the node to be unstuck should be solved at once - but that's not >> what javac does - as javac calls solveAny to do the heuristic trick: >> >> http://hg.openjdk.java.net/jdk10/master/file/tip/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java#l635 >> >> I think that, instead of investing resources on making these tricks >> more optimal, we should probably try to bring the compiler closer to >> what the spec has to say in this matter (or at least try and see what >> breaks, if anything). > > Or this is probably one of those cases in which the spec should mimic > what javac is doing I was thinking more about it, and? yes, there can be cases where the spec is overly eager; consider a couple of constraints like C1 and C2: vars(C1) = I1, O1 input(C1) = I1 output(C1) = O1 vars(C2) = I2, O2 input(C2) = I2 output(C2) = O2 T can influence I1 U can influence I1 V can influence U In this case, it's fine to pick C1 as the first constraint to solve - as its input variables (I1) do not influence any output var (O1, O2) of any other constraints. So, now we have to solve all input vars of C2 - namely I1. Which means, now we have to turn at the 'can-influence' relationship, and ask 'what are the variables I need to solve in order to get at I1' ? I believe this question has only one answer that is 'minimal'. In other words, there should be only a minimal subset of the graph that goes from one or more leaves and lead to I1. In the example above, such subset is { T, U, V, I1 }. Of course there are more non-minimal choices: { T, U, V, I1, O1 } { T, U, V, I1, O2 } { T, U, V, I1, O1, O2 } But I think there's only _one_ minimal answer. So, the way I see the javac implementation, is that the BestLeafSolver is a big workaround to the fact that we need to be able to solve a 'subset' of the inference graph. But this can be achieved in many different ways - and the approach implemented right now (which predates the spec text) is probably more general than it needs to. I think a very simple BestLeafSolver would simply 'skip' all the inference graph nodes which cannot influence any of the nodes containing at least one variable in the target set, and will keep going until all variables in such set are solved. I don' think such an algorithm would require any tracking of cost, paths and such. Maurizio > >> >> Cheers >> Maurizio >> >> >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsrbnd at gmail.com Fri Oct 13 11:50:14 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Fri, 13 Oct 2017 13:50:14 +0200 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> <9b392574-0f51-be26-ceeb-1fa82a9e7dcc@oracle.com> <09308a0b-4d1a-608e-7477-fc5bf142492b@oracle.com> Message-ID: Hi, On 13 October 2017 at 11:08, Maurizio Cimadamore wrote: > > But I think there's only _one_ minimal answer. So, the way I see the javac > implementation, is that the BestLeafSolver is a big workaround to the fact > that we need to be able to solve a 'subset' of the inference graph. But this > can be achieved in many different ways - and the approach implemented right > now (which predates the spec text) is probably more general than it needs > to. > > I think a very simple BestLeafSolver would simply 'skip' all the inference > graph nodes which cannot influence any of the nodes containing at least one > variable in the target set, and will keep going until all variables in such > set are solved. I don' think such an algorithm would require any tracking of > cost, paths and such. I think you're right, I wasn't sure enough to drastically simplify the best leaf solver this way. We only need to pick the trees related to the variables that need to be solved (pt (3) I suggested) and solve them leaf after leaf... the order in which leaves are solved being irrelevant. What do you think? Bernard > Maurizio > > > > Cheers > Maurizio From jan.lahoda at oracle.com Fri Oct 13 11:58:36 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Fri, 13 Oct 2017 13:58:36 +0200 Subject: RFR: JDK-8188035: JavaFileManager.listLocationsForModules does not always reflect values set through tandardJavaFileManager.setLocationForModule. Message-ID: <59E0AA6C.6000100@oracle.com> Hi, When StandardJavaFileManager.setLocationForModule is used, and then JavaFileManager.listLocationsForModules is used, then, for some locations, the listed locations won't include the changes through setLocationForModule. The proposal here is to prepend the paths/locations from setLocationForModule invocations to the output of listLocationsForModules. Bug: https://bugs.openjdk.java.net/browse/JDK-8188035 Webrev: http://cr.openjdk.java.net/~jlahoda/8188035/webrev.00/ Jan From jan.lahoda at oracle.com Fri Oct 13 12:30:22 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Fri, 13 Oct 2017 14:30:22 +0200 Subject: RFR: JDK-8180744: Update ct.sym for JDK 10 Message-ID: <59E0B1DE.3000701@oracle.com> Hi, The patch here adds a support for --release 9 to OpenJDK. This includes adding a snapshot of the JDK 9 APIs. Notes: -several changes to the historical data in make/data/symbols: --java.management.rmi-8.sym.txt contains a few classes that were originally in java.management-8.sym.txt (this change is adjusting the structure to adhere more to the final JDK 9 module layout) --java.annotations.common-* renamed to java.xml.ws.annotation-* to adhere to the final layout --diffing of classes across releases has been improved to avoid some unnecessary class header notices in the historical data --empty files are now not written for the historical data -the (JDK)PlatformProvider.PlatformDescription(Impl) now returns a file manager, instead of a list of paths. This makes the contract cleaner, and allow to handle the ".sig" extension mostly in the file manager instead of ClassFinder. (Due to this change, JDK-8139607: '-release option forces StandardJavaFileManager' is also resolved by this patch, although it is not the primary goal of this patch.) Bug: https://bugs.openjdk.java.net/browse/JDK-8180744 Webrev: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/ I'll send to build-dev as well after the javac changes will look OK. Any feedback is welcome. Thanks, Jan From vicente.romero at oracle.com Fri Oct 13 12:31:06 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Fri, 13 Oct 2017 08:31:06 -0400 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> <9b392574-0f51-be26-ceeb-1fa82a9e7dcc@oracle.com> <09308a0b-4d1a-608e-7477-fc5bf142492b@oracle.com> Message-ID: On 10/13/2017 05:08 AM, Maurizio Cimadamore wrote: > > > > On 12/10/17 22:27, Vicente Romero wrote: >> >> >> On 10/12/2017 04:16 PM, Maurizio Cimadamore wrote: >>> >>> >>> >>> On 12/10/17 20:04, Vicente Romero wrote: >>>> This is my interpretation of this problem and how I think we should >>>> discuss if this interpretation is correct, or if there is a better >>>> one, before considering optimizing the current implementation which >>>> doesn't fit very well into any of these descriptions strategies. >>> I think your interpretation of the problem is correct. This is the >>> dual of the max flow problem, with some variations (as you note). >>> I'm not sure about the aggressive strategy you propose; it seems >>> like it could get fooled quite easily if a flow with an high overall >>> cost is 'hidden' behind a leaf with an initial very low cost. As per >>> your point (2), yes it will typically be the case that the var to >>> instantiate is not a leaf, which is why we try to come up with the >>> best set of variables to instantiate eagerly - knowing that each >>> (redundant) eager instantiation could potentially lead to spurious >>> error messages. >>> >>> That said, this part is outside the spec - as section 18.5.2.2 says >>> this: >>> >>> "1 A subset of constraints is selected in C, satisfying the property >>> that, for each constraint, no input variable can influence an output >>> variable of another constraint in C. The terms /input variable/ and >>> /output variable/ are defined below. An inference variable ? /can >>> influence/ an inference variable ? if ? depends on the resolution of >>> ? (?18.4 >>> ), >>> or vice versa; or if there exists a third inference variable ? such >>> that ? can influence ? and ? can influence ?. >>> >>> 2 The selected constraint(s) are removed from C. >>> >>> 3 The input variables ?1, ..., ?m of all the selected constraint(s) >>> are resolved."" >>> >>> Here javac is playing some tricks that are totally outside of the >>> spec - note that the spec requires that all input inference >>> variables in the node to be unstuck should be solved at once - but >>> that's not what javac does - as javac calls solveAny to do the >>> heuristic trick: >>> >>> http://hg.openjdk.java.net/jdk10/master/file/tip/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java#l635 >>> >>> I think that, instead of investing resources on making these tricks >>> more optimal, we should probably try to bring the compiler closer to >>> what the spec has to say in this matter (or at least try and see >>> what breaks, if anything). >> >> Or this is probably one of those cases in which the spec should mimic >> what javac is doing > I was thinking more about it, and? yes, there can be cases where the > spec is overly eager; consider a couple of constraints like C1 and C2: > > > vars(C1) = I1, O1 > input(C1) = I1 > output(C1) = O1 > > vars(C2) = I2, O2 > input(C2) = I2 > output(C2) = O2 > > T can influence I1 > U can influence I1 > V can influence U > > > In this case, it's fine to pick C1 as the first constraint to solve - > as its input variables (I1) do not influence any output var (O1, O2) > of any other constraints. > > So, now we have to solve all input vars of C2 - namely I1. Which > means, now we have to turn at the 'can-influence' relationship, and > ask 'what are the variables I need to solve in order to get at I1' ? I > believe this question has only one answer that is 'minimal'. In other > words, there should be only a minimal subset of the graph that goes > from one or more leaves and lead to I1. In the example above, such > subset is { T, U, V, I1 }. > > Of course there are more non-minimal choices: > > { T, U, V, I1, O1 } > { T, U, V, I1, O2 } > { T, U, V, I1, O1, O2 } > > But I think there's only _one_ minimal answer. So, the way I see the > javac implementation, is that the BestLeafSolver is a big workaround > to the fact that we need to be able to solve a 'subset' of the > inference graph. But this can be achieved in many different ways - and > the approach implemented right now (which predates the spec text) is > probably more general than it needs to. > > I think a very simple BestLeafSolver would simply 'skip' all the > inference graph nodes which cannot influence any of the nodes > containing at least one variable in the target set, and will keep > going until all variables in such set are solved. I don' think such an > algorithm would require any tracking of cost, paths and such. well I think that there are two parts here, one is finding that minimal set that could be done using a simple flood fill algorithm in the graph, just connectivity matters. But then once we have the subset, we have to find a resolution order right? After the application of the Tarjan algo for strongly connected components, the graph is already topologically sorted. The subset found in step 1 will also be sorted we can follow that order. > > Maurizio Vicente >> >>> >>> Cheers >>> Maurizio >>> >>> >>> >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From martinrb at google.com Fri Oct 13 16:49:45 2017 From: martinrb at google.com (Martin Buchholz) Date: Fri, 13 Oct 2017 09:49:45 -0700 Subject: RFR: JDK-8180744: Update ct.sym for JDK 10 In-Reply-To: <59E0B1DE.3000701@oracle.com> References: <59E0B1DE.3000701@oracle.com> Message-ID: (drive-by comments) It's great that generated files are marked as such, but: - It's not obvious HOW these files are generated. Actually having the generation command write its own invocation into the generated files might be helpful. - do generated files need a legal notice? +# ########################################################## +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### +# ########################################################## The order of releases is surprising: +generate platforms 8:7:6:9 On Fri, Oct 13, 2017 at 5:30 AM, Jan Lahoda wrote: > Hi, > > The patch here adds a support for --release 9 to OpenJDK. This includes > adding a snapshot of the JDK 9 APIs. > > Notes: > -several changes to the historical data in make/data/symbols: > --java.management.rmi-8.sym.txt contains a few classes that were > originally in java.management-8.sym.txt (this change is adjusting the > structure to adhere more to the final JDK 9 module layout) > --java.annotations.common-* renamed to java.xml.ws.annotation-* to adhere > to the final layout > --diffing of classes across releases has been improved to avoid some > unnecessary class header notices in the historical data > --empty files are now not written for the historical data > -the (JDK)PlatformProvider.PlatformDescription(Impl) now returns a file > manager, instead of a list of paths. This makes the contract cleaner, and > allow to handle the ".sig" extension mostly in the file manager instead of > ClassFinder. (Due to this change, JDK-8139607: '-release option forces > StandardJavaFileManager' is also resolved by this patch, although it is not > the primary goal of this patch.) > > Bug: https://bugs.openjdk.java.net/browse/JDK-8180744 > Webrev: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/ > > I'll send to build-dev as well after the javac changes will look OK. > > Any feedback is welcome. > > Thanks, > Jan > -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Fri Oct 13 16:51:28 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 13 Oct 2017 17:51:28 +0100 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> <9b392574-0f51-be26-ceeb-1fa82a9e7dcc@oracle.com> <09308a0b-4d1a-608e-7477-fc5bf142492b@oracle.com> Message-ID: <536e8914-b2a0-82db-8528-b7146c7a0b7d@oracle.com> On 13/10/17 13:31, Vicente Romero wrote: > > > On 10/13/2017 05:08 AM, Maurizio Cimadamore wrote: >> >> >> >> On 12/10/17 22:27, Vicente Romero wrote: >>> >>> >>> On 10/12/2017 04:16 PM, Maurizio Cimadamore wrote: >>>> >>>> >>>> >>>> On 12/10/17 20:04, Vicente Romero wrote: >>>>> This is my interpretation of this problem and how I think we >>>>> should discuss if this interpretation is correct, or if there is a >>>>> better one, before considering optimizing the current >>>>> implementation which doesn't fit very well into any of these >>>>> descriptions strategies. >>>> I think your interpretation of the problem is correct. This is the >>>> dual of the max flow problem, with some variations (as you note). >>>> I'm not sure about the aggressive strategy you propose; it seems >>>> like it could get fooled quite easily if a flow with an high >>>> overall cost is 'hidden' behind a leaf with an initial very low >>>> cost. As per your point (2), yes it will typically be the case that >>>> the var to instantiate is not a leaf, which is why we try to come >>>> up with the best set of variables to instantiate eagerly - knowing >>>> that each (redundant) eager instantiation could potentially lead to >>>> spurious error messages. >>>> >>>> That said, this part is outside the spec - as section 18.5.2.2 says >>>> this: >>>> >>>> "1 A subset of constraints is selected in C, satisfying the >>>> property that, for each constraint, no input variable can influence >>>> an output variable of another constraint in C. The terms /input >>>> variable/ and /output variable/ are defined below. An inference >>>> variable ? /can influence/ an inference variable ? if ? depends on >>>> the resolution of ? (?18.4 >>>> ), >>>> or vice versa; or if there exists a third inference variable ? such >>>> that ? can influence ? and ? can influence ?. >>>> >>>> 2 The selected constraint(s) are removed from C. >>>> >>>> 3 The input variables ?1, ..., ?m of all the selected constraint(s) >>>> are resolved."" >>>> >>>> Here javac is playing some tricks that are totally outside of the >>>> spec - note that the spec requires that all input inference >>>> variables in the node to be unstuck should be solved at once - but >>>> that's not what javac does - as javac calls solveAny to do the >>>> heuristic trick: >>>> >>>> http://hg.openjdk.java.net/jdk10/master/file/tip/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java#l635 >>>> >>>> I think that, instead of investing resources on making these tricks >>>> more optimal, we should probably try to bring the compiler closer >>>> to what the spec has to say in this matter (or at least try and see >>>> what breaks, if anything). >>> >>> Or this is probably one of those cases in which the spec should >>> mimic what javac is doing >> I was thinking more about it, and? yes, there can be cases where the >> spec is overly eager; consider a couple of constraints like C1 and C2: >> >> >> vars(C1) = I1, O1 >> input(C1) = I1 >> output(C1) = O1 >> >> vars(C2) = I2, O2 >> input(C2) = I2 >> output(C2) = O2 >> >> T can influence I1 >> U can influence I1 >> V can influence U >> >> >> In this case, it's fine to pick C1 as the first constraint to solve - >> as its input variables (I1) do not influence any output var (O1, O2) >> of any other constraints. >> >> So, now we have to solve all input vars of C2 - namely I1. Which >> means, now we have to turn at the 'can-influence' relationship, and >> ask 'what are the variables I need to solve in order to get at I1' ? >> I believe this question has only one answer that is 'minimal'. In >> other words, there should be only a minimal subset of the graph that >> goes from one or more leaves and lead to I1. In the example above, >> such subset is { T, U, V, I1 }. >> >> Of course there are more non-minimal choices: >> >> { T, U, V, I1, O1 } >> { T, U, V, I1, O2 } >> { T, U, V, I1, O1, O2 } >> >> But I think there's only _one_ minimal answer. So, the way I see the >> javac implementation, is that the BestLeafSolver is a big workaround >> to the fact that we need to be able to solve a 'subset' of the >> inference graph. But this can be achieved in many different ways - >> and the approach implemented right now (which predates the spec text) >> is probably more general than it needs to. >> >> I think a very simple BestLeafSolver would simply 'skip' all the >> inference graph nodes which cannot influence any of the nodes >> containing at least one variable in the target set, and will keep >> going until all variables in such set are solved. I don' think such >> an algorithm would require any tracking of cost, paths and such. > > well I think that there are two parts here, one is finding that > minimal set that could be done using a simple flood fill algorithm in > the graph, just connectivity matters. But then once we have the > subset, we have to find a resolution order right? After the > application of the Tarjan algo for strongly connected components, the > graph is already topologically sorted. The subset found in step 1 will > also be sorted we can follow that order. Well, yes - basically we need to run Tarjan on a smaller graph. Maurizio > >> >> Maurizio > > Vicente > >>> >>>> >>>> Cheers >>>> Maurizio >>>> >>>> >>>> >>>> >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsrbnd at gmail.com Fri Oct 13 16:59:06 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Fri, 13 Oct 2017 18:59:06 +0200 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> <9b392574-0f51-be26-ceeb-1fa82a9e7dcc@oracle.com> <09308a0b-4d1a-608e-7477-fc5bf142492b@oracle.com> Message-ID: On 13 October 2017 at 14:31, Vicente Romero wrote: > > >> On 10/13/2017 05:08 AM, Maurizio Cimadamore wrote: >> >> >> But I think there's only _one_ minimal answer. So, the way I see the javac >> implementation, is that the BestLeafSolver is a big workaround to the fact >> that we need to be able to solve a 'subset' of the inference graph. But this >> can be achieved in many different ways - and the approach implemented right >> now (which predates the spec text) is probably more general than it needs >> to. >> >> I think a very simple BestLeafSolver would simply 'skip' all the inference >> graph nodes which cannot influence any of the nodes containing at least one >> variable in the target set, and will keep going until all variables in such >> set are solved. I don' think such an algorithm would require any tracking of >> cost, paths and such. >> >> > well I think that there are two parts here, one is finding that minimal set > that could be done using a simple flood fill algorithm in the graph, just > connectivity matters. This seems not to be needed as all the subtrees matching the variables in the list will have to be solved. We can simply peek the first one. > But then once we have the subset, we have to find a > resolution order right? After the application of the Tarjan algo for > strongly connected components, the graph is already topologically sorted. > The subset found in step 1 will also be sorted we can follow that order. Once we have selected a subtree matching one of the variables in the list (pt 3), we can simply solve all the subtree leaf by leaf. As leaves aren't inter-dependent, the order we solve them doesn't matter I think. Please take a look at the suggested implementation in attachment. It seems to give quite good results. What do you think? Bernard >> Maurizio > > > Vicente -------------- next part -------------- A non-text attachment was scrubbed... Name: InferenceGraph_lazy.patch Type: text/x-patch Size: 8959 bytes Desc: not available URL: From alex.buckley at oracle.com Fri Oct 13 18:36:04 2017 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 13 Oct 2017 11:36:04 -0700 Subject: Module loses its package after compilation when the package has nothing but a compilation unit with package declaration. In-Reply-To: References: Message-ID: <59E10794.7020500@oracle.com> On 10/12/2017 11:11 PM, Jayaprakash Arthanareeswaran wrote: > Let's say module A has a package x.y.z which has X.java which has the > following: > package x.y.z; > Now module B requires module A. Module "B" also has A.java, which > imports "x.y.z.*". > Compiling both A and B goes well. But things don't go well when I first > compiler A and > then B by having A in its module-path. I see the following: > error: package x.y.z does not exist I assume module A exports package x.y.z. I also assume you're compiling A/module-info.java in the same invocation as X.java, or with X.java on the source path, so that the compiler knows of the package declaration and thus accepts the 'exports' directive which specifies the package. Further assuming that you're working with an exploded directory tree, I'm not surprised by the error about x.y.z not existing. I would have expected an annotation processor running over the same exploded directory tree to not include x.y.z in A's getEnclosedElements(). Alex > As you can clearly see, compilation is not consistent between the two > modes. Also, > APT considering a non-existing package doesn't make sense either. > At the very least, the APT models should ignore the packages that don't > exist anymore. > Regards, > Jay From joe.darcy at oracle.com Fri Oct 13 19:10:07 2017 From: joe.darcy at oracle.com (joe darcy) Date: Fri, 13 Oct 2017 12:10:07 -0700 Subject: Module loses its package after compilation when the package has nothing but a compilation unit with package declaration. In-Reply-To: References: Message-ID: <923be978-d487-9e07-eb7e-42a0f5be28bf@oracle.com> Hello Jayaprakash, Code review requests on this list concerning API changes to javax.lang.model as well as an explicit request in April 2017 for feedback on the complete set of API changes [1] associated with the maintenance review (MR) of JSR 269 didn't receive a response from those working on an independent implementation of the API before the MR concluded in May 2017 [2]. This lack of response held even after I explicitly invited feedback from an Eclipse jdt committer who was a fellow speaker at Devoxx US in March 2017. If the goal is a more explicit specification, in my experience it would be more effective to send feedback requesting clarifications sometime before a release goes GA rather than literally the day after GA. [3] To use language precisely, the apt tool and associated API shipped in JDK 5.0, were deprecated in JDK 7, and were removed from the platform in JDK 8. The com.sun.* apt API never was never updated in any way to support modules and is completely irrelevant to this discussion about the javax.lang.model.* API and standardized annotation processing, which has been part of javac since JDK 6, which shipped in 2006. Cheers, -Joe [1] http://mail.openjdk.java.net/pipermail/compiler-dev/2017-April/010896.html [2] https://jcp.org/en/jsr/results?id=5942 [3] http://mail.openjdk.java.net/pipermail/jigsaw-dev/2017-September/013220.html On 10/12/2017 11:11 PM, Jayaprakash Arthanareeswaran wrote: > Hello experts, > This question was originally raised via [1], admittedly late, but > didn't receive any > response.I am re-posting it as advised by Alan Bateman. > Towards the end of our development effort for Java 9, we found that > Javac and > Eclipse compiler produced different results for > ModuleElement.getEnclosedElements() > for a binary module under certain circumstances. Specifically, for a > binary module that > exports a package that doesn't have any types (the sources had only a > compilation unit > with a package declaration), Javac includes that package in the > enclosed element list, > but Eclipse doesn't. I understand it is like this for consistency > sake, but does it make > sense especially in light of what we see during the following example: > Let's say module A has a package x.y.z which has X.java which has the > following: > package x.y.z; > Now module B requires module A. Module "B" also has A.java, which > imports "x.y.z.*". > Compiling both A and B goes well. But things don't go well when I > first compiler A and > then B by having A in its module-path. I see the following: > error: package x.y.z does not exist > As you can clearly see, compilation is not consistent between the two > modes. Also, > APT considering a non-existing package doesn't make sense either. > At the very least, the APT models should ignore the packages that > don't exist anymore. > Regards, > Jay > -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Fri Oct 13 19:59:52 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 13 Oct 2017 20:59:52 +0100 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> <9b392574-0f51-be26-ceeb-1fa82a9e7dcc@oracle.com> <09308a0b-4d1a-608e-7477-fc5bf142492b@oracle.com> Message-ID: <22818a1e-f2b1-5c4e-e98b-a4c0f9c8e52e@oracle.com> Hi, I think the affected area is close to this: https://bugs.openjdk.java.net/browse/JDK-8178150 for which I have a fix in the work which I will submit for review soon. After that fix is in, we can consider deeper refactorings in the area. Cheers Maurizio On 13/10/17 17:59, B. Blaser wrote: > On 13 October 2017 at 14:31, Vicente Romero wrote: >> >>> On 10/13/2017 05:08 AM, Maurizio Cimadamore wrote: >>> >>> >>> But I think there's only _one_ minimal answer. So, the way I see the javac >>> implementation, is that the BestLeafSolver is a big workaround to the fact >>> that we need to be able to solve a 'subset' of the inference graph. But this >>> can be achieved in many different ways - and the approach implemented right >>> now (which predates the spec text) is probably more general than it needs >>> to. >>> >>> I think a very simple BestLeafSolver would simply 'skip' all the inference >>> graph nodes which cannot influence any of the nodes containing at least one >>> variable in the target set, and will keep going until all variables in such >>> set are solved. I don' think such an algorithm would require any tracking of >>> cost, paths and such. >>> >>> >> well I think that there are two parts here, one is finding that minimal set >> that could be done using a simple flood fill algorithm in the graph, just >> connectivity matters. > This seems not to be needed as all the subtrees matching the variables > in the list will have to be solved. > We can simply peek the first one. > >> But then once we have the subset, we have to find a >> resolution order right? After the application of the Tarjan algo for >> strongly connected components, the graph is already topologically sorted. >> The subset found in step 1 will also be sorted we can follow that order. > Once we have selected a subtree matching one of the variables in the > list (pt 3), we can simply solve all the subtree leaf by leaf. As > leaves aren't inter-dependent, the order we solve them doesn't matter > I think. > > Please take a look at the suggested implementation in attachment. > It seems to give quite good results. > > What do you think? > Bernard > > >>> Maurizio >> >> Vicente From jarthana at in.ibm.com Sat Oct 14 03:36:37 2017 From: jarthana at in.ibm.com (Jayaprakash Arthanareeswaran) Date: Sat, 14 Oct 2017 03:36:37 +0000 Subject: Module loses its package after compilation when the package has nothing but a compilation unit with package declaration. In-Reply-To: References: , Message-ID: An HTML attachment was scrubbed... URL: From bsrbnd at gmail.com Sun Oct 15 11:48:05 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Sun, 15 Oct 2017 13:48:05 +0200 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: <22818a1e-f2b1-5c4e-e98b-a4c0f9c8e52e@oracle.com> References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> <9b392574-0f51-be26-ceeb-1fa82a9e7dcc@oracle.com> <09308a0b-4d1a-608e-7477-fc5bf142492b@oracle.com> <22818a1e-f2b1-5c4e-e98b-a4c0f9c8e52e@oracle.com> Message-ID: On 13 October 2017 at 21:59, Maurizio Cimadamore wrote: > Hi, > I think the affected area is close to this: > > https://bugs.openjdk.java.net/browse/JDK-8178150 Quoting from your JBS comment, here are the two stuck expressions: * LOGGER::info - input vars = { C }, output vars = { } * iterable -> "" - input vars = { T1 }, output vars = { T2 } The problem here is that the input var 'C' is influenced by the output var 'T2' via the bound set of 'C' which doesn't seem to be currently implemented in javac. I wrote a fix, here under, that adds the corresponding dependencies before computing the acyclic stuck graph in 'DeferredAttr.pickDeferredNode()'. I tried this fix using the "lazy" leaf heuristic (the last one I suggested) that picks a node to be solved in O(log(n)). Note that this fix shouldn't interfere with any leaf solving heuristic so that it should be possible to choose the best one between: * the current one (with optimization?) that chooses the smallest subtree * the "lazy" one that minimizes the effort to choose a leaf in O(log(n)) * the "conservative" one (from Vicente) that picks the nearest leaf * or any other heuristic like the "aggressive" one Does this fix look reasonable to you? Cheers, Bernard diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -29,6 +29,8 @@ import com.sun.source.tree.NewClassTree; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Type.StructuralTypeMapping; +import com.sun.tools.javac.code.Type.UndetVar; +import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; import com.sun.tools.javac.code.Types.TypeMapping; import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext; import com.sun.tools.javac.comp.Resolve.ResolveError; @@ -668,10 +670,15 @@ //the intersection between A's input variable and B's output variable is non-empty. for (StuckNode sn1 : nodes) { for (Type t : sn1.data.deferredStuckPolicy.stuckVars()) { + UndetVar uv = (UndetVar)inferenceContext.asUndetVar(t); for (StuckNode sn2 : nodes) { - if (sn1 != sn2 && sn2.data.deferredStuckPolicy.depVars().contains(t)) { + if (sn1 == sn2) continue; + + Set depVars = sn2.data.deferredStuckPolicy.depVars(); + + if (depVars.contains(t) || Type.containsAny( + uv.getBounds(InferenceBound.values()), List.from(depVars))) sn1.deps.add(sn2); - } } } } > for which I have a fix in the work which I will submit for review soon. > > After that fix is in, we can consider deeper refactorings in the area. > > Cheers > Maurizio From maurizio.cimadamore at oracle.com Sun Oct 15 21:04:47 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Sun, 15 Oct 2017 22:04:47 +0100 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> <9b392574-0f51-be26-ceeb-1fa82a9e7dcc@oracle.com> <09308a0b-4d1a-608e-7477-fc5bf142492b@oracle.com> <22818a1e-f2b1-5c4e-e98b-a4c0f9c8e52e@oracle.com> Message-ID: Thanks - as I said I already have a fix for this - I will submit this soon. Maurizio On 15/10/17 12:48, B. Blaser wrote: > On 13 October 2017 at 21:59, Maurizio Cimadamore > wrote: >> Hi, >> I think the affected area is close to this: >> >> https://bugs.openjdk.java.net/browse/JDK-8178150 > Quoting from your JBS comment, here are the two stuck expressions: > > * LOGGER::info - input vars = { C }, output vars = { } > * iterable -> "" - input vars = { T1 }, output vars = { T2 } > > The problem here is that the input var 'C' is influenced by the output > var 'T2' via the bound set of 'C' which doesn't seem to be currently > implemented in javac. > > I wrote a fix, here under, that adds the corresponding dependencies > before computing the acyclic stuck graph in > 'DeferredAttr.pickDeferredNode()'. > > I tried this fix using the "lazy" leaf heuristic (the last one I > suggested) that picks a node to be solved in O(log(n)). > > Note that this fix shouldn't interfere with any leaf solving heuristic > so that it should be possible to choose the best one between: > * the current one (with optimization?) that chooses the smallest subtree > * the "lazy" one that minimizes the effort to choose a leaf in O(log(n)) > * the "conservative" one (from Vicente) that picks the nearest leaf > * or any other heuristic like the "aggressive" one > > Does this fix look reasonable to you? > > Cheers, > Bernard > > > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java > b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java > @@ -29,6 +29,8 @@ > import com.sun.source.tree.NewClassTree; > import com.sun.tools.javac.code.*; > import com.sun.tools.javac.code.Type.StructuralTypeMapping; > +import com.sun.tools.javac.code.Type.UndetVar; > +import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; > import com.sun.tools.javac.code.Types.TypeMapping; > import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext; > import com.sun.tools.javac.comp.Resolve.ResolveError; > @@ -668,10 +670,15 @@ > //the intersection between A's input variable and B's > output variable is non-empty. > for (StuckNode sn1 : nodes) { > for (Type t : sn1.data.deferredStuckPolicy.stuckVars()) { > + UndetVar uv = (UndetVar)inferenceContext.asUndetVar(t); > for (StuckNode sn2 : nodes) { > - if (sn1 != sn2 && > sn2.data.deferredStuckPolicy.depVars().contains(t)) { > + if (sn1 == sn2) continue; > + > + Set depVars = > sn2.data.deferredStuckPolicy.depVars(); > + > + if (depVars.contains(t) || Type.containsAny( > + > uv.getBounds(InferenceBound.values()), List.from(depVars))) > sn1.deps.add(sn2); > - } > } > } > } > > >> for which I have a fix in the work which I will submit for review soon. >> >> After that fix is in, we can consider deeper refactorings in the area. >> >> Cheers >> Maurizio From maurizio.cimadamore at oracle.com Mon Oct 16 09:52:25 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 16 Oct 2017 10:52:25 +0100 Subject: RFR: JDK-8180744: Update ct.sym for JDK 10 In-Reply-To: References: <59E0B1DE.3000701@oracle.com> Message-ID: Hi Martin, I believe some comments on how files are generated are here: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java.html That said, I agree it would perhaps be a nice improvement (not necessary for this particular review), to record the launcher/options used to generate each file as comments in the file header. Maurizio On 13/10/17 17:49, Martin Buchholz wrote: > (drive-by comments) > > It's great that generated files are marked as such, but: > - It's not obvious HOW these files are generated.? Actually having the > generation command write its own invocation into the generated files > might be helpful. > - do generated files need a legal notice? > +# ########################################################## > +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### > +# ########################################################## > > > The order of releases is surprising: > +generate platforms 8:7:6:9 > > On Fri, Oct 13, 2017 at 5:30 AM, Jan Lahoda > wrote: > > Hi, > > The patch here adds a support for --release 9 to OpenJDK. This > includes adding a snapshot of the JDK 9 APIs. > > Notes: > -several changes to the historical data in make/data/symbols: > --java.management.rmi-8.sym.txt contains a few classes that were > originally in java.management-8.sym.txt (this change is adjusting > the structure to adhere more to the final JDK 9 module layout) > --java.annotations.common-* renamed to java.xml.ws.annotation-* to > adhere to the final layout > --diffing of classes across releases has been improved to avoid > some unnecessary class header notices in the historical data > --empty files are now not written for the historical data > -the (JDK)PlatformProvider.PlatformDescription(Impl) now returns a > file manager, instead of a list of paths. This makes the contract > cleaner, and allow to handle the ".sig" extension mostly in the > file manager instead of ClassFinder. (Due to this change, > JDK-8139607: '-release option forces StandardJavaFileManager' is > also resolved by this patch, although it is not the primary goal > of this patch.) > > Bug: https://bugs.openjdk.java.net/browse/JDK-8180744 > > Webrev: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/ > > > I'll send to build-dev as well after the javac changes will look OK. > > Any feedback is welcome. > > Thanks, > ? ? Jan > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jan.lahoda at oracle.com Mon Oct 16 11:56:50 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Mon, 16 Oct 2017 13:56:50 +0200 Subject: RFR: JDK-8180744: Update ct.sym for JDK 10 In-Reply-To: References: <59E0B1DE.3000701@oracle.com> Message-ID: <59E49E82.7090409@oracle.com> On 16.10.2017 11:52, Maurizio Cimadamore wrote: > Hi Martin, > I believe some comments on how files are generated are here: > > http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java.html > > That said, I agree it would perhaps be a nice improvement (not necessary > for this particular review), to record the launcher/options used to > generate each file as comments in the file header. Sure, I'll work on adding that. I'll probably add that only to the symbols file. > > Maurizio > > > On 13/10/17 17:49, Martin Buchholz wrote: >> (drive-by comments) >> >> It's great that generated files are marked as such, but: >> - It's not obvious HOW these files are generated. Actually having the >> generation command write its own invocation into the generated files >> might be helpful. >> - do generated files need a legal notice? Is it wrong to include that notice? >> +# ########################################################## >> +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### >> +# ########################################################## >> >> >> The order of releases is surprising: >> +generate platforms 8:7:6:9 It is true that the order is not significant here, although it is significant on other places - the .sym.txt files (can and currently do) only store full APIs for one version (8 currently), and the rest is just diffs between versions. So when reading a .sym.txt files for a version, the data for the base version need to be already read. Thanks, Jan >> >> On Fri, Oct 13, 2017 at 5:30 AM, Jan Lahoda > > wrote: >> >> Hi, >> >> The patch here adds a support for --release 9 to OpenJDK. This >> includes adding a snapshot of the JDK 9 APIs. >> >> Notes: >> -several changes to the historical data in make/data/symbols: >> --java.management.rmi-8.sym.txt contains a few classes that were >> originally in java.management-8.sym.txt (this change is adjusting >> the structure to adhere more to the final JDK 9 module layout) >> --java.annotations.common-* renamed to java.xml.ws.annotation-* to >> adhere to the final layout >> --diffing of classes across releases has been improved to avoid >> some unnecessary class header notices in the historical data >> --empty files are now not written for the historical data >> -the (JDK)PlatformProvider.PlatformDescription(Impl) now returns a >> file manager, instead of a list of paths. This makes the contract >> cleaner, and allow to handle the ".sig" extension mostly in the >> file manager instead of ClassFinder. (Due to this change, >> JDK-8139607: '-release option forces StandardJavaFileManager' is >> also resolved by this patch, although it is not the primary goal >> of this patch.) >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8180744 >> >> Webrev: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/ >> >> >> I'll send to build-dev as well after the javac changes will look OK. >> >> Any feedback is welcome. >> >> Thanks, >> Jan >> >> > From martinrb at google.com Mon Oct 16 15:41:20 2017 From: martinrb at google.com (Martin Buchholz) Date: Mon, 16 Oct 2017 08:41:20 -0700 Subject: RFR: JDK-8189094: Change required boot jdk to JDK 9 In-Reply-To: References: Message-ID: The difficulties encountered trying to run langtools10 in a jdk9 suggests that the jdk9 module model is too restrictive. I've long lobbied for treating langtools as just another collection of ordinary programs that happen to be written in java and should not need special support from the host jdk. Many people will want to run modified langtools. Shouldn't replaceability of any module be one of the goals of the module system? On Mon, Oct 16, 2017 at 6:12 AM, Erik Joelsson wrote: > With JDK 9 released, it's high time to change the required boot jdk for > building JDK 10. This time, the change wasn't as straight forward as it > usually is. > > It's currently possible to use any of JDK 8, 9 or a recent build of 10 to > boot the JDK 10 build. This support is however fragile. The most sensitive > part is the building and running of the interim javac and javadoc tools, > where we build the new JDK 10 versions of these tools, but -source/-target > set appropriate for the boot jdk, so we can run them on the boot jdk when > compiling the rest of the product. > > In the current build, we compile the java source files of the modules > java.compiler, jdk.compiler, jdk.javadoc and jdk.jdeps in the legacy way, > using -Xbootclasspath and not including any module-info.java files. We then > run them by using the --patch-module argument. This means we are running > the JDK 10 classes but using the module definitions of the boot jdk. This > works for now, but when the JDK module definitions for any of these modules > need to change, this model will start to break. > > In this patch I have tried to change this so we compile and run using JDK > 9 module style modes. The big problem to overcome then is that > jdk.compiler, and jdk.javadoc are not upgradeable. This means we can't > compile new versions of these modules and override them in the boot jdk. > This leaves us with two options: either run the interim classes in the > unnamed module, or define a new set of interim modules, based on the > existing modules but with new names. The first option seems simpler, but > that would require maintaining legacy service provider definitions for > these modules. So I chose the latter instead. The new module names have > ".interim" as suffix. > > To generate the new modules, I copy the module-info.java files to a new > gensrc dir and sed replace the module names. I also generate a new > ToolProvider.java so that the default tools are taken from the interim > modules. > > I've made sure that jrtfs.jar is generated with --release 8 to keep > compatibility with JDK 8. > > Webrev: http://cr.openjdk.java.net/~erikj/8189094/webrev.01 > > Bug: https://bugs.openjdk.java.net/browse/JDK-8189094 > > /Erik > -------------- next part -------------- An HTML attachment was scrubbed... URL: From joe.darcy at oracle.com Mon Oct 16 17:01:31 2017 From: joe.darcy at oracle.com (joe darcy) Date: Mon, 16 Oct 2017 10:01:31 -0700 Subject: Module loses its package after compilation when the package has nothing but a compilation unit with package declaration. In-Reply-To: References: Message-ID: Hello Jay, On 10/13/2017 8:36 PM, Jayaprakash Arthanareeswaran wrote: > Hello Joe, > We started implementing the API very early in our Java 9 effort and > found no issues with the API > so far until we ran into this particular issue very late in the game. > If I were to go by what Alex said > in the other mail, this is perhaps a bug on the annotation processing > side of Javac. > It would have been useful to know no issues were found while the API was under development during JDK 9. -Joe -------------- next part -------------- An HTML attachment was scrubbed... URL: From Alan.Bateman at oracle.com Mon Oct 16 17:18:19 2017 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 16 Oct 2017 18:18:19 +0100 Subject: RFR: JDK-8189094: Change required boot jdk to JDK 9 In-Reply-To: References: Message-ID: <96cea94b-9945-986b-4c38-1ad7d16b7735@oracle.com> On 16/10/2017 16:41, Martin Buchholz wrote: > The difficulties encountered trying to run langtools10 in a jdk9 suggests > that the jdk9 module model is too restrictive. I've long lobbied for > treating langtools as just another collection of ordinary programs that > happen to be written in java and should not need special support from the > host jdk. > > Many people will want to run modified langtools. Shouldn't replaceability > of any module be one of the goals of the module system? > The module system already supports ways to replace/override a module (via the upgrade module path and the --upgrade-module-path option) or patch/augment a module to override or add classes/resources (--patch-module). At the same time, it supports the ability to tie a group of closely connected modules with integrity hashes to prevent accidental mixing of modules from different builds or releases. The issue that Erik has been wrestling with is that a module can't be both upgradeable and non-upgradable at the same time. If they upgradeable then you risk someone creating a run-time image with jdk.compiler and jdk.javadoc modules from different JDK releases - it's not supportable of course. If you continue with them as non-upgradeable modules then you need to do something special in the JDK build to combine a boot JDK with newer versions of the modules and this is what Erik is doing. There are a couple of ways to do that, like putting the classes for these modules on the class path and limiting observability with --limit-modules. The alternative is to put the code into modules with new names, Erik's patch favors that approach. -Alan. From martinrb at google.com Mon Oct 16 18:18:57 2017 From: martinrb at google.com (Martin Buchholz) Date: Mon, 16 Oct 2017 11:18:57 -0700 Subject: RFR: JDK-8189094: Change required boot jdk to JDK 9 In-Reply-To: <96cea94b-9945-986b-4c38-1ad7d16b7735@oracle.com> References: <96cea94b-9945-986b-4c38-1ad7d16b7735@oracle.com> Message-ID: Obviously y'all have the engineering resources to do any shoe-horning necessary to get jdk9 to run jdk10 langtools. But consider that this is the sort of thing users will be doing as well. It seems very natural to decouple langtools from its host jdk; at Google we often run langtools hosted in the "wrong version" JDK. I would choose a name other than "interim" which suggests what you're doing is only for bootstrapping. Imagine that the langtools10 will become an independent modular artifact hosted on Maven Central. I'd like to be able, at runtime, to decide whether to use jdk N langtools or jdk N+1 langtools (or special errorprone-enabled langtools, etc...), and have a minimal-effort solution that allows that to happen. Java's bootstrap process should be a poster child for the promise of modularity, that I could copy to enable my runtime choices. On Mon, Oct 16, 2017 at 10:18 AM, Alan Bateman wrote: > On 16/10/2017 16:41, Martin Buchholz wrote: > >> The difficulties encountered trying to run langtools10 in a jdk9 suggests >> that the jdk9 module model is too restrictive. I've long lobbied for >> treating langtools as just another collection of ordinary programs that >> happen to be written in java and should not need special support from the >> host jdk. >> >> Many people will want to run modified langtools. Shouldn't replaceability >> of any module be one of the goals of the module system? >> >> The module system already supports ways to replace/override a module (via > the upgrade module path and the --upgrade-module-path option) or > patch/augment a module to override or add classes/resources > (--patch-module). > > At the same time, it supports the ability to tie a group of closely > connected modules with integrity hashes to prevent accidental mixing of > modules from different builds or releases. > > The issue that Erik has been wrestling with is that a module can't be both > upgradeable and non-upgradable at the same time. If they upgradeable then > you risk someone creating a run-time image with jdk.compiler and > jdk.javadoc modules from different JDK releases - it's not supportable of > course. If you continue with them as non-upgradeable modules then you need > to do something special in the JDK build to combine a boot JDK with newer > versions of the modules and this is what Erik is doing. There are a couple > of ways to do that, like putting the classes for these modules on the class > path and limiting observability with --limit-modules. The alternative is to > put the code into modules with new names, Erik's patch favors that approach. > > -Alan. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From martinrb at google.com Mon Oct 16 18:53:18 2017 From: martinrb at google.com (Martin Buchholz) Date: Mon, 16 Oct 2017 11:53:18 -0700 Subject: RFR: JDK-8189094: Change required boot jdk to JDK 9 In-Reply-To: References: <96cea94b-9945-986b-4c38-1ad7d16b7735@oracle.com> Message-ID: What's the canonical way to list all upgradeable modules? There's a list in JEP 261, but naturally we can't consider it authoritative. I was surprised that even java --describe-module doesn't tell me whether a module is upgradeable. I was surprised to see JEP 261 say that java.compiler is upgradeable, but not jdk.compiler. Perhaps thinking of the bootstrap use case? -------------- next part -------------- An HTML attachment was scrubbed... URL: From Alan.Bateman at oracle.com Mon Oct 16 19:31:29 2017 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 16 Oct 2017 20:31:29 +0100 Subject: RFR: JDK-8189094: Change required boot jdk to JDK 9 In-Reply-To: References: <96cea94b-9945-986b-4c38-1ad7d16b7735@oracle.com> Message-ID: <54583c4a-218f-64f2-7329-019aa402dc70@oracle.com> On 16/10/2017 19:53, Martin Buchholz wrote: > What's the canonical way to list all upgradeable modules? > There's a list in JEP 261, but naturally we can't consider it > authoritative. make/common/Modules.gmk has the list (look for UPGRADEABLE_MODULES and UPGRADEABLE_TOOL_MODULES). > > I was surprised that even java --describe-module doesn't tell me > whether a module is upgradeable. All non-core modules (meaning modules not associated with the boot loader) are upgradable unless tied by hashes to java.base. So you need to look at java.base to find the list of modules that it has recorded hashes for. `javap -v -m java.base module-info` is one way to see this. Not very user friendly but upgradeable modules aren't broadly interesting to joe developer. If joe developer is interested then the javadoc for each of the upgradable modules has a statement in its javadoc to say this. The equivalent with Java SE 8 / JDK 8 and older was the table of APIs and JSR in the Endorsed Standards Override Mechanism document. > > I was surprised to see JEP 261 say that java.compiler is upgradeable, > but not jdk.compiler. > Perhaps thinking of the bootstrap use case? I see Jon has replied to this point. Another part to that is that java.compiler exports the APIs maintained by JSR 199 and JSR 269 and these two JSR remain standalone technoloiges. -Alan. -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Mon Oct 16 20:30:07 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 16 Oct 2017 21:30:07 +0100 Subject: RFR: JDK-8180744: Update ct.sym for JDK 10 In-Reply-To: <59E0B1DE.3000701@oracle.com> References: <59E0B1DE.3000701@oracle.com> Message-ID: Hi Jan, the patch looks very good. I like the new JDKPlatformProvider and I find the new interface a lot cleaner (and I like that you could remove support for sig files from other javac components, that is a good sign!). Overall I think that we should try and improve (not as part of this review/bug) CreateSymbols. It is quite a big class, doing many things at once. I think at the very least we should try to add more documentations (e.g. I found many invariants that are not documented), and, in the long run, I think the code would probably benefit if we could split CreateSymbols in 3 parts: * definition of the DescriptionXYZ classes * one tool to generate the sym.txt files * one tool to generate ct.sym from description files Also, I couldn't help but note that certain constraints had a significant impact on the implementation complexity: * the fact that it is not customary to store binary files in openjdk probably forced you to 'quote' the classfiles guts (as generated by Probe.java) * a similar restriction was probably the cause for having a text file representation rather than a classfile based one (which would have been much more amenable to be manipulated with tools such as ASM) * the desire not to call .sig file 'classfiles' (as they are not well-formed) is also causing unnecessary complexity - in principle you shouldn't need a special file manager to load those Anyway, all the comments are clearly outside the scope of this review - I just hope that at some point some of these decisions would be looked at again, to see if we can achieve this feature in a way that's easier to maintain in the long run. Cheers Maurizio On 13/10/17 13:30, Jan Lahoda wrote: > Hi, > > The patch here adds a support for --release 9 to OpenJDK. This > includes adding a snapshot of the JDK 9 APIs. > > Notes: > -several changes to the historical data in make/data/symbols: > --java.management.rmi-8.sym.txt contains a few classes that were > originally in java.management-8.sym.txt (this change is adjusting the > structure to adhere more to the final JDK 9 module layout) > --java.annotations.common-* renamed to java.xml.ws.annotation-* to > adhere to the final layout > --diffing of classes across releases has been improved to avoid some > unnecessary class header notices in the historical data > --empty files are now not written for the historical data > -the (JDK)PlatformProvider.PlatformDescription(Impl) now returns a > file manager, instead of a list of paths. This makes the contract > cleaner, and allow to handle the ".sig" extension mostly in the file > manager instead of ClassFinder. (Due to this change, JDK-8139607: > '-release option forces StandardJavaFileManager' is also resolved by > this patch, although it is not the primary goal of this patch.) > > Bug: https://bugs.openjdk.java.net/browse/JDK-8180744 > Webrev: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/ > > I'll send to build-dev as well after the javac changes will look OK. > > Any feedback is welcome. > > Thanks, > ??? Jan From jan.lahoda at oracle.com Tue Oct 17 13:19:20 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Tue, 17 Oct 2017 15:19:20 +0200 Subject: RFR: JDK-8180744: Update ct.sym for JDK 10 In-Reply-To: <59E49E82.7090409@oracle.com> References: <59E0B1DE.3000701@oracle.com> <59E49E82.7090409@oracle.com> Message-ID: <59E60358.6040608@oracle.com> An updated version of the patch that records in the symbols file the arguments used to generate the -sym.txt files and that sorts the platforms in generate platforms is here: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.01/ Thanks for the comments so far! Jan On 16.10.2017 13:56, Jan Lahoda wrote: > On 16.10.2017 11:52, Maurizio Cimadamore wrote: >> Hi Martin, >> I believe some comments on how files are generated are here: >> >> http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java.html >> >> >> That said, I agree it would perhaps be a nice improvement (not necessary >> for this particular review), to record the launcher/options used to >> generate each file as comments in the file header. > > Sure, I'll work on adding that. I'll probably add that only to the > symbols file. > >> >> Maurizio >> >> >> On 13/10/17 17:49, Martin Buchholz wrote: >>> (drive-by comments) >>> >>> It's great that generated files are marked as such, but: >>> - It's not obvious HOW these files are generated. Actually having the >>> generation command write its own invocation into the generated files >>> might be helpful. >>> - do generated files need a legal notice? > > Is it wrong to include that notice? > >>> +# ########################################################## >>> +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### >>> +# ########################################################## >>> >>> >>> The order of releases is surprising: >>> +generate platforms 8:7:6:9 > > It is true that the order is not significant here, although it is > significant on other places - the .sym.txt files (can and currently do) > only store full APIs for one version (8 currently), and the rest is just > diffs between versions. So when reading a .sym.txt files for a version, > the data for the base version need to be already read. > > Thanks, > Jan > >>> >>> On Fri, Oct 13, 2017 at 5:30 AM, Jan Lahoda >> > wrote: >>> >>> Hi, >>> >>> The patch here adds a support for --release 9 to OpenJDK. This >>> includes adding a snapshot of the JDK 9 APIs. >>> >>> Notes: >>> -several changes to the historical data in make/data/symbols: >>> --java.management.rmi-8.sym.txt contains a few classes that were >>> originally in java.management-8.sym.txt (this change is adjusting >>> the structure to adhere more to the final JDK 9 module layout) >>> --java.annotations.common-* renamed to java.xml.ws.annotation-* to >>> adhere to the final layout >>> --diffing of classes across releases has been improved to avoid >>> some unnecessary class header notices in the historical data >>> --empty files are now not written for the historical data >>> -the (JDK)PlatformProvider.PlatformDescription(Impl) now returns a >>> file manager, instead of a list of paths. This makes the contract >>> cleaner, and allow to handle the ".sig" extension mostly in the >>> file manager instead of ClassFinder. (Due to this change, >>> JDK-8139607: '-release option forces StandardJavaFileManager' is >>> also resolved by this patch, although it is not the primary goal >>> of this patch.) >>> >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8180744 >>> >>> Webrev: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/ >>> >>> >>> I'll send to build-dev as well after the javac changes will look OK. >>> >>> Any feedback is welcome. >>> >>> Thanks, >>> Jan >>> >>> >> From jan.lahoda at oracle.com Tue Oct 17 13:20:37 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Tue, 17 Oct 2017 15:20:37 +0200 Subject: RFR: JDK-8180744: Update ct.sym for JDK 10 In-Reply-To: References: <59E0B1DE.3000701@oracle.com> Message-ID: <59E603A5.50809@oracle.com> On 16.10.2017 22:30, Maurizio Cimadamore wrote: > Hi Jan, > the patch looks very good. I like the new JDKPlatformProvider and I find > the new interface a lot cleaner (and I like that you could remove > support for sig files from other javac components, that is a good sign!). Thanks! > > Overall I think that we should try and improve (not as part of this > review/bug) CreateSymbols. It is quite a big class, doing many things at > once. I think at the very least we should try to add more documentations > (e.g. I found many invariants that are not documented), and, in the long > run, I think the code would probably benefit if we could split > CreateSymbols in 3 parts: > > * definition of the DescriptionXYZ classes > * one tool to generate the sym.txt files > * one tool to generate ct.sym from description files I've filled: https://bugs.openjdk.java.net/browse/JDK-8189435 Jan > > Also, I couldn't help but note that certain constraints had a > significant impact on the implementation complexity: > > * the fact that it is not customary to store binary files in openjdk > probably forced you to 'quote' the classfiles guts (as generated by > Probe.java) > * a similar restriction was probably the cause for having a text file > representation rather than a classfile based one (which would have been > much more amenable to be manipulated with tools such as ASM) > * the desire not to call .sig file 'classfiles' (as they are not > well-formed) is also causing unnecessary complexity - in principle you > shouldn't need a special file manager to load those > > Anyway, all the comments are clearly outside the scope of this review - > I just hope that at some point some of these decisions would be looked > at again, to see if we can achieve this feature in a way that's easier > to maintain in the long run. > > Cheers > Maurizio > > > On 13/10/17 13:30, Jan Lahoda wrote: >> Hi, >> >> The patch here adds a support for --release 9 to OpenJDK. This >> includes adding a snapshot of the JDK 9 APIs. >> >> Notes: >> -several changes to the historical data in make/data/symbols: >> --java.management.rmi-8.sym.txt contains a few classes that were >> originally in java.management-8.sym.txt (this change is adjusting the >> structure to adhere more to the final JDK 9 module layout) >> --java.annotations.common-* renamed to java.xml.ws.annotation-* to >> adhere to the final layout >> --diffing of classes across releases has been improved to avoid some >> unnecessary class header notices in the historical data >> --empty files are now not written for the historical data >> -the (JDK)PlatformProvider.PlatformDescription(Impl) now returns a >> file manager, instead of a list of paths. This makes the contract >> cleaner, and allow to handle the ".sig" extension mostly in the file >> manager instead of ClassFinder. (Due to this change, JDK-8139607: >> '-release option forces StandardJavaFileManager' is also resolved by >> this patch, although it is not the primary goal of this patch.) >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8180744 >> Webrev: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/ >> >> I'll send to build-dev as well after the javac changes will look OK. >> >> Any feedback is welcome. >> >> Thanks, >> Jan > From maurizio.cimadamore at oracle.com Tue Oct 17 14:48:13 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 17 Oct 2017 15:48:13 +0100 Subject: RFR: JDK-8180744: Update ct.sym for JDK 10 In-Reply-To: <59E60358.6040608@oracle.com> References: <59E0B1DE.3000701@oracle.com> <59E49E82.7090409@oracle.com> <59E60358.6040608@oracle.com> Message-ID: <682e35c3-b9a4-5c05-8866-886c0f4d7d49@oracle.com> Thanks for taking care of this issue and for filing up the followup issue. As for this change, I guess I wished that every generated file had some explanation as to how it was obtained, but as discussed offline, this is not possible for the various sym.txt files - as they are all generated in the same run, and to generate them sometimes you need to use files that are not checked in. So, overall, I approve this changeset as is. Maurizio On 17/10/17 14:19, Jan Lahoda wrote: > An updated version of the patch that records in the symbols file the > arguments used to generate the -sym.txt files and that sorts the > platforms in generate platforms is here: > http://cr.openjdk.java.net/~jlahoda/8180744/webrev.01/ > > Thanks for the comments so far! > ??? Jan > > On 16.10.2017 13:56, Jan Lahoda wrote: >> On 16.10.2017 11:52, Maurizio Cimadamore wrote: >>> Hi Martin, >>> I believe some comments on how files are generated are here: >>> >>> http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java.html >>> >>> >>> >>> That said, I agree it would perhaps be a nice improvement (not >>> necessary >>> for this particular review), to record the launcher/options used to >>> generate each file as comments in the file header. >> >> Sure, I'll work on adding that. I'll probably add that only to the >> symbols file. >> >>> >>> Maurizio >>> >>> >>> On 13/10/17 17:49, Martin Buchholz wrote: >>>> (drive-by comments) >>>> >>>> It's great that generated files are marked as such, but: >>>> - It's not obvious HOW these files are generated.? Actually having the >>>> generation command write its own invocation into the generated files >>>> might be helpful. >>>> - do generated files need a legal notice? >> >> Is it wrong to include that notice? >> >>>> +# ########################################################## >>>> +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### >>>> +# ########################################################## >>>> >>>> >>>> The order of releases is surprising: >>>> +generate platforms 8:7:6:9 >> >> It is true that the order is not significant here, although it is >> significant on other places - the .sym.txt files (can and currently do) >> only store full APIs for one version (8 currently), and the rest is just >> diffs between versions. So when reading a .sym.txt files for a version, >> the data for the base version need to be already read. >> >> Thanks, >> ??? Jan >> >>>> >>>> On Fri, Oct 13, 2017 at 5:30 AM, Jan Lahoda >>> > wrote: >>>> >>>> ??? Hi, >>>> >>>> ??? The patch here adds a support for --release 9 to OpenJDK. This >>>> ??? includes adding a snapshot of the JDK 9 APIs. >>>> >>>> ??? Notes: >>>> ??? -several changes to the historical data in make/data/symbols: >>>> ??? --java.management.rmi-8.sym.txt contains a few classes that were >>>> ??? originally in java.management-8.sym.txt (this change is adjusting >>>> ??? the structure to adhere more to the final JDK 9 module layout) >>>> ??? --java.annotations.common-* renamed to java.xml.ws.annotation-* to >>>> ??? adhere to the final layout >>>> ??? --diffing of classes across releases has been improved to avoid >>>> ??? some unnecessary class header notices in the historical data >>>> ??? --empty files are now not written for the historical data >>>> ??? -the (JDK)PlatformProvider.PlatformDescription(Impl) now returns a >>>> ??? file manager, instead of a list of paths. This makes the contract >>>> ??? cleaner, and allow to handle the ".sig" extension mostly in the >>>> ??? file manager instead of ClassFinder. (Due to this change, >>>> ??? JDK-8139607: '-release option forces StandardJavaFileManager' is >>>> ??? also resolved by this patch, although it is not the primary goal >>>> ??? of this patch.) >>>> >>>> ??? Bug: https://bugs.openjdk.java.net/browse/JDK-8180744 >>>> ??? >>>> ??? Webrev: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/ >>>> >>>> >>>> ??? I'll send to build-dev as well after the javac changes will >>>> look OK. >>>> >>>> ??? Any feedback is welcome. >>>> >>>> ??? Thanks, >>>> ??????? Jan >>>> >>>> >>> From martinrb at google.com Tue Oct 17 16:31:37 2017 From: martinrb at google.com (Martin Buchholz) Date: Tue, 17 Oct 2017 09:31:37 -0700 Subject: RFR: JDK-8189094: Change required boot jdk to JDK 9 In-Reply-To: <54583c4a-218f-64f2-7329-019aa402dc70@oracle.com> References: <96cea94b-9945-986b-4c38-1ad7d16b7735@oracle.com> <54583c4a-218f-64f2-7329-019aa402dc70@oracle.com> Message-ID: 1. The upgrade module path. This path contains compiled definitions of modules that will be observed in preference to the compiled definitions of any *upgradeable modules* that are present in (3) and (4). See the Java SE Platform for the designation of which standard modules are upgradeable. The doc for java.lang.module says "See the Java SE Platform" but I guess that just means checking the javadoc for each module to check whether it's upgradeable. It's surprising to see runtime modules tied together to the extent of recording hashes of contents of reverse dependencies, but as you say few developers will need to care. This does mean you can never "drop in" an independently built module into a jdk the way hotspot developers do with libjvm.so. But that's OK - --patch-module and the ability to build from source are sufficient. -------------- next part -------------- An HTML attachment was scrubbed... URL: From martinrb at google.com Tue Oct 17 16:53:42 2017 From: martinrb at google.com (Martin Buchholz) Date: Tue, 17 Oct 2017 09:53:42 -0700 Subject: RFR: JDK-8189094: Change required boot jdk to JDK 9 In-Reply-To: References: <96cea94b-9945-986b-4c38-1ad7d16b7735@oracle.com> <54583c4a-218f-64f2-7329-019aa402dc70@oracle.com> Message-ID: I tried to figure out how this patch actually works. At first I thought we were "shading" (renaming all the packages in the source files) but now I think we're merely renaming the modules by appending ".interim" to the names. But that looks like cheating to me - we're not allowed to have multiple modules containing the same packages, but are getting away with it because the runtime happens to never look at the (unused) original jdk9 modules? -------------- next part -------------- An HTML attachment was scrubbed... URL: From Alan.Bateman at oracle.com Tue Oct 17 17:10:34 2017 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 17 Oct 2017 18:10:34 +0100 Subject: RFR: JDK-8189094: Change required boot jdk to JDK 9 In-Reply-To: References: <96cea94b-9945-986b-4c38-1ad7d16b7735@oracle.com> <54583c4a-218f-64f2-7329-019aa402dc70@oracle.com> Message-ID: On 17/10/2017 17:53, Martin Buchholz wrote: > I tried to figure out how this patch actually works.? At first I > thought we were "shading" (renaming all the packages in the source > files) but now I think we're merely renaming the modules by appending > ".interim" to the names.? But that looks like cheating to me - we're > not allowed to have multiple modules containing the same packages, but > are getting away with it because the runtime happens to never look at > the (unused) original jdk9 modules? The patch uses `--limit-modules` to limit the observability of modules and prevent the jdk.compiler module in the boot JDK from being resolved. If the boot JDK were to resolve jdk.compiler (in its own run-time image) and jdk.compiler.interim on the module path then you would end up with two modules containing the same classes mapped to the app class loader, can't do that. -Alan -------------- next part -------------- An HTML attachment was scrubbed... URL: From jan.lahoda at oracle.com Tue Oct 17 17:47:42 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Tue, 17 Oct 2017 19:47:42 +0200 Subject: RFR: JDK-8180744: Update ct.sym for JDK 10 In-Reply-To: <682e35c3-b9a4-5c05-8866-886c0f4d7d49@oracle.com> References: <59E0B1DE.3000701@oracle.com> <59E49E82.7090409@oracle.com> <59E60358.6040608@oracle.com> <682e35c3-b9a4-5c05-8866-886c0f4d7d49@oracle.com> Message-ID: <59E6423E.7090309@oracle.com> On 17.10.2017 16:48, Maurizio Cimadamore wrote: > Thanks for taking care of this issue and for filing up the followup issue. > > As for this change, I guess I wished that every generated file had some > explanation as to how it was obtained, but as discussed offline, this is > not possible for the various sym.txt files - as they are all generated > in the same run, and to generate them sometimes you need to use files > that are not checked in. If desired, it would be easy to add the note (and any other note) to all the files, just seemed cleaner to put it to the "main" one. Thanks, Jan > > So, overall, I approve this changeset as is. > > Maurizio > > > On 17/10/17 14:19, Jan Lahoda wrote: >> An updated version of the patch that records in the symbols file the >> arguments used to generate the -sym.txt files and that sorts the >> platforms in generate platforms is here: >> http://cr.openjdk.java.net/~jlahoda/8180744/webrev.01/ >> >> Thanks for the comments so far! >> Jan >> >> On 16.10.2017 13:56, Jan Lahoda wrote: >>> On 16.10.2017 11:52, Maurizio Cimadamore wrote: >>>> Hi Martin, >>>> I believe some comments on how files are generated are here: >>>> >>>> http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java.html >>>> >>>> >>>> >>>> That said, I agree it would perhaps be a nice improvement (not >>>> necessary >>>> for this particular review), to record the launcher/options used to >>>> generate each file as comments in the file header. >>> >>> Sure, I'll work on adding that. I'll probably add that only to the >>> symbols file. >>> >>>> >>>> Maurizio >>>> >>>> >>>> On 13/10/17 17:49, Martin Buchholz wrote: >>>>> (drive-by comments) >>>>> >>>>> It's great that generated files are marked as such, but: >>>>> - It's not obvious HOW these files are generated. Actually having the >>>>> generation command write its own invocation into the generated files >>>>> might be helpful. >>>>> - do generated files need a legal notice? >>> >>> Is it wrong to include that notice? >>> >>>>> +# ########################################################## >>>>> +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### >>>>> +# ########################################################## >>>>> >>>>> >>>>> The order of releases is surprising: >>>>> +generate platforms 8:7:6:9 >>> >>> It is true that the order is not significant here, although it is >>> significant on other places - the .sym.txt files (can and currently do) >>> only store full APIs for one version (8 currently), and the rest is just >>> diffs between versions. So when reading a .sym.txt files for a version, >>> the data for the base version need to be already read. >>> >>> Thanks, >>> Jan >>> >>>>> >>>>> On Fri, Oct 13, 2017 at 5:30 AM, Jan Lahoda >>>> > wrote: >>>>> >>>>> Hi, >>>>> >>>>> The patch here adds a support for --release 9 to OpenJDK. This >>>>> includes adding a snapshot of the JDK 9 APIs. >>>>> >>>>> Notes: >>>>> -several changes to the historical data in make/data/symbols: >>>>> --java.management.rmi-8.sym.txt contains a few classes that were >>>>> originally in java.management-8.sym.txt (this change is adjusting >>>>> the structure to adhere more to the final JDK 9 module layout) >>>>> --java.annotations.common-* renamed to java.xml.ws.annotation-* to >>>>> adhere to the final layout >>>>> --diffing of classes across releases has been improved to avoid >>>>> some unnecessary class header notices in the historical data >>>>> --empty files are now not written for the historical data >>>>> -the (JDK)PlatformProvider.PlatformDescription(Impl) now returns a >>>>> file manager, instead of a list of paths. This makes the contract >>>>> cleaner, and allow to handle the ".sig" extension mostly in the >>>>> file manager instead of ClassFinder. (Due to this change, >>>>> JDK-8139607: '-release option forces StandardJavaFileManager' is >>>>> also resolved by this patch, although it is not the primary goal >>>>> of this patch.) >>>>> >>>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8180744 >>>>> >>>>> Webrev: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/ >>>>> >>>>> >>>>> I'll send to build-dev as well after the javac changes will >>>>> look OK. >>>>> >>>>> Any feedback is welcome. >>>>> >>>>> Thanks, >>>>> Jan >>>>> >>>>> >>>> > From maurizio.cimadamore at oracle.com Tue Oct 17 18:04:14 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 17 Oct 2017 19:04:14 +0100 Subject: RFR: JDK-8180744: Update ct.sym for JDK 10 In-Reply-To: <59E6423E.7090309@oracle.com> References: <59E0B1DE.3000701@oracle.com> <59E49E82.7090409@oracle.com> <59E60358.6040608@oracle.com> <682e35c3-b9a4-5c05-8866-886c0f4d7d49@oracle.com> <59E6423E.7090309@oracle.com> Message-ID: <7afe0bdf-cd57-6395-0ec6-2b24d7c95caf@oracle.com> On 17/10/17 18:47, Jan Lahoda wrote: > On 17.10.2017 16:48, Maurizio Cimadamore wrote: >> Thanks for taking care of this issue and for filing up the followup >> issue. >> >> As for this change, I guess I wished that every generated file had some >> explanation as to how it was obtained, but as discussed offline, this is >> not possible for the various sym.txt files - as they are all generated >> in the same run, and to generate them sometimes you need to use files >> that are not checked in. > > If desired, it would be easy to add the note (and any other note) to > all the files, just seemed cleaner to put it to the "main" one. I agree with your decision. Maurizio > > > Thanks, > ??? Jan > >> >> So, overall, I approve this changeset as is. >> >> Maurizio >> >> >> On 17/10/17 14:19, Jan Lahoda wrote: >>> An updated version of the patch that records in the symbols file the >>> arguments used to generate the -sym.txt files and that sorts the >>> platforms in generate platforms is here: >>> http://cr.openjdk.java.net/~jlahoda/8180744/webrev.01/ >>> >>> Thanks for the comments so far! >>> ??? Jan >>> >>> On 16.10.2017 13:56, Jan Lahoda wrote: >>>> On 16.10.2017 11:52, Maurizio Cimadamore wrote: >>>>> Hi Martin, >>>>> I believe some comments on how files are generated are here: >>>>> >>>>> http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java.html >>>>> >>>>> >>>>> >>>>> >>>>> That said, I agree it would perhaps be a nice improvement (not >>>>> necessary >>>>> for this particular review), to record the launcher/options used to >>>>> generate each file as comments in the file header. >>>> >>>> Sure, I'll work on adding that. I'll probably add that only to the >>>> symbols file. >>>> >>>>> >>>>> Maurizio >>>>> >>>>> >>>>> On 13/10/17 17:49, Martin Buchholz wrote: >>>>>> (drive-by comments) >>>>>> >>>>>> It's great that generated files are marked as such, but: >>>>>> - It's not obvious HOW these files are generated. Actually having >>>>>> the >>>>>> generation command write its own invocation into the generated files >>>>>> might be helpful. >>>>>> - do generated files need a legal notice? >>>> >>>> Is it wrong to include that notice? >>>> >>>>>> +# ########################################################## >>>>>> +# ### THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. ### >>>>>> +# ########################################################## >>>>>> >>>>>> >>>>>> The order of releases is surprising: >>>>>> +generate platforms 8:7:6:9 >>>> >>>> It is true that the order is not significant here, although it is >>>> significant on other places - the .sym.txt files (can and currently >>>> do) >>>> only store full APIs for one version (8 currently), and the rest is >>>> just >>>> diffs between versions. So when reading a .sym.txt files for a >>>> version, >>>> the data for the base version need to be already read. >>>> >>>> Thanks, >>>> ??? Jan >>>> >>>>>> >>>>>> On Fri, Oct 13, 2017 at 5:30 AM, Jan Lahoda >>>>> > wrote: >>>>>> >>>>>> ??? Hi, >>>>>> >>>>>> ??? The patch here adds a support for --release 9 to OpenJDK. This >>>>>> ??? includes adding a snapshot of the JDK 9 APIs. >>>>>> >>>>>> ??? Notes: >>>>>> ??? -several changes to the historical data in make/data/symbols: >>>>>> ??? --java.management.rmi-8.sym.txt contains a few classes that were >>>>>> ??? originally in java.management-8.sym.txt (this change is >>>>>> adjusting >>>>>> ??? the structure to adhere more to the final JDK 9 module layout) >>>>>> ??? --java.annotations.common-* renamed to >>>>>> java.xml.ws.annotation-* to >>>>>> ??? adhere to the final layout >>>>>> ??? --diffing of classes across releases has been improved to avoid >>>>>> ??? some unnecessary class header notices in the historical data >>>>>> ??? --empty files are now not written for the historical data >>>>>> ??? -the (JDK)PlatformProvider.PlatformDescription(Impl) now >>>>>> returns a >>>>>> ??? file manager, instead of a list of paths. This makes the >>>>>> contract >>>>>> ??? cleaner, and allow to handle the ".sig" extension mostly in the >>>>>> ??? file manager instead of ClassFinder. (Due to this change, >>>>>> ??? JDK-8139607: '-release option forces StandardJavaFileManager' is >>>>>> ??? also resolved by this patch, although it is not the primary goal >>>>>> ??? of this patch.) >>>>>> >>>>>> ??? Bug: https://bugs.openjdk.java.net/browse/JDK-8180744 >>>>>> >>>>>> ??? Webrev: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/ >>>>>> >>>>>> >>>>>> ??? I'll send to build-dev as well after the javac changes will >>>>>> look OK. >>>>>> >>>>>> ??? Any feedback is welcome. >>>>>> >>>>>> ??? Thanks, >>>>>> ??????? Jan >>>>>> >>>>>> >>>>> >> From martinrb at google.com Tue Oct 17 19:20:23 2017 From: martinrb at google.com (Martin Buchholz) Date: Tue, 17 Oct 2017 12:20:23 -0700 Subject: RFR: JDK-8189094: Change required boot jdk to JDK 9 In-Reply-To: References: <96cea94b-9945-986b-4c38-1ad7d16b7735@oracle.com> <54583c4a-218f-64f2-7329-019aa402dc70@oracle.com> Message-ID: On Tue, Oct 17, 2017 at 10:10 AM, Alan Bateman wrote: > On 17/10/2017 17:53, Martin Buchholz wrote: > > I tried to figure out how this patch actually works. At first I thought > we were "shading" (renaming all the packages in the source files) but now I > think we're merely renaming the modules by appending ".interim" to the > names. But that looks like cheating to me - we're not allowed to have > multiple modules containing the same packages, but are getting away with it > because the runtime happens to never look at the (unused) original jdk9 > modules? > > The patch uses `--limit-modules` to limit the observability of modules and > prevent the jdk.compiler module in the boot JDK from being resolved. If the > boot JDK were to resolve jdk.compiler (in its own run-time image) and > jdk.compiler.interim on the module path then you would end up with two > modules containing the same classes mapped to the app class loader, can't > do that. > Wow, --limit-modules sure is a good trick. So now we have two possible replacements for the demise of -Xbootclasspath/p: --patch-module --limit-modules combined with renamed replacement modules Looking at the patch I see +INTERIM_LANGTOOLS_ADD_EXPORTS := \ + --add-exports java.base/sun.reflect.annotation=jdk.compiler.interim \ + --add-exports java.base/jdk.internal.util.jar=jdk.jdeps.interim \ + --add-exports java.base/jdk.internal.misc=jdk.jdeps.interim \ + # so the interim compiler is accessing JDK internals - isn't this what we're telling users NOT to do? Especially when this is the internals of the boot jdk - You can't bootstrap jdk10 with any compliant implementation of Java SE 9! The jdk bootstrap process should be setting a good example! -------------- next part -------------- An HTML attachment was scrubbed... URL: From Alan.Bateman at oracle.com Tue Oct 17 20:37:21 2017 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 17 Oct 2017 21:37:21 +0100 Subject: RFR: JDK-8189094: Change required boot jdk to JDK 9 In-Reply-To: References: <96cea94b-9945-986b-4c38-1ad7d16b7735@oracle.com> <54583c4a-218f-64f2-7329-019aa402dc70@oracle.com> Message-ID: On 17/10/2017 20:20, Martin Buchholz wrote: > : > > Wow, --limit-modules sure is a good trick.? So now we have two > possible replacements for the demise of -Xbootclasspath/p: > --patch-module > --limit-modules combined with renamed replacement modules The trick works for the unique scenario of bootstrapping the build but is not general purpose. You can't use it to replace java.base or any module mapped to the boot or platform class loaders for example. > > Looking at the patch I see > +INTERIM_LANGTOOLS_ADD_EXPORTS := \ > + --add-exports java.base/sun.reflect.annotation=jdk.compiler.interim \ > + --add-exports java.base/jdk.internal.util.jar=jdk.jdeps.interim \ > + --add-exports java.base/jdk.internal.misc=jdk.jdeps.interim \ > + # > so the interim compiler is accessing JDK internals - isn't this what > we're telling users NOT to do?? Especially when this is the internals > of the boot jdk - You can't bootstrap jdk10 with any compliant > implementation of Java SE 9!? The jdk bootstrap process should be > setting a good example! We are stuck with the first one due to an oversight in JDK 5 in the way that annotations are serialized. I think the other two should go away once JarFile provides a way to get a versioned stream (there have been a couple of threads about this on core-libs-dev). -Alan -------------- next part -------------- An HTML attachment was scrubbed... URL: From jan.lahoda at oracle.com Wed Oct 18 12:00:16 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Wed, 18 Oct 2017 14:00:16 +0200 Subject: RFR: JDK-8186873: Possible dead code "com.sun.tools.javac.tree.TreeInfo.isAnonymousDiamond()" which was added in 9 Message-ID: <59E74250.5030908@oracle.com> Hi, I'd like to ask for a review for removal of a method that is (as far as I can tell) unused. Bug: https://bugs.openjdk.java.net/browse/JDK-8186873 Webrev: http://cr.openjdk.java.net/~jlahoda/8186873/webrev.00/ Thanks, Jan From maurizio.cimadamore at oracle.com Wed Oct 18 12:23:51 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 18 Oct 2017 13:23:51 +0100 Subject: RFR: JDK-8186873: Possible dead code "com.sun.tools.javac.tree.TreeInfo.isAnonymousDiamond()" which was added in 9 In-Reply-To: <59E74250.5030908@oracle.com> References: <59E74250.5030908@oracle.com> Message-ID: <029220f1-5d5f-1e8b-2f37-535ddcee8c35@oracle.com> Go for it! Maurizio On 18/10/17 13:00, Jan Lahoda wrote: > Hi, > > I'd like to ask for a review for removal of a method that is (as far > as I can tell) unused. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8186873 > Webrev: http://cr.openjdk.java.net/~jlahoda/8186873/webrev.00/ > > Thanks, > ??? Jan From maurizio.cimadamore at oracle.com Wed Oct 18 18:08:30 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 18 Oct 2017 19:08:30 +0100 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> <9b392574-0f51-be26-ceeb-1fa82a9e7dcc@oracle.com> <09308a0b-4d1a-608e-7477-fc5bf142492b@oracle.com> <22818a1e-f2b1-5c4e-e98b-a4c0f9c8e52e@oracle.com> Message-ID: <94446646-43ee-79d2-2a47-742a70a491be@oracle.com> For the records, the fix I'm working on is slightly more general than the one provided here - I think we have to take transitivity into account, it's not enough to look at the bounds of a given input variable and see if it contains any of the output vars. Consider this case: alpha <: List beta <: List gamma <: String In this case you get three inference nodes, one for each inference var - and you have Node(alpha) depends on Node(beta) depends on Node(gamma) so, technically speaking, gamma can influence alpha, but gamma does not appear among alpha's bounds, even after incorporation. I think in certain cases (like in the one described in the bug) incorporation copies some of the bounds from one var to another and that gives you the illusion of transitivity, but that doesn't always happen. See slightly tweaked example at the end of this email So, unless I'm missing something, I think that for the can-influence relation we should piggy back to the inference graph dependencies. Maurizio class T8178150_transitive { ??? public static void test(List> testList, Logger LOGGER) { ??????? testList.forEach(T8178150.bind(cast(LOGGER::info), iterable -> "")); ??? } ??? private static TestProcedure bind(Consumer delegate, Function function) { ??????? return null; ??? } ??? private static C cast(C consumer) { ??????? return consumer; ??? } ??? private static final class TestProcedure implements Consumer { ??????? @Override ??????? public void accept(final X1 t1) { } ??? } } On 15/10/17 12:48, B. Blaser wrote: > On 13 October 2017 at 21:59, Maurizio Cimadamore > wrote: >> Hi, >> I think the affected area is close to this: >> >> https://bugs.openjdk.java.net/browse/JDK-8178150 > Quoting from your JBS comment, here are the two stuck expressions: > > * LOGGER::info - input vars = { C }, output vars = { } > * iterable -> "" - input vars = { T1 }, output vars = { T2 } > > The problem here is that the input var 'C' is influenced by the output > var 'T2' via the bound set of 'C' which doesn't seem to be currently > implemented in javac. > > I wrote a fix, here under, that adds the corresponding dependencies > before computing the acyclic stuck graph in > 'DeferredAttr.pickDeferredNode()'. > > I tried this fix using the "lazy" leaf heuristic (the last one I > suggested) that picks a node to be solved in O(log(n)). > > Note that this fix shouldn't interfere with any leaf solving heuristic > so that it should be possible to choose the best one between: > * the current one (with optimization?) that chooses the smallest subtree > * the "lazy" one that minimizes the effort to choose a leaf in O(log(n)) > * the "conservative" one (from Vicente) that picks the nearest leaf > * or any other heuristic like the "aggressive" one > > Does this fix look reasonable to you? > > Cheers, > Bernard > > > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java > b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java > @@ -29,6 +29,8 @@ > import com.sun.source.tree.NewClassTree; > import com.sun.tools.javac.code.*; > import com.sun.tools.javac.code.Type.StructuralTypeMapping; > +import com.sun.tools.javac.code.Type.UndetVar; > +import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; > import com.sun.tools.javac.code.Types.TypeMapping; > import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext; > import com.sun.tools.javac.comp.Resolve.ResolveError; > @@ -668,10 +670,15 @@ > //the intersection between A's input variable and B's > output variable is non-empty. > for (StuckNode sn1 : nodes) { > for (Type t : sn1.data.deferredStuckPolicy.stuckVars()) { > + UndetVar uv = (UndetVar)inferenceContext.asUndetVar(t); > for (StuckNode sn2 : nodes) { > - if (sn1 != sn2 && > sn2.data.deferredStuckPolicy.depVars().contains(t)) { > + if (sn1 == sn2) continue; > + > + Set depVars = > sn2.data.deferredStuckPolicy.depVars(); > + > + if (depVars.contains(t) || Type.containsAny( > + > uv.getBounds(InferenceBound.values()), List.from(depVars))) > sn1.deps.add(sn2); > - } > } > } > } > > >> for which I have a fix in the work which I will submit for review soon. >> >> After that fix is in, we can consider deeper refactorings in the area. >> >> Cheers >> Maurizio From vicente.romero at oracle.com Wed Oct 18 18:19:31 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Wed, 18 Oct 2017 14:19:31 -0400 Subject: Complexity reduction when choosing the best inference leaf to be solved In-Reply-To: <94446646-43ee-79d2-2a47-742a70a491be@oracle.com> References: <6de4e8e6-7483-0a57-95c5-25ce14edd68c@oracle.com> <5a3f10db-2f27-e2ba-13d8-19500e9be89a@oracle.com> <80ea14f4-b23c-84b6-31f3-e3d02db8232d@oracle.com> <47834c98-6be3-675b-881e-8c3bdc5509c9@oracle.com> <9b392574-0f51-be26-ceeb-1fa82a9e7dcc@oracle.com> <09308a0b-4d1a-608e-7477-fc5bf142492b@oracle.com> <22818a1e-f2b1-5c4e-e98b-a4c0f9c8e52e@oracle.com> <94446646-43ee-79d2-2a47-742a70a491be@oracle.com> Message-ID: On 10/18/2017 02:08 PM, Maurizio Cimadamore wrote: > For the records, the fix I'm working on is slightly more general than > the one provided here - I think we have to take transitivity into > account, it's not enough to look at the bounds of a given input > variable and see if it contains any of the output vars. Consider this > case: > > alpha <: List > beta <: List > gamma <: String > > In this case you get three inference nodes, one for each inference var > - and you have > > Node(alpha) depends on Node(beta) depends on Node(gamma) > > so, technically speaking, gamma can influence alpha, but gamma does > not appear among alpha's bounds, even after incorporation. > > I think in certain cases (like in the one described in the bug) > incorporation copies some of the bounds from one var to another and > that gives you the illusion of transitivity, but that doesn't always > happen. See slightly tweaked example at the end of this email > > So, unless I'm missing something, I think that for the can-influence > relation we should piggy back to the inference graph dependencies. right that's one of the reasons I was thinking about a max flow algorithm, costs were over the table, but as you mentioned later that's probably overkill for this case and a simple graph visit should be enough > > Maurizio Vicente > > > class T8178150_transitive { > > ??? public static void test(List> testList, Logger LOGGER) { > ??????? testList.forEach(T8178150.bind(cast(LOGGER::info), iterable -> > "")); > ??? } > > ??? private static TestProcedure > bind(Consumer delegate, Function function) { > ??????? return null; > ??? } > > ??? private static C cast(C consumer) { > ??????? return consumer; > ??? } > > ??? private static final class TestProcedure implements > Consumer { > ??????? @Override > ??????? public void accept(final X1 t1) { } > ??? } > } > > > On 15/10/17 12:48, B. Blaser wrote: >> On 13 October 2017 at 21:59, Maurizio Cimadamore >> wrote: >>> Hi, >>> I think the affected area is close to this: >>> >>> https://bugs.openjdk.java.net/browse/JDK-8178150 >> Quoting from your JBS comment, here are the two stuck expressions: >> >> * LOGGER::info - input vars = { C }, output vars = { } >> * iterable -> "" - input vars = { T1 }, output vars = { T2 } >> >> The problem here is that the input var 'C' is influenced by the output >> var 'T2' via the bound set of 'C' which doesn't seem to be currently >> implemented in javac. >> >> I wrote a fix, here under, that adds the corresponding dependencies >> before computing the acyclic stuck graph in >> 'DeferredAttr.pickDeferredNode()'. >> >> I tried this fix using the "lazy" leaf heuristic (the last one I >> suggested) that picks a node to be solved in O(log(n)). >> >> Note that this fix shouldn't interfere with any leaf solving heuristic >> so that it should be possible to choose the best one between: >> * the current one (with optimization?) that chooses the smallest subtree >> * the "lazy" one that minimizes the effort to choose a leaf in O(log(n)) >> * the "conservative" one (from Vicente) that picks the nearest leaf >> * or any other heuristic like the "aggressive" one >> >> Does this fix look reasonable to you? >> >> Cheers, >> Bernard >> >> >> diff --git >> a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java >> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java >> >> --- >> a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java >> +++ >> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java >> @@ -29,6 +29,8 @@ >> ? import com.sun.source.tree.NewClassTree; >> ? import com.sun.tools.javac.code.*; >> ? import com.sun.tools.javac.code.Type.StructuralTypeMapping; >> +import com.sun.tools.javac.code.Type.UndetVar; >> +import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; >> ? import com.sun.tools.javac.code.Types.TypeMapping; >> ? import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext; >> ? import com.sun.tools.javac.comp.Resolve.ResolveError; >> @@ -668,10 +670,15 @@ >> ????????????? //the intersection between A's input variable and B's >> output variable is non-empty. >> ????????????? for (StuckNode sn1 : nodes) { >> ????????????????? for (Type t : >> sn1.data.deferredStuckPolicy.stuckVars()) { >> +??????????????????? UndetVar uv = >> (UndetVar)inferenceContext.asUndetVar(t); >> ????????????????????? for (StuckNode sn2 : nodes) { >> -??????????????????????? if (sn1 != sn2 && >> sn2.data.deferredStuckPolicy.depVars().contains(t)) { >> +??????????????????????? if (sn1 == sn2) continue; >> + >> +??????????????????????? Set depVars = >> sn2.data.deferredStuckPolicy.depVars(); >> + >> +??????????????????????? if (depVars.contains(t) || Type.containsAny( >> + >> uv.getBounds(InferenceBound.values()), List.from(depVars))) >> ????????????????????????????? sn1.deps.add(sn2); >> -??????????????????????? } >> ????????????????????? } >> ????????????????? } >> ????????????? } >> >> >>> for which I have a fix in the work which I will submit for review soon. >>> >>> After that fix is in, we can consider deeper refactorings in the area. >>> >>> Cheers >>> Maurizio > From jonathan.gibbons at oracle.com Wed Oct 18 20:13:50 2017 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 18 Oct 2017 13:13:50 -0700 Subject: RFR: JDK-8188035: JavaFileManager.listLocationsForModules does not always reflect values set through tandardJavaFileManager.setLocationForModule. In-Reply-To: <59E0AA6C.6000100@oracle.com> References: <59E0AA6C.6000100@oracle.com> Message-ID: <59E7B5FE.8060404@oracle.com> Looks good to me. -- Jon On 10/13/2017 04:58 AM, Jan Lahoda wrote: > Hi, > > When StandardJavaFileManager.setLocationForModule is used, and then > JavaFileManager.listLocationsForModules is used, then, for some > locations, the listed locations won't include the changes through > setLocationForModule. The proposal here is to prepend the > paths/locations from setLocationForModule invocations to the output of > listLocationsForModules. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8188035 > Webrev: http://cr.openjdk.java.net/~jlahoda/8188035/webrev.00/ > > Jan From maurizio.cimadamore at oracle.com Wed Oct 18 20:15:56 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 18 Oct 2017 21:15:56 +0100 Subject: RFR 8178150: Regression in logic for handling inference stuck constraints Message-ID: <7ac44223-93da-f4d0-fc20-293b8db99707@oracle.com> Hi, this issue has already been discussed in [1]. The issue has to do with the fact that logic for picking a deferred node to unstick ignores the can-influence relationship (aka inference graph dependencies). The implemented code is not optimized (almost deliberately); I wanted the code to follow the spec more or less cleanly. While I'm open to small improvements, I would please ask to focus on correctness for the time being since (i) this code is not an hot execution path and (ii) other performance improvements in this area will follow, see [2]. http://cr.openjdk.java.net/~mcimadamore/8178150/ [1] - http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011192.html [2] - http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011126.html Cheers Maurizio From jonathan.gibbons at oracle.com Wed Oct 18 21:07:36 2017 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 18 Oct 2017 14:07:36 -0700 Subject: RFR: JDK-8180744: Update ct.sym for JDK 10 In-Reply-To: <59E0B1DE.3000701@oracle.com> References: <59E0B1DE.3000701@oracle.com> Message-ID: <59E7C298.1060803@oracle.com> On a pragmatic level, I note that there are some excessively long lines here. I know we don't rigidly adhere to an 80 character limit, but some of the lines are perversely long, and will be tedious to review in followup webrevs. A quick grep of the changeset shows 67 lines over 100 characters and 36 over 120. (This is not counting the long lines in the generated files.) This webrev seems to include changes for another review, 8188035. There are distinct blobs of work here: for example, the javac work for JDKPlatformProvider seems logically distinct from the changes for CreateSymbols. It seems a shame the work could not have been separated into distinct changesets. Generally, we need more documentation on the overall process for creating these files, including details on the tool(s), and the various file and file formats involved. It feels wrong to export javac internals to jdeps. Maybe this should (eventually) evolve into a more supported service API? -- Jon On 10/13/2017 05:30 AM, Jan Lahoda wrote: > Hi, > > The patch here adds a support for --release 9 to OpenJDK. This > includes adding a snapshot of the JDK 9 APIs. > > Notes: > -several changes to the historical data in make/data/symbols: > --java.management.rmi-8.sym.txt contains a few classes that were > originally in java.management-8.sym.txt (this change is adjusting the > structure to adhere more to the final JDK 9 module layout) > --java.annotations.common-* renamed to java.xml.ws.annotation-* to > adhere to the final layout > --diffing of classes across releases has been improved to avoid some > unnecessary class header notices in the historical data > --empty files are now not written for the historical data > -the (JDK)PlatformProvider.PlatformDescription(Impl) now returns a > file manager, instead of a list of paths. This makes the contract > cleaner, and allow to handle the ".sig" extension mostly in the file > manager instead of ClassFinder. (Due to this change, JDK-8139607: > '-release option forces StandardJavaFileManager' is also resolved by > this patch, although it is not the primary goal of this patch.) > > Bug: https://bugs.openjdk.java.net/browse/JDK-8180744 > Webrev: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/ > > I'll send to build-dev as well after the javac changes will look OK. > > Any feedback is welcome. > > Thanks, > Jan From vicente.romero at oracle.com Wed Oct 18 23:57:27 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Wed, 18 Oct 2017 19:57:27 -0400 Subject: RFR 8178150: Regression in logic for handling inference stuck constraints In-Reply-To: <7ac44223-93da-f4d0-fc20-293b8db99707@oracle.com> References: <7ac44223-93da-f4d0-fc20-293b8db99707@oracle.com> Message-ID: <461326c8-f7fe-6f11-95e9-5da6c3ff7fa9@oracle.com> Hi Maurizio, I'm not sure about the correctness or the objective of the closure() method. The termination condition seems to be: stop as soon as you find a cycle in the graph, at least this is my reading. But for some graphs this could imply finding a subset of the closure not the whole of it. It seems to me like implementing a graph traversal method should be what it is wanted here. Unless there is something I'm missing. Also in the same method the javadoc could have stall comments as it says that a kind of dependencies is given but there is no argument passed to the method. Thanks, Vicente On 10/18/2017 04:15 PM, Maurizio Cimadamore wrote: > Hi, > this issue has already been discussed in [1]. > > The issue has to do with the fact that logic for picking a deferred > node to unstick ignores the can-influence relationship (aka inference > graph dependencies). > > The implemented code is not optimized (almost deliberately); I wanted > the code to follow the spec more or less cleanly. While I'm open to > small improvements, I would please ask to focus on correctness for the > time being since (i) this code is not an hot execution path and (ii) > other performance improvements in this area will follow, see [2]. > > http://cr.openjdk.java.net/~mcimadamore/8178150/ > > [1] - > http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011192.html > [2] - > http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011126.html > > Cheers > Maurizio > From maurizio.cimadamore at oracle.com Thu Oct 19 08:38:53 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 19 Oct 2017 09:38:53 +0100 Subject: RFR 8178150: Regression in logic for handling inference stuck constraints In-Reply-To: <461326c8-f7fe-6f11-95e9-5da6c3ff7fa9@oracle.com> References: <7ac44223-93da-f4d0-fc20-293b8db99707@oracle.com> <461326c8-f7fe-6f11-95e9-5da6c3ff7fa9@oracle.com> Message-ID: I think you are right - this method was there when I first wrote the patch but then got removed. I resurrected it for the purpose of this patch, but it seems like it's not doing what we need. Maurizio On 19/10/17 00:57, Vicente Romero wrote: > Hi Maurizio, > > I'm not sure about the correctness or the objective of the closure() > method. The termination condition seems to be: stop as soon as you > find a cycle in the graph, at least this is my reading. But for some > graphs this could imply finding a subset of the closure not the whole > of it. It seems to me like implementing a graph traversal method > should be what it is wanted here. Unless there is something I'm missing. > > Also in the same method the javadoc could have stall comments as it > says that a kind of dependencies is given but there is no argument > passed to the method. > > Thanks, > Vicente > > On 10/18/2017 04:15 PM, Maurizio Cimadamore wrote: >> Hi, >> this issue has already been discussed in [1]. >> >> The issue has to do with the fact that logic for picking a deferred >> node to unstick ignores the can-influence relationship (aka inference >> graph dependencies). >> >> The implemented code is not optimized (almost deliberately); I wanted >> the code to follow the spec more or less cleanly. While I'm open to >> small improvements, I would please ask to focus on correctness for >> the time being since (i) this code is not an hot execution path and >> (ii) other performance improvements in this area will follow, see [2]. >> >> http://cr.openjdk.java.net/~mcimadamore/8178150/ >> >> [1] - >> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011192.html >> [2] - >> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011126.html >> >> Cheers >> Maurizio >> > From maurizio.cimadamore at oracle.com Thu Oct 19 09:41:08 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 19 Oct 2017 10:41:08 +0100 Subject: RFR 8178150: Regression in logic for handling inference stuck constraints In-Reply-To: References: <7ac44223-93da-f4d0-fc20-293b8db99707@oracle.com> <461326c8-f7fe-6f11-95e9-5da6c3ff7fa9@oracle.com> Message-ID: Updated webrev http://cr.openjdk.java.net/~mcimadamore/8178150_v2/ Maurizio On 19/10/17 09:38, Maurizio Cimadamore wrote: > I think you are right - this method was there when I first wrote the > patch but then got removed. I resurrected it for the purpose of this > patch, but it seems like it's not doing what we need. > > Maurizio > > > On 19/10/17 00:57, Vicente Romero wrote: >> Hi Maurizio, >> >> I'm not sure about the correctness or the objective of the closure() >> method. The termination condition seems to be: stop as soon as you >> find a cycle in the graph, at least this is my reading. But for some >> graphs this could imply finding a subset of the closure not the whole >> of it. It seems to me like implementing a graph traversal method >> should be what it is wanted here. Unless there is something I'm missing. >> >> Also in the same method the javadoc could have stall comments as it >> says that a kind of dependencies is given but there is no argument >> passed to the method. >> >> Thanks, >> Vicente >> >> On 10/18/2017 04:15 PM, Maurizio Cimadamore wrote: >>> Hi, >>> this issue has already been discussed in [1]. >>> >>> The issue has to do with the fact that logic for picking a deferred >>> node to unstick ignores the can-influence relationship (aka >>> inference graph dependencies). >>> >>> The implemented code is not optimized (almost deliberately); I >>> wanted the code to follow the spec more or less cleanly. While I'm >>> open to small improvements, I would please ask to focus on >>> correctness for the time being since (i) this code is not an hot >>> execution path and (ii) other performance improvements in this area >>> will follow, see [2]. >>> >>> http://cr.openjdk.java.net/~mcimadamore/8178150/ >>> >>> [1] - >>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011192.html >>> [2] - >>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011126.html >>> >>> Cheers >>> Maurizio >>> >> > From andrej.golovnin at gmail.com Thu Oct 19 11:04:44 2017 From: andrej.golovnin at gmail.com (Andrej Golovnin) Date: Thu, 19 Oct 2017 13:04:44 +0200 Subject: RFR 8178150: Regression in logic for handling inference stuck constraints In-Reply-To: References: <7ac44223-93da-f4d0-fc20-293b8db99707@oracle.com> <461326c8-f7fe-6f11-95e9-5da6c3ff7fa9@oracle.com> Message-ID: Hi Maurizio, in src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java 1768 deps.stream().forEach(d -> d.closureInternal(closure)); This can be replaced by a simple for-each loop. And if you really don't want to write a for-each loop, then you can can use the forEach-method defined in the Iterable interface: deps.forEach(d -> d.closureInternal(closure)); and avoid creation of a stream. Best regards Andrej Golovnin On Thu, Oct 19, 2017 at 11:41 AM, Maurizio Cimadamore wrote: > Updated webrev > > http://cr.openjdk.java.net/~mcimadamore/8178150_v2/ > > Maurizio > > > On 19/10/17 09:38, Maurizio Cimadamore wrote: >> >> I think you are right - this method was there when I first wrote the patch >> but then got removed. I resurrected it for the purpose of this patch, but it >> seems like it's not doing what we need. >> >> Maurizio >> >> >> On 19/10/17 00:57, Vicente Romero wrote: >>> >>> Hi Maurizio, >>> >>> I'm not sure about the correctness or the objective of the closure() >>> method. The termination condition seems to be: stop as soon as you find a >>> cycle in the graph, at least this is my reading. But for some graphs this >>> could imply finding a subset of the closure not the whole of it. It seems to >>> me like implementing a graph traversal method should be what it is wanted >>> here. Unless there is something I'm missing. >>> >>> Also in the same method the javadoc could have stall comments as it says >>> that a kind of dependencies is given but there is no argument passed to the >>> method. >>> >>> Thanks, >>> Vicente >>> >>> On 10/18/2017 04:15 PM, Maurizio Cimadamore wrote: >>>> >>>> Hi, >>>> this issue has already been discussed in [1]. >>>> >>>> The issue has to do with the fact that logic for picking a deferred node >>>> to unstick ignores the can-influence relationship (aka inference graph >>>> dependencies). >>>> >>>> The implemented code is not optimized (almost deliberately); I wanted >>>> the code to follow the spec more or less cleanly. While I'm open to small >>>> improvements, I would please ask to focus on correctness for the time being >>>> since (i) this code is not an hot execution path and (ii) other performance >>>> improvements in this area will follow, see [2]. >>>> >>>> http://cr.openjdk.java.net/~mcimadamore/8178150/ >>>> >>>> [1] - >>>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011192.html >>>> [2] - >>>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011126.html >>>> >>>> Cheers >>>> Maurizio >>>> >>> >> > From maurizio.cimadamore at oracle.com Thu Oct 19 11:08:49 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 19 Oct 2017 12:08:49 +0100 Subject: RFR 8178150: Regression in logic for handling inference stuck constraints In-Reply-To: References: <7ac44223-93da-f4d0-fc20-293b8db99707@oracle.com> <461326c8-f7fe-6f11-95e9-5da6c3ff7fa9@oracle.com> Message-ID: Thanks - I'll address this (and maybe other comments). You are right that a simple for loop is probably more readable here (and better as it avoids stream creation). I will upload an updated webrev once I accumulate enough comments :-) Maurizio On 19/10/17 12:04, Andrej Golovnin wrote: > Hi Maurizio, > > in src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java > > 1768 deps.stream().forEach(d -> > d.closureInternal(closure)); > > This can be replaced by a simple for-each loop. And if you really > don't want to write a for-each loop, then you can can use the > forEach-method defined in the Iterable interface: > > deps.forEach(d -> d.closureInternal(closure)); > > and avoid creation of a stream. > > Best regards > Andrej Golovnin > > On Thu, Oct 19, 2017 at 11:41 AM, Maurizio Cimadamore > wrote: >> Updated webrev >> >> http://cr.openjdk.java.net/~mcimadamore/8178150_v2/ >> >> Maurizio >> >> >> On 19/10/17 09:38, Maurizio Cimadamore wrote: >>> I think you are right - this method was there when I first wrote the patch >>> but then got removed. I resurrected it for the purpose of this patch, but it >>> seems like it's not doing what we need. >>> >>> Maurizio >>> >>> >>> On 19/10/17 00:57, Vicente Romero wrote: >>>> Hi Maurizio, >>>> >>>> I'm not sure about the correctness or the objective of the closure() >>>> method. The termination condition seems to be: stop as soon as you find a >>>> cycle in the graph, at least this is my reading. But for some graphs this >>>> could imply finding a subset of the closure not the whole of it. It seems to >>>> me like implementing a graph traversal method should be what it is wanted >>>> here. Unless there is something I'm missing. >>>> >>>> Also in the same method the javadoc could have stall comments as it says >>>> that a kind of dependencies is given but there is no argument passed to the >>>> method. >>>> >>>> Thanks, >>>> Vicente >>>> >>>> On 10/18/2017 04:15 PM, Maurizio Cimadamore wrote: >>>>> Hi, >>>>> this issue has already been discussed in [1]. >>>>> >>>>> The issue has to do with the fact that logic for picking a deferred node >>>>> to unstick ignores the can-influence relationship (aka inference graph >>>>> dependencies). >>>>> >>>>> The implemented code is not optimized (almost deliberately); I wanted >>>>> the code to follow the spec more or less cleanly. While I'm open to small >>>>> improvements, I would please ask to focus on correctness for the time being >>>>> since (i) this code is not an hot execution path and (ii) other performance >>>>> improvements in this area will follow, see [2]. >>>>> >>>>> http://cr.openjdk.java.net/~mcimadamore/8178150/ >>>>> >>>>> [1] - >>>>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011192.html >>>>> [2] - >>>>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011126.html >>>>> >>>>> Cheers >>>>> Maurizio >>>>> From maurizio.cimadamore at oracle.com Thu Oct 19 11:12:41 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 19 Oct 2017 12:12:41 +0100 Subject: RFR 8178150: Regression in logic for handling inference stuck constraints In-Reply-To: References: <7ac44223-93da-f4d0-fc20-293b8db99707@oracle.com> <461326c8-f7fe-6f11-95e9-5da6c3ff7fa9@oracle.com> Message-ID: Btw - a possible low hanging fruit performance wise here is to cache the closure of a node in the node itself. But this adds complexity as there are methods to update dependencies every time the inference graph is updated. So the cache would have to be cleared, at the very least in the Node::graphChanged method. Since, as mentioned in the original message, it is likely that we will address residual performance concerns in a followup issue, I decided to leave this alone - in case we want to come up with a more holistic optimization. Cheers Maurizio On 19/10/17 12:08, Maurizio Cimadamore wrote: > Thanks - I'll address this (and maybe other comments). You are right > that a simple for loop is probably more readable here (and better as > it avoids stream creation). > > I will upload an updated webrev once I accumulate enough comments :-) > > Maurizio > > > On 19/10/17 12:04, Andrej Golovnin wrote: >> Hi Maurizio, >> >> in src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >> >> 1768???????????????????????? deps.stream().forEach(d -> >> d.closureInternal(closure)); >> >> This can be replaced by a simple for-each loop. And if you really >> don't want to write a for-each loop, then you can can use the >> forEach-method defined in the Iterable interface: >> >> deps.forEach(d -> d.closureInternal(closure)); >> >> and avoid creation of a stream. >> >> Best regards >> Andrej Golovnin >> >> On Thu, Oct 19, 2017 at 11:41 AM, Maurizio Cimadamore >> wrote: >>> Updated webrev >>> >>> http://cr.openjdk.java.net/~mcimadamore/8178150_v2/ >>> >>> Maurizio >>> >>> >>> On 19/10/17 09:38, Maurizio Cimadamore wrote: >>>> I think you are right - this method was there when I first wrote >>>> the patch >>>> but then got removed. I resurrected it for the purpose of this >>>> patch, but it >>>> seems like it's not doing what we need. >>>> >>>> Maurizio >>>> >>>> >>>> On 19/10/17 00:57, Vicente Romero wrote: >>>>> Hi Maurizio, >>>>> >>>>> I'm not sure about the correctness or the objective of the closure() >>>>> method. The termination condition seems to be: stop as soon as you >>>>> find a >>>>> cycle in the graph, at least this is my reading. But for some >>>>> graphs this >>>>> could imply finding a subset of the closure not the whole of it. >>>>> It seems to >>>>> me like implementing a graph traversal method should be what it is >>>>> wanted >>>>> here. Unless there is something I'm missing. >>>>> >>>>> Also in the same method the javadoc could have stall comments as >>>>> it says >>>>> that a kind of dependencies is given but there is no argument >>>>> passed to the >>>>> method. >>>>> >>>>> Thanks, >>>>> Vicente >>>>> >>>>> On 10/18/2017 04:15 PM, Maurizio Cimadamore wrote: >>>>>> Hi, >>>>>> this issue has already been discussed in [1]. >>>>>> >>>>>> The issue has to do with the fact that logic for picking a >>>>>> deferred node >>>>>> to unstick ignores the can-influence relationship (aka inference >>>>>> graph >>>>>> dependencies). >>>>>> >>>>>> The implemented code is not optimized (almost deliberately); I >>>>>> wanted >>>>>> the code to follow the spec more or less cleanly. While I'm open >>>>>> to small >>>>>> improvements, I would please ask to focus on correctness for the >>>>>> time being >>>>>> since (i) this code is not an hot execution path and (ii) other >>>>>> performance >>>>>> improvements in this area will follow, see [2]. >>>>>> >>>>>> http://cr.openjdk.java.net/~mcimadamore/8178150/ >>>>>> >>>>>> [1] - >>>>>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011192.html >>>>>> >>>>>> [2] - >>>>>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011126.html >>>>>> >>>>>> >>>>>> Cheers >>>>>> Maurizio >>>>>> > From bsrbnd at gmail.com Thu Oct 19 13:45:53 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Thu, 19 Oct 2017 15:45:53 +0200 Subject: RFR 8178150: Regression in logic for handling inference stuck constraints In-Reply-To: References: <7ac44223-93da-f4d0-fc20-293b8db99707@oracle.com> <461326c8-f7fe-6f11-95e9-5da6c3ff7fa9@oracle.com> Message-ID: Hi, On 19 October 2017 at 13:12, Maurizio Cimadamore wrote: > Btw - a possible low hanging fruit performance wise here is to cache the > closure of a node in the node itself. But this adds complexity as there are > methods to update dependencies every time the inference graph is updated. So > the cache would have to be cleared, at the very least in the > Node::graphChanged method. > > Since, as mentioned in the original message, it is likely that we will > address residual performance concerns in a followup issue, I decided to > leave this alone - in case we want to come up with a more holistic > optimization. Looks good to me too, I also agree that your general method is safer. Note it's a bit strange that transitive nodes sometimes appear in the bound set, but not always, as you wrote in [1]. I also noticed you used 'graph.findNode(inputVar)' which will hopefully be optimized along with some other issues like 'stack.contains()' in 'Tarjan.findSCC()' which currently performs a linear scan of the stack ;-) Thanks! Bernard [1] http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011215.html > Cheers > Maurizio From erik.joelsson at oracle.com Thu Oct 19 13:47:47 2017 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Thu, 19 Oct 2017 15:47:47 +0200 Subject: RFR: JDK-8182285: Speeding up incremental build by hashing module APIs Message-ID: <373705b4-c9a5-0eab-11f8-28895442e5c6@oracle.com> This patch introduces a new Javac plugin as a build tool, written by Jan Lahoda. The plugin creates a hash of the public API of what is being compiled and puts it in a file. The file is only updated if there is a difference compared to the current contents of the file. I have provided the integration with the build system. The benefit of this is that we finally get some reasonable incremental build performance between modules. If you make a change to a class in java.base that doesn't touch the public API, the build will no longer recompile all other modules. Webrev: http://cr.openjdk.java.net/~erikj/8182285/webrev.02/ Bug: https://bugs.openjdk.java.net/browse/JDK-8182285 /Erik From magnus.ihse.bursie at oracle.com Thu Oct 19 14:37:25 2017 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Thu, 19 Oct 2017 16:37:25 +0200 Subject: RFR: JDK-8182285: Speeding up incremental build by hashing module APIs In-Reply-To: <373705b4-c9a5-0eab-11f8-28895442e5c6@oracle.com> References: <373705b4-c9a5-0eab-11f8-28895442e5c6@oracle.com> Message-ID: <96ef3001-a236-5772-3bcb-4e00b909a6ce@oracle.com> On 2017-10-19 15:47, Erik Joelsson wrote: > This patch introduces a new Javac plugin as a build tool, written by > Jan Lahoda. The plugin creates a hash of the public API of what is > being compiled and puts it in a file. The file is only updated if > there is a difference compared to the current contents of the file. I > have provided the integration with the build system. > > The benefit of this is that we finally get some reasonable incremental > build performance between modules. If you make a change to a class in > java.base that doesn't touch the public API, the build will no longer > recompile all other modules. > > Webrev: http://cr.openjdk.java.net/~erikj/8182285/webrev.02/ Looks good to me. Nice to finally see this happening! :-) /Magnus > > Bug: https://bugs.openjdk.java.net/browse/JDK-8182285 > > /Erik > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsrbnd at gmail.com Thu Oct 19 17:37:26 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Thu, 19 Oct 2017 19:37:26 +0200 Subject: Incoherent invocation type inference? In-Reply-To: <5f88a054-d80c-df3d-e76f-a78ec3c9a13e@oracle.com> References: <5e5ae04c-e442-7925-0fae-8544376ffd54@oracle.com> <1197680659.2383392.1484480737965.JavaMail.zimbra@u-pem.fr> <43f3f78e-73ef-e54d-91dc-47f2b56b2e8b@oracle.com> <7d0167b4-6085-9256-7073-61e9bf9ddfdb@oracle.com> <42944d98-ef8d-5f29-32aa-cac5581f96f5@oracle.com> <6ab2395d-ffd3-8437-2c57-a93d357e3c15@oracle.com> <5f88a054-d80c-df3d-e76f-a78ec3c9a13e@oracle.com> Message-ID: On 28 August 2017 at 14:18, Maurizio Cimadamore wrote: > > > On 25/08/17 08:23, B. Blaser wrote: >> >> Maurizio, >> >> On 22 January 2017 at 17:26, B. Blaser wrote: >>> >>> Hi, >>> >>> 2017-01-19 18:22 GMT+01:00 Maurizio Cimadamore >>> : >>>> >>>> Not sure about your proposed patch. >>>> >>>> To me the warning should be a property of the method declaration, not of >>>> the >>>> specific inference. >>>> >>>> If a method returns a naked type-variable which is not mentioned >>>> anywhere in >>>> the method parameter types -> Lint warning (not an unchecked warning - >>>> just >>>> an optional Lint one - category TBD). >>>> >>>> It's true that, by looking at the callsite, you can also warn for >>>> clients >>>> passing 'null' arguments, but the extra benefit is not worth the extra >>>> complexity IMHO. And, I think this is a problem of bad API, not one of >>>> bad >>>> clients. A well-designed API should not have any methods that match the >>>> criteria stated above - as their behavior would ultimately be at the >>>> client's mercy. >>>> >>>> Maurizio >>> >>> Here under is a suggestion for the implementation of the rule you >>> stated above (Attr.visitMethodDef(), upon rev. b6960e2da008). >>> >>> I kept a check on the callsite for further evaluation (in >>> Attr.checkMethod() to be more general). I think both are >>> complementary. >>> >>> " T[] List.toArray(T[])" is a good example of a well designed API. >>> But an invocation of the form "a = l.toArray(null)" is dangerous due >>> to the obvious API's lack of control over T and might be warned. >>> >>> For the Lint category, I suggest to name it "generic" and to use it >>> for warnings about type variables. Other checks like the "final" one >>> could fall into the same category. >>> >>> Does this look better? >> >> Should I create a JBS issue for that? > > Yes, please, go ahead. I've seen this popping out frequently enough that I > think it deserves some closure. Done: https://bugs.openjdk.java.net/browse/JDK-8189684 Cheers, Bernard > Maurizio > >> >> Bernard >> >>> Thanks, >>> Bernard From bsrbnd at gmail.com Thu Oct 19 17:44:27 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Thu, 19 Oct 2017 19:44:27 +0200 Subject: Choosing the best inference leaf is non-deterministic In-Reply-To: References: <1b7b6fc8-6604-f300-93b7-1d61b83eb7d7@oracle.com> Message-ID: I created the following JBS issue for that: https://bugs.openjdk.java.net/browse/JDK-8189683 Cheers, Bernard On 10 October 2017 at 22:43, B. Blaser wrote: > On 10 October 2017 at 11:45, Maurizio Cimadamore > wrote: >> >> >> On 10/10/17 10:26, B. Blaser wrote: >>> >>> This is stable enough until we find a failing example;-) >>> >>> If you run twice the second example given in [1], you'll see that the >>> nodes aren't always solved in the same order... >>> >>> While there isn't any problem in this case, this non-deterministic >>> behavior is definitively unsafe, which is probably due to the fact >>> that the default 'hashCode()' might depend on the reference (memory >>> location), see [3]. >>> >>> The 'TreeSet' I suggested yesterday isn't probably a good solution >>> neither as it uses the comparison method defined to compute the >>> acyclic graph. >>> >>> So, something derived from 'LinkedHashMap' would be better to preserve >>> the insertion order and to access the elements in O(1). Or, at least, >>> overriding 'hashCode()' with something more stable while not >>> preserving the insertion order (a sequential index assigned to each >>> node when the inference graph is created, for example). >>> >>> What do you think? >> >> I think we need to understand the source of non-determinism. If that is >> simply caused by nodes not having stable equals and hashcode, we might as >> well add those methods, and make the problem go away w/o any extra memory >> cost. Iteration order could still be non-deterministic in multi-threaded >> scenario, but that's not a concern with this part of javac. >> >> Or, we could look into a more robust data structure - typically >> LinkedHashSet is used in such cases, which is probably more robust longer >> term. > > I think 'LinkedHashSet' is exactly what we need here, as next. > > Thanks! > Bernard > > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java > b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java > @@ -59,6 +59,7 @@ > import java.util.EnumSet; > import java.util.HashMap; > import java.util.HashSet; > +import java.util.LinkedHashSet; > import java.util.Map; > import java.util.Optional; > import java.util.Properties; > @@ -1705,11 +1706,11 @@ > class Node extends > GraphUtils.TarjanNode, Node> implements > DottableNode, Node> { > > /** node dependencies */ > - Set deps; > + LinkedHashSet deps; > > Node(Type ivar) { > super(ListBuffer.of(ivar)); > - this.deps = new HashSet<>(); > + this.deps = new LinkedHashSet<>(); > } > > @Override > @@ -1780,7 +1781,7 @@ > addDependencies(n.deps); > } > //update deps > - Set deps2 = new HashSet<>(); > + LinkedHashSet deps2 = new LinkedHashSet<>(); > for (Node d : deps) { > if (data.contains(d.data.first())) { > deps2.add(this); > > >> Or we could do both :-) >> >> Maurizio >> >>> >>> Bernard >>> >>> [3] >>> https://docs.oracle.com/javase/9/docs/api/java/lang/Object.html#hashCode-- From jan.lahoda at oracle.com Thu Oct 19 17:46:10 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Thu, 19 Oct 2017 19:46:10 +0200 Subject: RFR: JDK-8180744: Update ct.sym for JDK 10 In-Reply-To: <59E7C298.1060803@oracle.com> References: <59E0B1DE.3000701@oracle.com> <59E7C298.1060803@oracle.com> Message-ID: <59E8E4E2.5060208@oracle.com> Hi, Thanks for the comments. I've split the work into three parts: -the change to PlatformProvider to return a file manager: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.02/improve-platformprovider/ -the changes to support --release 9 (modular environment): http://cr.openjdk.java.net/~jlahoda/8180744/webrev.02/release-infrastructure/ -the update to the historical data: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.02/release-data/ I was tried to limit the lengths of the lines. On 18.10.2017 23:07, Jonathan Gibbons wrote: > On a pragmatic level, I note that there are some excessively long lines > here. I know we don't rigidly adhere to an 80 character limit, but some > of the lines are perversely long, and will be tedious to review in > followup webrevs. A quick grep of the changeset shows 67 lines over > 100 characters and 36 over 120. (This is not counting the long lines in > the generated files.) > > This webrev seems to include changes for another review, 8188035. > > There are distinct blobs of work here: for example, the javac work for > JDKPlatformProvider seems logically distinct from the changes for > CreateSymbols. It seems a shame the work could not have been separated > into distinct changesets. > > Generally, we need more documentation on the overall process for > creating these files, including details on the tool(s), and the various > file and file formats involved. > > It feels wrong to export javac internals to jdeps. Maybe this should > (eventually) evolve into a more supported service API? There are other jdk.compiler packages already exported to jdk.jdeps. And the current implementation of jdeprscan is already depending on details of --release implementation in javac (that the improve-platformprovider patch is trying to improve and breaks jdeprscan, so this is an attempt to make it work again). Jan > > -- Jon > > > On 10/13/2017 05:30 AM, Jan Lahoda wrote: >> Hi, >> >> The patch here adds a support for --release 9 to OpenJDK. This >> includes adding a snapshot of the JDK 9 APIs. >> >> Notes: >> -several changes to the historical data in make/data/symbols: >> --java.management.rmi-8.sym.txt contains a few classes that were >> originally in java.management-8.sym.txt (this change is adjusting the >> structure to adhere more to the final JDK 9 module layout) >> --java.annotations.common-* renamed to java.xml.ws.annotation-* to >> adhere to the final layout >> --diffing of classes across releases has been improved to avoid some >> unnecessary class header notices in the historical data >> --empty files are now not written for the historical data >> -the (JDK)PlatformProvider.PlatformDescription(Impl) now returns a >> file manager, instead of a list of paths. This makes the contract >> cleaner, and allow to handle the ".sig" extension mostly in the file >> manager instead of ClassFinder. (Due to this change, JDK-8139607: >> '-release option forces StandardJavaFileManager' is also resolved by >> this patch, although it is not the primary goal of this patch.) >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8180744 >> Webrev: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/ >> >> I'll send to build-dev as well after the javac changes will look OK. >> >> Any feedback is welcome. >> >> Thanks, >> Jan > From cushon at google.com Thu Oct 19 17:55:29 2017 From: cushon at google.com (Liam Miller-Cushon) Date: Thu, 19 Oct 2017 10:55:29 -0700 Subject: RFR 8177486: incorrect handling of mandated parameter names in MethodParameters attributes In-Reply-To: References: Message-ID: Hi, would anyone be willing to review this patch? On Thu, Mar 23, 2017 at 4:35 PM, Liam Miller-Cushon wrote: > Hello, > > Please review this fix for JDK-8177486, which is a class reading bug that > affects MethodParameters attributes with mandated parameters. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8177486 > Webrev: http://cr.openjdk.java.net/~cushon/8177486/webrev.00/ > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cushon at google.com Thu Oct 19 17:57:44 2017 From: cushon at google.com (Liam Miller-Cushon) Date: Thu, 19 Oct 2017 10:57:44 -0700 Subject: RFR 8187247: canonical import check compares classes by simple name In-Reply-To: References: <59C3DE19.4080107@oracle.com> Message-ID: Friendly ping. Is this blocked on anything? On Mon, Sep 25, 2017 at 2:25 PM, Liam Miller-Cushon wrote: > Hi Jan, > > Thanks for the review. I moved the test to a directory. > > Updated webrev: http://cr.openjdk.java.net/~cushon/8187247/webrev.01/ > The formatted patch is attached. > > On Thu, Sep 21, 2017 at 8:43 AM, Jan Lahoda wrote: > >> Hi Liam, >> >> I apologize for belated answer. Seems OK to me, thanks for doing this. >> Only maybe put the test into a directory where it will be separate (e.g. >> importChecks/ImportCanonicalSameName) to avoid interference between this >> test and possible future tests. >> >> Should I integrate this change? >> >> Jan >> >> >> On 5.9.2017 18:58, Liam Miller-Cushon wrote: >> >>> This change fixes a bug that causes javac to incorrectly accept >>> non-canonical imports if the actual and expected symbols have the same >>> simple name. >>> >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8187247 >>> Webrev: http://cr.openjdk.java.net/~cushon/8187247/webrev.00/ >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From joe.darcy at oracle.com Thu Oct 19 21:32:39 2017 From: joe.darcy at oracle.com (joe darcy) Date: Thu, 19 Oct 2017 14:32:39 -0700 Subject: JDK 10 RFR of JDK-8062385: Remove @SuppressWarnings("cast") and casts for NIO related usages when JDK 9 becomes the bootstrap JDK Message-ID: <95c9d889-ae46-73ba-1712-c8ae5d2447fc@oracle.com> Hello, With the bootstrap of JDK 10 updated to JDK 9, please review the small patch below to address JDK-8062385: Remove @SuppressWarnings("cast") and casts for NIO related usages when JDK 9 becomes the bootstrap JDK For background, quoting the description of JDK-8062385: > The fix for JDK-4774077 introduced covariant return types in the NIO > buffer hierarchy. > > As a consequence that fix introduced redundant casts (and because of > -Werror a build failure) in langtools when compiling with JDK 9, but > the casts are still required when bootstrapping with JDK 8. > > The fix for JDK-8062376 added @SuppressWarnings("cast") annotations to > ensure no build failure. > > When JDK 9 becomes the default bootstrap JDK the > @SuppressWarnings("cast") and casts can be removed. Thanks, -Joe diff -r 92f08900cb3c src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java Thu Oct 19 17:47:04 2017 +0200 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java Thu Oct 19 14:28:21 2017 -0700 @@ -304,7 +304,6 @@ return (encodingName != null) ? encodingName : getDefaultEncodingName(); } - @SuppressWarnings("cast") public CharBuffer decode(ByteBuffer inbuf, boolean ignoreEncodingErrors) { String encName = getEncodingName(); CharsetDecoder decoder; @@ -312,7 +311,7 @@ decoder = getDecoder(encName, ignoreEncodingErrors); } catch (IllegalCharsetNameException | UnsupportedCharsetException e) { log.error(Errors.UnsupportedEncoding(encName)); - return (CharBuffer)CharBuffer.allocate(1).flip(); + return CharBuffer.allocate(1).flip(); } // slightly overestimate the buffer size to avoid reallocation. @@ -389,7 +388,6 @@ * @return a byte buffer containing the contents of the stream * @throws IOException if an error occurred while reading the stream */ - @SuppressWarnings("cast") public ByteBuffer makeByteBuffer(InputStream in) throws IOException { int limit = in.available(); @@ -401,14 +399,14 @@ // expand buffer result = ByteBuffer. allocate(limit <<= 1). - put((ByteBuffer)result.flip()); + put(result.flip()); int count = in.read(result.array(), position, limit - position); if (count < 0) break; result.position(position += count); } - return (ByteBuffer)result.flip(); + return result.flip(); } public void recycleByteBuffer(ByteBuffer bb) { @@ -418,14 +416,13 @@ /** * A single-element cache of direct byte buffers. */ - @SuppressWarnings("cast") private static class ByteBufferCache { private ByteBuffer cached; ByteBuffer get(int capacity) { if (capacity < 20480) capacity = 20480; ByteBuffer result = (cached != null && cached.capacity() >= capacity) - ? (ByteBuffer)cached.clear() + ? cached.clear() : ByteBuffer.allocate(capacity + capacity>>1); cached = null; return result; diff -r 92f08900cb3c src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu Oct 19 17:47:04 2017 +0200 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu Oct 19 14:28:21 2017 -0700 @@ -98,10 +98,9 @@ */ public class JavacFileManager extends BaseFileManager implements StandardJavaFileManager { - @SuppressWarnings("cast") public static char[] toArray(CharBuffer buffer) { if (buffer.hasArray()) - return ((CharBuffer)buffer.compact().flip()).array(); + return buffer.compact().flip().array(); else return buffer.toString().toCharArray(); } From cushon at google.com Fri Oct 20 01:51:55 2017 From: cushon at google.com (Liam Miller-Cushon) Date: Thu, 19 Oct 2017 18:51:55 -0700 Subject: RFR 8189708: class reading issue with named and annotated parameters Message-ID: Hello, Please consider the following fix for JDK-8189708, which is a class reading issue that prevents parameter names from being recorded for methods that have both MethodParameters and Runtime{Visible,Invisible}ParameterAnnotations attributes. Bug: https://bugs.openjdk.java.net/browse/JDK-8189708 Webrev: http://cr.openjdk.java.net/~cushon/8189708/webrev.00/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From jan.lahoda at oracle.com Fri Oct 20 07:28:53 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Fri, 20 Oct 2017 09:28:53 +0200 Subject: RFR 8189708: class reading issue with named and annotated parameters In-Reply-To: References: Message-ID: <59E9A5B5.5060200@oracle.com> Hi Liam, Thanks for looking at this. FWIW, I was looking at this problem quite a long time ago under JDK-8007720, but unfortunately didn't have time to fully finish that. For completeness, I've put the patch I had at that time here: http://cr.openjdk.java.net/~jlahoda/8007720/8007720 On 20.10.2017 03:51, Liam Miller-Cushon wrote: > Hello, > > Please consider the following fix for JDK-8189708, which is a class > reading issue that prevents parameter names from being recorded for > methods that have both MethodParameters and > Runtime{Visible,Invisible}ParameterAnnotations attributes. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8189708 > Webrev: http://cr.openjdk.java.net/~cushon/8189708/webrev.00/ A few comments on this patch: -what happens if there are both runtime invisible and visible annotations of method's parameters? Seems those that appear later will overwrite those that appear sooner? -the MethodSymbol.savedParameterAnnotations is only used during reading inside the ClassReader, right? It seems wasteful to have it as a field on each MethodSymbol, better would be a field in ClassReader. -please check what happens for annotations on constructors of enums/non-static innerclasses Thanks, Jan From jan.lahoda at oracle.com Fri Oct 20 15:42:51 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Fri, 20 Oct 2017 17:42:51 +0200 Subject: RFR 8187247: canonical import check compares classes by simple name In-Reply-To: References: <59C3DE19.4080107@oracle.com> Message-ID: <59EA197B.4090004@oracle.com> Hi Liam, Thanks for the ping. Seems OK. I'll push on Monday, unless someone else wants to. Jan On 19.10.2017 19:57, Liam Miller-Cushon wrote: > Friendly ping. Is this blocked on anything? > > On Mon, Sep 25, 2017 at 2:25 PM, Liam Miller-Cushon > wrote: > > Hi Jan, > > Thanks for the review. I moved the test to a directory. > > Updated webrev: > http://cr.openjdk.java.net/~cushon/8187247/webrev.01/ > > The formatted patch is attached. > > On Thu, Sep 21, 2017 at 8:43 AM, Jan Lahoda > wrote: > > Hi Liam, > > I apologize for belated answer. Seems OK to me, thanks for doing > this. Only maybe put the test into a directory where it will be > separate (e.g. importChecks/ImportCanonicalSameName) to avoid > interference between this test and possible future tests. > > Should I integrate this change? > > Jan > > > On 5.9.2017 18:58, Liam Miller-Cushon wrote: > > This change fixes a bug that causes javac to incorrectly accept > non-canonical imports if the actual and expected symbols > have the same > simple name. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8187247 > > Webrev: > http://cr.openjdk.java.net/~cushon/8187247/webrev.00/ > > > > From cushon at google.com Fri Oct 20 16:30:12 2017 From: cushon at google.com (Liam Miller-Cushon) Date: Fri, 20 Oct 2017 09:30:12 -0700 Subject: RFR 8189708: class reading issue with named and annotated parameters In-Reply-To: <59E9A5B5.5060200@oracle.com> References: <59E9A5B5.5060200@oracle.com> Message-ID: Thanks for the comments, On Fri, Oct 20, 2017 at 12:28 AM, Jan Lahoda wrote: > > -what happens if there are both runtime invisible and visible annotations > of method's parameters? Seems those that appear later will overwrite those > that appear sooner? > Oops, thanks. The way your patch handles that looks good to me. > -the MethodSymbol.savedParameterAnnotations is only used during reading > inside the ClassReader, right? It seems wasteful to have it as a field on > each MethodSymbol, better would be a field in ClassReader. > Sounds good. I'll try to avoid having savedParameterNames as a field in MethodSymbol also. Do you remember if you encountered any issues with that in your patch? > -please check what happens for annotations on constructors of > enums/non-static innerclasses > Will do. (Also, note that there appears to be an issue with reading MethodParameters on constructors of enums/non-static inner classes: JDK-8177486) -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Fri Oct 20 18:07:05 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 20 Oct 2017 19:07:05 +0100 Subject: RFR 8189749: Devise strategy for making source level checks more uniform Message-ID: Hi, this biggie patch allows the treatment of source level checks to be more uniform. The general problem is explained in details here: https://bugs.openjdk.java.net/browse/JDK-8189749 Webrev is here: http://cr.openjdk.java.net/~mcimadamore/8189749/ The way I approached this, was to create a first class entity, an enum called Feature. Each 'feature' has: * a min source level (e.g. what is the min source level required to compile that feature, meaning that lower levels will result in errors) * a max source level (e.g. what is the max source level required to compile that feature, meaning that higher levels will result in errors) * an optional resource key The first two properties are obviously used to decided if feature XYZ can be used given source level N. The last property is used to automate generation of source check diagnostics. Note that this patch introduce a _single_ source check diagnostic: # 0: message segment (feature), 1: string (found version), 2: string (expected version) compiler.misc.feature.not.supported.in.source=\ ?? {0} not supported in -source {1}\n\ ??? (use -source {2} or higher to enable {0}) And then there's a bunch of feature fragments, example: compiler.misc.feature.modules=\ ??? modules compiler.misc.feature.diamond.and.anon.class=\ ??? ''<>'' with anonymous inner classes compiler.misc.feature.binary.lit=\ ??? binary literals (and many more :-)) Since each feature 'knows' its fragment, it is super easy for the compiler to generate the source level check diagnostic for any feature. And, if you need to add a new feature, you just need to add an enum value, and wired it up with the corresponding resource key - done :-) Since this change affects the way in which source check diagnostics are generated, quite a lot of changes were required to adjust expected output in golden files. Aside from those changes, I also addressed the following issues: * JavaTokenizer was not using SOURCE_LEVEL flags for its diagnostics, and it was not using the new diagnostic framework to generate errors, which made the porting harder - so I've fixed that * CALog in Completeness analyzer required a new override for an AbstractLog::error variant that was probably forgotten (this was required otherwise CompletenessAnalyzerTest was failing after the change above) * Log has a 'feature' so that diagnostics marked with the SOURCE_LEVEL flag can be reported only once per source. But this check was only looking at the 'head' of a diagnostic, ignoring all arguments. Since now all source level check diagnostics share the same head, I needed to tweak the logic to also compare arguments - or else, one source level check error being reported would also disable unrelated source level check diags. Then there were a bunch of mechanical translation, for instance idioms such as: allowSimplifiedVarargs = source.allowSimplifiedVarargs(); Were rewritten as: allowSimplifiedVarargs = source.allowed(Feature.SIMPLIFIED_VARARGS); Also, in JavacParser, this idiom: checkTypeAnnotations(); has been replaced with checkSourceLevel(Feature.TYPE_ANNOTATIONS); Where checkSourceLevel is a new general routine that works on any Feature. Finally, where possible, I also got rid of the various boolean flags of the kind 'allowPrivateMethodInInterfaces' - if the class already had a 'source' field, the boolean flag can be omitted, and the check can be performed on the source object itself. Cheers Maurizio From cushon at google.com Sat Oct 21 00:51:45 2017 From: cushon at google.com (Liam Miller-Cushon) Date: Fri, 20 Oct 2017 17:51:45 -0700 Subject: RFR 8189708: class reading issue with named and annotated parameters In-Reply-To: References: <59E9A5B5.5060200@oracle.com> Message-ID: Here's an updated patch that incorporates your approach: http://cr.openjdk.java.net/~cushon/8007720/webrev.01/ I included the fix for JDK-8177486 so I could test the inner class / enum constructor case. If this looks like it's on the right track I'll move that part (and the corresponding tests) back into a separate change. On Fri, Oct 20, 2017 at 9:30 AM, Liam Miller-Cushon wrote: > Thanks for the comments, > > On Fri, Oct 20, 2017 at 12:28 AM, Jan Lahoda > wrote: >> >> -what happens if there are both runtime invisible and visible annotations >> of method's parameters? Seems those that appear later will overwrite those >> that appear sooner? >> > > Oops, thanks. The way your patch handles that looks good to me. > > >> -the MethodSymbol.savedParameterAnnotations is only used during reading >> inside the ClassReader, right? It seems wasteful to have it as a field on >> each MethodSymbol, better would be a field in ClassReader. >> > > Sounds good. I'll try to avoid having savedParameterNames as a field in > MethodSymbol also. Do you remember if you encountered any issues with that > in your patch? > > >> -please check what happens for annotations on constructors of >> enums/non-static innerclasses >> > > Will do. (Also, note that there appears to be an issue with reading > MethodParameters on constructors of enums/non-static inner classes: > JDK-8177486) > -------------- next part -------------- An HTML attachment was scrubbed... URL: From peter.major at forgerock.com Sun Oct 22 01:27:18 2017 From: peter.major at forgerock.com (Peter Major) Date: Sun, 22 Oct 2017 02:27:18 +0100 Subject: Bug in annotation processing? Message-ID: Hi, I'm running into a strange problem with javac, whereby the internal state of the Modules object gets messed up and compilation blows up with an assertion error: AssertionError ??? at jdk.compiler/com.sun.tools.javac.util.Assert.error(Assert.java:155) ??? at jdk.compiler/com.sun.tools.javac.util.Assert.check(Assert.java:46) ??? at jdk.compiler/com.sun.tools.javac.comp.Modules.enter(Modules.java:250) I've been trying to track this one down, and so far the only thing I can see is that the Modules state is initialized correctly, then there is a newRound call clearing out everything, then Modules inits everything again, then there is a newRound call from: ? [3] com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.finalCompiler (JavacProcessingEnvironment.java:1,099) and the next thing I know is Modules#enter blows up because rootModules is null. (The correct state would be [unnamed module].) Is this sufficient amount of information for a bug report, or does this issue ring a bell for anyone? Apologies if this is not the right forum. Best Regards, Peter Major From bsrbnd at gmail.com Sun Oct 22 17:36:12 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Sun, 22 Oct 2017 19:36:12 +0200 Subject: Linear implementation of Tarjan's algorithm Message-ID: Hi, As briefly mentioned in [1], the current implementation of Tarjan's algorithm performs a linear scan of the stack while iterating on the node dependencies which might be avoided... Next is an attempt to make the whole implementation more linear using a 'HashStack' that provides all operations in constant time, especially 'contains()'. What do you think? Thanks, Bernard [1] http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011226.html diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Properties; +import java.util.HashSet; /**

This is NOT part of any supported API. * If you write code that depends on this, you do so at your own risk. @@ -164,7 +165,28 @@ ListBuffer> sccs = new ListBuffer<>(); /** Stack of all reacheable nodes from given root. */ - ListBuffer stack = new ListBuffer<>(); + HashStack stack = new HashStack<>(); + //where + private static class HashStack { + HashSet set = new HashSet<>(); + List stack = List.nil(); + + private void push(N n) { + set.add(n); + stack = stack.prepend(n); + } + + private N pop() { + N n = stack.head; + set.remove(n); + stack = stack.tail; + return n; + } + + private boolean contains(N n) { + return set.contains(n); + } + } private List> findSCC(Iterable nodes) { for (N node : nodes) { @@ -197,7 +219,7 @@ n.index = index; n.lowlink = index; index++; - stack.prepend(n); + stack.push(n); n.active = true; } @@ -205,7 +227,7 @@ N n; ListBuffer cycle = new ListBuffer<>(); do { - n = stack.remove(); + n = stack.pop(); n.active = false; cycle.add(n); } while (n != v); From forax at univ-mlv.fr Sun Oct 22 18:06:03 2017 From: forax at univ-mlv.fr (Remi Forax) Date: Sun, 22 Oct 2017 20:06:03 +0200 (CEST) Subject: Linear implementation of Tarjan's algorithm In-Reply-To: References: Message-ID: <451662128.2472977.1508695563065.JavaMail.zimbra@u-pem.fr> Please do not add a new class just for that, for a code as simple as this one, you can inline every methods. Also, i think the compiler will create 8 methods for your class HashStack, you should declare the class and all the method package private (or wait for the compiler using the 18.3 as bootstrap JDK). regards, R?mi ----- Mail original ----- > De: "B. Blaser" > ?: "compiler-dev" > Envoy?: Dimanche 22 Octobre 2017 19:36:12 > Objet: Linear implementation of Tarjan's algorithm > Hi, > > As briefly mentioned in [1], the current implementation of Tarjan's > algorithm performs a linear scan of the stack while iterating on the > node dependencies which might be avoided... > > Next is an attempt to make the whole implementation more linear using > a 'HashStack' that provides all operations in constant time, > especially 'contains()'. > > What do you think? > > Thanks, > Bernard > > > [1] http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011226.html > > > diff --git > a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java > b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java > @@ -28,6 +28,7 @@ > import java.util.ArrayList; > import java.util.Collection; > import java.util.Properties; > +import java.util.HashSet; > > /**

This is NOT part of any supported API. > * If you write code that depends on this, you do so at your own risk. > @@ -164,7 +165,28 @@ > ListBuffer> sccs = new ListBuffer<>(); > > /** Stack of all reacheable nodes from given root. */ > - ListBuffer stack = new ListBuffer<>(); > + HashStack stack = new HashStack<>(); > + //where > + private static class HashStack { > + HashSet set = new HashSet<>(); > + List stack = List.nil(); > + > + private void push(N n) { > + set.add(n); > + stack = stack.prepend(n); > + } > + > + private N pop() { > + N n = stack.head; > + set.remove(n); > + stack = stack.tail; > + return n; > + } > + > + private boolean contains(N n) { > + return set.contains(n); > + } > + } > > private List> findSCC(Iterable extends N> nodes) { > for (N node : nodes) { > @@ -197,7 +219,7 @@ > n.index = index; > n.lowlink = index; > index++; > - stack.prepend(n); > + stack.push(n); > n.active = true; > } > > @@ -205,7 +227,7 @@ > N n; > ListBuffer cycle = new ListBuffer<>(); > do { > - n = stack.remove(); > + n = stack.pop(); > n.active = false; > cycle.add(n); > } while (n != v); From maurizio.cimadamore at oracle.com Sun Oct 22 20:14:52 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Sun, 22 Oct 2017 21:14:52 +0100 Subject: Linear implementation of Tarjan's algorithm In-Reply-To: <451662128.2472977.1508695563065.JavaMail.zimbra@u-pem.fr> References: <451662128.2472977.1508695563065.JavaMail.zimbra@u-pem.fr> Message-ID: <8b879ed0-1c88-1e6d-a477-88797190f202@oracle.com> Another thing I'm concerned here is that we're jumping into performance fixes w/o any evidence of what the bottlenecks really are. I'm all for fixing performance issues (and during JDK 9 we did a lot of work in order to resolve the combinatorial explosion of checks in nested method calls). So, I think that, before we decide to spend significant cycles on this (and other related issues), we should at least come up with reasonable examples which demonstrate the bottleneck. In other words, in a world where the average inference graph has 4-5 nodes, does it really matter much how the contains() method is implemented? And, if you have a 1000 nodes inference-graph, are you sure that the main bottleneck is going to be the contains method? After having profiled MANY javac runs, I have to admit I have never seen that popping up - of course with all the optimizations that went into the compiler recently, things might have changed, but I still think that we should handle performance-related matters on a more data-driven basis. Cheers Maurizio On 22/10/17 19:06, Remi Forax wrote: > Please do not add a new class just for that, for a code as simple as this one, you can inline every methods. > Also, i think the compiler will create 8 methods for your class HashStack, you should declare the class and all the method package private (or wait for the compiler using the 18.3 as bootstrap JDK). > > regards, > R?mi > > ----- Mail original ----- >> De: "B. Blaser" >> ?: "compiler-dev" >> Envoy?: Dimanche 22 Octobre 2017 19:36:12 >> Objet: Linear implementation of Tarjan's algorithm >> Hi, >> >> As briefly mentioned in [1], the current implementation of Tarjan's >> algorithm performs a linear scan of the stack while iterating on the >> node dependencies which might be avoided... >> >> Next is an attempt to make the whole implementation more linear using >> a 'HashStack' that provides all operations in constant time, >> especially 'contains()'. >> >> What do you think? >> >> Thanks, >> Bernard >> >> >> [1] http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011226.html >> >> >> diff --git >> a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java >> b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java >> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java >> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java >> @@ -28,6 +28,7 @@ >> import java.util.ArrayList; >> import java.util.Collection; >> import java.util.Properties; >> +import java.util.HashSet; >> >> /**

This is NOT part of any supported API. >> * If you write code that depends on this, you do so at your own risk. >> @@ -164,7 +165,28 @@ >> ListBuffer> sccs = new ListBuffer<>(); >> >> /** Stack of all reacheable nodes from given root. */ >> - ListBuffer stack = new ListBuffer<>(); >> + HashStack stack = new HashStack<>(); >> + //where >> + private static class HashStack { >> + HashSet set = new HashSet<>(); >> + List stack = List.nil(); >> + >> + private void push(N n) { >> + set.add(n); >> + stack = stack.prepend(n); >> + } >> + >> + private N pop() { >> + N n = stack.head; >> + set.remove(n); >> + stack = stack.tail; >> + return n; >> + } >> + >> + private boolean contains(N n) { >> + return set.contains(n); >> + } >> + } >> >> private List> findSCC(Iterable> extends N> nodes) { >> for (N node : nodes) { >> @@ -197,7 +219,7 @@ >> n.index = index; >> n.lowlink = index; >> index++; >> - stack.prepend(n); >> + stack.push(n); >> n.active = true; >> } >> >> @@ -205,7 +227,7 @@ >> N n; >> ListBuffer cycle = new ListBuffer<>(); >> do { >> - n = stack.remove(); >> + n = stack.pop(); >> n.active = false; >> cycle.add(n); >> } while (n != v); From jan.lahoda at oracle.com Mon Oct 23 11:50:55 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Mon, 23 Oct 2017 13:50:55 +0200 Subject: RFR: JDK-8189796: Incorrect end position for missing statement Message-ID: <59EDD79F.2080604@oracle.com> Hi, Consider code like: { if (true) } (i.e. missing statement after "if"). The if statement will get parsed as "if (true) (ERROR);", which appears OK, but the end position for "(ERROR);" and "(ERROR)" is not set. In addition, due to this, the end pos of the error/diagnostic produced is -1. Bug: https://bugs.openjdk.java.net/browse/JDK-8189796 Proposed patch: cr.openjdk.java.net/~jlahoda/8189796/webrev.00/ Thanks, Jan From bsrbnd at gmail.com Mon Oct 23 13:01:34 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Mon, 23 Oct 2017 15:01:34 +0200 Subject: Linear implementation of Tarjan's algorithm In-Reply-To: <8b879ed0-1c88-1e6d-a477-88797190f202@oracle.com> References: <451662128.2472977.1508695563065.JavaMail.zimbra@u-pem.fr> <8b879ed0-1c88-1e6d-a477-88797190f202@oracle.com> Message-ID: I agree with both of you. To R?mi, It's never easy to choose between readability and absolute performance, but I agree an inline rewriting would probably be more appropriate here. To Maurizio, this wasn't intended to be a major optimization but only a very small rewriting that might help going faster in some particular situations. Cheers, Bernard On 22 October 2017 at 22:14, Maurizio Cimadamore wrote: > Another thing I'm concerned here is that we're jumping into performance > fixes w/o any evidence of what the bottlenecks really are. I'm all for > fixing performance issues (and during JDK 9 we did a lot of work in order to > resolve the combinatorial explosion of checks in nested method calls). So, I > think that, before we decide to spend significant cycles on this (and other > related issues), we should at least come up with reasonable examples which > demonstrate the bottleneck. In other words, in a world where the average > inference graph has 4-5 nodes, does it really matter much how the contains() > method is implemented? And, if you have a 1000 nodes inference-graph, are > you sure that the main bottleneck is going to be the contains method? After > having profiled MANY javac runs, I have to admit I have never seen that > popping up - of course with all the optimizations that went into the > compiler recently, things might have changed, but I still think that we > should handle performance-related matters on a more data-driven basis. > > Cheers > Maurizio > > > > On 22/10/17 19:06, Remi Forax wrote: >> >> Please do not add a new class just for that, for a code as simple as this >> one, you can inline every methods. >> Also, i think the compiler will create 8 methods for your class HashStack, >> you should declare the class and all the method package private (or wait for >> the compiler using the 18.3 as bootstrap JDK). >> >> regards, >> R?mi >> >> ----- Mail original ----- >>> >>> De: "B. Blaser" >>> ?: "compiler-dev" >>> Envoy?: Dimanche 22 Octobre 2017 19:36:12 >>> Objet: Linear implementation of Tarjan's algorithm >>> Hi, >>> >>> As briefly mentioned in [1], the current implementation of Tarjan's >>> algorithm performs a linear scan of the stack while iterating on the >>> node dependencies which might be avoided... >>> >>> Next is an attempt to make the whole implementation more linear using >>> a 'HashStack' that provides all operations in constant time, >>> especially 'contains()'. >>> >>> What do you think? >>> >>> Thanks, >>> Bernard >>> >>> >>> [1] >>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011226.html >>> >>> >>> diff --git >>> a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java >>> b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java >>> --- >>> a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java >>> +++ >>> b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java >>> @@ -28,6 +28,7 @@ >>> import java.util.ArrayList; >>> import java.util.Collection; >>> import java.util.Properties; >>> +import java.util.HashSet; >>> >>> /**

This is NOT part of any supported API. >>> * If you write code that depends on this, you do so at your own risk. >>> @@ -164,7 +165,28 @@ >>> ListBuffer> sccs = new ListBuffer<>(); >>> >>> /** Stack of all reacheable nodes from given root. */ >>> - ListBuffer stack = new ListBuffer<>(); >>> + HashStack stack = new HashStack<>(); >>> + //where >>> + private static class HashStack { >>> + HashSet set = new HashSet<>(); >>> + List stack = List.nil(); >>> + >>> + private void push(N n) { >>> + set.add(n); >>> + stack = stack.prepend(n); >>> + } >>> + >>> + private N pop() { >>> + N n = stack.head; >>> + set.remove(n); >>> + stack = stack.tail; >>> + return n; >>> + } >>> + >>> + private boolean contains(N n) { >>> + return set.contains(n); >>> + } >>> + } >>> >>> private List> findSCC(Iterable>> extends N> nodes) { >>> for (N node : nodes) { >>> @@ -197,7 +219,7 @@ >>> n.index = index; >>> n.lowlink = index; >>> index++; >>> - stack.prepend(n); >>> + stack.push(n); >>> n.active = true; >>> } >>> >>> @@ -205,7 +227,7 @@ >>> N n; >>> ListBuffer cycle = new ListBuffer<>(); >>> do { >>> - n = stack.remove(); >>> + n = stack.pop(); >>> n.active = false; >>> cycle.add(n); >>> } while (n != v); > > From maurizio.cimadamore at oracle.com Mon Oct 23 15:58:45 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 23 Oct 2017 16:58:45 +0100 Subject: Linear implementation of Tarjan's algorithm In-Reply-To: References: <451662128.2472977.1508695563065.JavaMail.zimbra@u-pem.fr> <8b879ed0-1c88-1e6d-a477-88797190f202@oracle.com> Message-ID: To have a better idea of the kind of performance issues we are having in this area, take a look here: https://bugs.openjdk.java.net/browse/JDK-8152289 I'm slightly pessimistic that any of the performance fixes discussed here in the last few weeks would actually make a difference here - the sad reality is that the cost of doing incorporation dominates pretty much everything else. And the name of the game to address these kind of issues seem to be to attempt to reduce the size of the inference graph by finding similarities between variables [1]/minimize number of propagation steps as much as possible [2], etc. [1] - https://bugs.openjdk.java.net/browse/JDK-8046685 [2] - https://bugs.openjdk.java.net/browse/JDK-8067767 Maurizio On 23/10/17 14:01, B. Blaser wrote: > I agree with both of you. > > To R?mi, It's never easy to choose between readability and absolute > performance, but I agree an inline rewriting would probably be more > appropriate here. > > To Maurizio, this wasn't intended to be a major optimization but only > a very small rewriting that might help going faster in some particular > situations. > > Cheers, > Bernard > > > On 22 October 2017 at 22:14, Maurizio Cimadamore > wrote: >> Another thing I'm concerned here is that we're jumping into performance >> fixes w/o any evidence of what the bottlenecks really are. I'm all for >> fixing performance issues (and during JDK 9 we did a lot of work in order to >> resolve the combinatorial explosion of checks in nested method calls). So, I >> think that, before we decide to spend significant cycles on this (and other >> related issues), we should at least come up with reasonable examples which >> demonstrate the bottleneck. In other words, in a world where the average >> inference graph has 4-5 nodes, does it really matter much how the contains() >> method is implemented? And, if you have a 1000 nodes inference-graph, are >> you sure that the main bottleneck is going to be the contains method? After >> having profiled MANY javac runs, I have to admit I have never seen that >> popping up - of course with all the optimizations that went into the >> compiler recently, things might have changed, but I still think that we >> should handle performance-related matters on a more data-driven basis. >> >> Cheers >> Maurizio >> >> >> >> On 22/10/17 19:06, Remi Forax wrote: >>> Please do not add a new class just for that, for a code as simple as this >>> one, you can inline every methods. >>> Also, i think the compiler will create 8 methods for your class HashStack, >>> you should declare the class and all the method package private (or wait for >>> the compiler using the 18.3 as bootstrap JDK). >>> >>> regards, >>> R?mi >>> >>> ----- Mail original ----- >>>> De: "B. Blaser" >>>> ?: "compiler-dev" >>>> Envoy?: Dimanche 22 Octobre 2017 19:36:12 >>>> Objet: Linear implementation of Tarjan's algorithm >>>> Hi, >>>> >>>> As briefly mentioned in [1], the current implementation of Tarjan's >>>> algorithm performs a linear scan of the stack while iterating on the >>>> node dependencies which might be avoided... >>>> >>>> Next is an attempt to make the whole implementation more linear using >>>> a 'HashStack' that provides all operations in constant time, >>>> especially 'contains()'. >>>> >>>> What do you think? >>>> >>>> Thanks, >>>> Bernard >>>> >>>> >>>> [1] >>>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011226.html >>>> >>>> >>>> diff --git >>>> a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java >>>> b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java >>>> --- >>>> a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java >>>> +++ >>>> b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/GraphUtils.java >>>> @@ -28,6 +28,7 @@ >>>> import java.util.ArrayList; >>>> import java.util.Collection; >>>> import java.util.Properties; >>>> +import java.util.HashSet; >>>> >>>> /**

This is NOT part of any supported API. >>>> * If you write code that depends on this, you do so at your own risk. >>>> @@ -164,7 +165,28 @@ >>>> ListBuffer> sccs = new ListBuffer<>(); >>>> >>>> /** Stack of all reacheable nodes from given root. */ >>>> - ListBuffer stack = new ListBuffer<>(); >>>> + HashStack stack = new HashStack<>(); >>>> + //where >>>> + private static class HashStack { >>>> + HashSet set = new HashSet<>(); >>>> + List stack = List.nil(); >>>> + >>>> + private void push(N n) { >>>> + set.add(n); >>>> + stack = stack.prepend(n); >>>> + } >>>> + >>>> + private N pop() { >>>> + N n = stack.head; >>>> + set.remove(n); >>>> + stack = stack.tail; >>>> + return n; >>>> + } >>>> + >>>> + private boolean contains(N n) { >>>> + return set.contains(n); >>>> + } >>>> + } >>>> >>>> private List> findSCC(Iterable>>> extends N> nodes) { >>>> for (N node : nodes) { >>>> @@ -197,7 +219,7 @@ >>>> n.index = index; >>>> n.lowlink = index; >>>> index++; >>>> - stack.prepend(n); >>>> + stack.push(n); >>>> n.active = true; >>>> } >>>> >>>> @@ -205,7 +227,7 @@ >>>> N n; >>>> ListBuffer cycle = new ListBuffer<>(); >>>> do { >>>> - n = stack.remove(); >>>> + n = stack.pop(); >>>> n.active = false; >>>> cycle.add(n); >>>> } while (n != v); >> From cushon at google.com Mon Oct 23 19:30:20 2017 From: cushon at google.com (Liam Miller-Cushon) Date: Mon, 23 Oct 2017 12:30:20 -0700 Subject: RFR 8187247: canonical import check compares classes by simple name In-Reply-To: <59EA197B.4090004@oracle.com> References: <59C3DE19.4080107@oracle.com> <59EA197B.4090004@oracle.com> Message-ID: Thanks! On Fri, Oct 20, 2017 at 8:42 AM, Jan Lahoda wrote: > Hi Liam, > > Thanks for the ping. Seems OK. I'll push on Monday, unless someone else > wants to. > > Jan > > On 19.10.2017 19:57, Liam Miller-Cushon wrote: > >> Friendly ping. Is this blocked on anything? >> >> On Mon, Sep 25, 2017 at 2:25 PM, Liam Miller-Cushon > > wrote: >> >> Hi Jan, >> >> Thanks for the review. I moved the test to a directory. >> >> Updated webrev: >> http://cr.openjdk.java.net/~cushon/8187247/webrev.01/ >> >> The formatted patch is attached. >> >> On Thu, Sep 21, 2017 at 8:43 AM, Jan Lahoda > > wrote: >> >> Hi Liam, >> >> I apologize for belated answer. Seems OK to me, thanks for doing >> this. Only maybe put the test into a directory where it will be >> separate (e.g. importChecks/ImportCanonicalSameName) to avoid >> interference between this test and possible future tests. >> >> Should I integrate this change? >> >> Jan >> >> >> On 5.9.2017 18:58, Liam Miller-Cushon wrote: >> >> This change fixes a bug that causes javac to incorrectly >> accept >> non-canonical imports if the actual and expected symbols >> have the same >> simple name. >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8187247 >> >> Webrev: >> http://cr.openjdk.java.net/~cushon/8187247/webrev.00/ >> >> >> >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From mark.reinhold at oracle.com Mon Oct 23 21:48:13 2017 From: mark.reinhold at oracle.com (mark.reinhold at oracle.com) Date: Mon, 23 Oct 2017 14:48:13 -0700 (PDT) Subject: JEP 313: Remove the Native-Header Generation Tool (javah) Message-ID: <20171023214813.A3FB9EB349@eggemoggin.niobe.net> New JEP Candidate: http://openjdk.java.net/jeps/313 - Mark From maurizio.cimadamore at oracle.com Tue Oct 24 08:08:44 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 24 Oct 2017 09:08:44 +0100 Subject: RFR: JDK-8189796: Incorrect end position for missing statement In-Reply-To: <59EDD79F.2080604@oracle.com> References: <59EDD79F.2080604@oracle.com> Message-ID: Looks good - meta-observation: at some point we should (i) make sure that all errors generated in the parser go through some uniform routine (such as syntaxError) and also that (ii) such routine is updated to use the new diagnostic keys instead of strings and varargs. Maurizio On 23/10/17 12:50, Jan Lahoda wrote: > Hi, > > Consider code like: > { > ???? if (true) > } > > (i.e. missing statement after "if"). The if statement will get parsed > as "if (true) (ERROR);", which appears OK, but the end position for > "(ERROR);" and "(ERROR)" is not set. In addition, due to this, the end > pos of the error/diagnostic produced is -1. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8189796 > Proposed patch: cr.openjdk.java.net/~jlahoda/8189796/webrev.00/ > > Thanks, > ???? Jan From maurizio.cimadamore at oracle.com Tue Oct 24 08:10:30 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 24 Oct 2017 09:10:30 +0100 Subject: JDK 10 RFR of JDK-8062385: Remove @SuppressWarnings("cast") and casts for NIO related usages when JDK 9 becomes the bootstrap JDK In-Reply-To: <95c9d889-ae46-73ba-1712-c8ae5d2447fc@oracle.com> References: <95c9d889-ae46-73ba-1712-c8ae5d2447fc@oracle.com> Message-ID: <0f33c598-0207-7fa2-6918-8b011f105782@oracle.com> Looks good Maurizio On 19/10/17 22:32, joe darcy wrote: > Hello, > > With the bootstrap of JDK 10 updated to JDK 9, please review the small > patch below to address > > ??? JDK-8062385: Remove @SuppressWarnings("cast") and casts for NIO > related usages when JDK 9 becomes the bootstrap JDK > > For background, quoting the description of JDK-8062385: > >> The fix for JDK-4774077 introduced covariant return types in the NIO >> buffer hierarchy. >> >> As a consequence that fix introduced redundant casts (and because of >> -Werror a build failure) in langtools when compiling with JDK 9, but >> the casts are still required when bootstrapping with JDK 8. >> >> The fix for JDK-8062376 added @SuppressWarnings("cast") annotations >> to ensure no build failure. >> >> When JDK 9 becomes the default bootstrap JDK the >> @SuppressWarnings("cast") and casts can be removed. > > Thanks, > > -Joe > > diff -r 92f08900cb3c > src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java > --- > a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java > Thu Oct 19 17:47:04 2017 +0200 > +++ > b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java > Thu Oct 19 14:28:21 2017 -0700 > @@ -304,7 +304,6 @@ > ???????? return (encodingName != null) ? encodingName : > getDefaultEncodingName(); > ???? } > > -??? @SuppressWarnings("cast") > ???? public CharBuffer decode(ByteBuffer inbuf, boolean > ignoreEncodingErrors) { > ???????? String encName = getEncodingName(); > ???????? CharsetDecoder decoder; > @@ -312,7 +311,7 @@ > ???????????? decoder = getDecoder(encName, ignoreEncodingErrors); > ???????? } catch (IllegalCharsetNameException | > UnsupportedCharsetException e) { > ???????????? log.error(Errors.UnsupportedEncoding(encName)); > -??????????? return (CharBuffer)CharBuffer.allocate(1).flip(); > +??????????? return CharBuffer.allocate(1).flip(); > ???????? } > > ???????? // slightly overestimate the buffer size to avoid reallocation. > @@ -389,7 +388,6 @@ > ????? * @return a byte buffer containing the contents of the stream > ????? * @throws IOException if an error occurred while reading the stream > ????? */ > -??? @SuppressWarnings("cast") > ???? public ByteBuffer makeByteBuffer(InputStream in) > ???????? throws IOException { > ???????? int limit = in.available(); > @@ -401,14 +399,14 @@ > ???????????????? // expand buffer > ???????????????? result = ByteBuffer. > ???????????????????? allocate(limit <<= 1). > -??????????????????? put((ByteBuffer)result.flip()); > +??????????????????? put(result.flip()); > ???????????? int count = in.read(result.array(), > ???????????????? position, > ???????????????? limit - position); > ???????????? if (count < 0) break; > ???????????? result.position(position += count); > ???????? } > -??????? return (ByteBuffer)result.flip(); > +??????? return result.flip(); > ???? } > > ???? public void recycleByteBuffer(ByteBuffer bb) { > @@ -418,14 +416,13 @@ > ???? /** > ????? * A single-element cache of direct byte buffers. > ????? */ > -??? @SuppressWarnings("cast") > ???? private static class ByteBufferCache { > ???????? private ByteBuffer cached; > ???????? ByteBuffer get(int capacity) { > ???????????? if (capacity < 20480) capacity = 20480; > ???????????? ByteBuffer result = > ???????????????? (cached != null && cached.capacity() >= capacity) > -??????????????? ? (ByteBuffer)cached.clear() > +??????????????? ? cached.clear() > ???????????????? : ByteBuffer.allocate(capacity + capacity>>1); > ???????????? cached = null; > ???????????? return result; > diff -r 92f08900cb3c > src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java > --- > a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java > Thu Oct 19 17:47:04 2017 +0200 > +++ > b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java > Thu Oct 19 14:28:21 2017 -0700 > @@ -98,10 +98,9 @@ > ? */ > ?public class JavacFileManager extends BaseFileManager implements > StandardJavaFileManager { > > -??? @SuppressWarnings("cast") > ???? public static char[] toArray(CharBuffer buffer) { > ???????? if (buffer.hasArray()) > -??????????? return ((CharBuffer)buffer.compact().flip()).array(); > +??????????? return buffer.compact().flip().array(); > ???????? else > ???????????? return buffer.toString().toCharArray(); > ???? } > From jan.lahoda at oracle.com Tue Oct 24 08:24:19 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Tue, 24 Oct 2017 10:24:19 +0200 Subject: RFR: JDK-8189796: Incorrect end position for missing statement In-Reply-To: References: <59EDD79F.2080604@oracle.com> Message-ID: <59EEF8B3.4080209@oracle.com> On 24.10.2017 10:08, Maurizio Cimadamore wrote: > Looks good - meta-observation: at some point we should (i) make sure Thanks! > that all errors generated in the parser go through some uniform routine > (such as syntaxError) and also that (ii) such routine is updated to use > the new diagnostic keys instead of strings and varargs. Agreed on both. Jan > > Maurizio > > > On 23/10/17 12:50, Jan Lahoda wrote: >> Hi, >> >> Consider code like: >> { >> if (true) >> } >> >> (i.e. missing statement after "if"). The if statement will get parsed >> as "if (true) (ERROR);", which appears OK, but the end position for >> "(ERROR);" and "(ERROR)" is not set. In addition, due to this, the end >> pos of the error/diagnostic produced is -1. >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8189796 >> Proposed patch: cr.openjdk.java.net/~jlahoda/8189796/webrev.00/ >> >> Thanks, >> Jan > From vicente.romero at oracle.com Tue Oct 24 22:21:30 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Tue, 24 Oct 2017 18:21:30 -0400 Subject: RFR 8178150: Regression in logic for handling inference stuck constraints In-Reply-To: References: <7ac44223-93da-f4d0-fc20-293b8db99707@oracle.com> <461326c8-f7fe-6f11-95e9-5da6c3ff7fa9@oracle.com> Message-ID: Hi Maurizio, Thanks for the updated version. I agree with you that once the closure of a given node is calculated it should be cached. Probably in an independent data structure as it could be expensive to calculate the closure and also because for a given graph, the closure will be the same for a given node until the graph changes. I still have comments on the performance land but I would like to focus on the correctness first. This code, at DeferredAttrContext::buildStuckGraph: InferenceGraph graph = infer.new GraphSolver(inferenceContext, types.noWarnings) ??????????????????? .new InferenceGraph(); will return a graph in which strongly connected components have been merged along with theirs dependencies, meaning that if variable T1 and T2 are strongly connected, dependencies of T1 will be the same as dependencies of T2. I'm not sure that the spec considered this graph as the one over which to calculate input and output variables. Also I'm wondering if it could be the case that the tarjan algorithm could place an input and an output variable in the same node. Apart from this there are assumptions that even though are previous to this code, could affect the outcome. It is been assumed that stuck variables == input variables. But according to the spec in this case ?LambdaExpression ? throws T ? T is an input variable, but I don't think that it will be considered as a stuck variable. Similar for method references. Thanks, Vicente On 10/19/2017 05:41 AM, Maurizio Cimadamore wrote: > Updated webrev > > http://cr.openjdk.java.net/~mcimadamore/8178150_v2/ > > Maurizio > > > On 19/10/17 09:38, Maurizio Cimadamore wrote: >> I think you are right - this method was there when I first wrote the >> patch but then got removed. I resurrected it for the purpose of this >> patch, but it seems like it's not doing what we need. >> >> Maurizio >> >> >> On 19/10/17 00:57, Vicente Romero wrote: >>> Hi Maurizio, >>> >>> I'm not sure about the correctness or the objective of the closure() >>> method. The termination condition seems to be: stop as soon as you >>> find a cycle in the graph, at least this is my reading. But for some >>> graphs this could imply finding a subset of the closure not the >>> whole of it. It seems to me like implementing a graph traversal >>> method should be what it is wanted here. Unless there is something >>> I'm missing. >>> >>> Also in the same method the javadoc could have stall comments as it >>> says that a kind of dependencies is given but there is no argument >>> passed to the method. >>> >>> Thanks, >>> Vicente >>> >>> On 10/18/2017 04:15 PM, Maurizio Cimadamore wrote: >>>> Hi, >>>> this issue has already been discussed in [1]. >>>> >>>> The issue has to do with the fact that logic for picking a deferred >>>> node to unstick ignores the can-influence relationship (aka >>>> inference graph dependencies). >>>> >>>> The implemented code is not optimized (almost deliberately); I >>>> wanted the code to follow the spec more or less cleanly. While I'm >>>> open to small improvements, I would please ask to focus on >>>> correctness for the time being since (i) this code is not an hot >>>> execution path and (ii) other performance improvements in this area >>>> will follow, see [2]. >>>> >>>> http://cr.openjdk.java.net/~mcimadamore/8178150/ >>>> >>>> [1] - >>>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011192.html >>>> [2] - >>>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011126.html >>>> >>>> Cheers >>>> Maurizio >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Tue Oct 24 23:43:35 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 25 Oct 2017 00:43:35 +0100 Subject: RFR 8178150: Regression in logic for handling inference stuck constraints In-Reply-To: References: <7ac44223-93da-f4d0-fc20-293b8db99707@oracle.com> <461326c8-f7fe-6f11-95e9-5da6c3ff7fa9@oracle.com> Message-ID: <4055d274-054c-605d-9d80-c8b28d68f431@oracle.com> On 24/10/17 23:21, Vicente Romero wrote: > Hi Maurizio, > > Thanks for the updated version. I agree with you that once the closure > of a given node is calculated it should be cached. Probably in an > independent data structure as it could be expensive to calculate the > closure and also because for a given graph, the closure will be the > same for a given node until the graph changes. I still have comments > on the performance land but I would like to focus on the correctness > first. This code, at DeferredAttrContext::buildStuckGraph: > > InferenceGraph graph = infer.new GraphSolver(inferenceContext, > types.noWarnings) > ??????????????????? .new InferenceGraph(); > > will return a graph in which strongly connected components have been > merged along with theirs dependencies, meaning that if variable T1 and > T2 are strongly connected, dependencies of T1 will be the same as > dependencies of T2. I'm not sure that the spec considered this graph > as the one over which to calculate input and output variables. input and output variables are computed on a number of factors; first there's a structural definition that says what input and output variables are, looking at the shape of the constraints. Then, once you know which variables are input and which are output, you have to (quoting the spec) do this: ?"A subset of constraints is selected in C, satisfying the property that, for each constraint, no input variable can influence an output variable of another constraint in C" The "can influence" bit here is crucial - in fact the spec goes on and says "An inference variable ? /can influence/ an inference variable ? if ? depends on the resolution of ? (?18.4 ), or vice versa; or if there exists a third inference variable ? such that ? can influence ? and ? can influence ?. " That is, 'can influence' induces the same inference graph that is used during resolution - it _is_ the same thing. So it's natural, I think, for the implementation, to reuse the same graph to model the 'can influence' relationship. > Also I'm wondering if it could be the case that the tarjan algorithm > could place an input and an output variable in the same node. In terms of the spec, I think you are asking "is it possible for two variables alpha and beta, where alpha is an input variable and beta is an output variable to be such that alpha can influence beta and beta can influence alpha?" I think that's possible yes. But that's why 18.5.2.2 allows for cycles, and breaks up the deadlock by picking one. > > Apart from this there are assumptions that even though are previous to > this code, could affect the outcome. It is been assumed that stuck > variables == input variables. But according to the spec in this case > > ?LambdaExpression ? throws T ? > > T is an input variable, but I don't think that it will be considered > as a stuck variable. Similar for method references. I was confused a bit by that too - but note that it doesn't mean what it looks - for instance, consider this (18.1.2): "?/LambdaExpression/ ?_/throws/ T?: The checked exceptions thrown by the body of the /LambdaExpression/ are declared by the |throws| clause of the function type derived from T." This implies that T is just a target type (a functional interface); in other words, this means that we have a lambda and a target which is an inference var - so the constraint for evaluating checked exceptions is also 'stuck' because you can't obtain the set of expected exceptions if you don't have a functional interface as a target. But I believe that both ??/LambdaExpression/ ? T? and ?/LambdaExpression/ ?_/throws/ T? lead to the same set of input variables; there is actually a very tiny difference, in that the latter constraint doesn't add in the input variable set the input variables of the constraints coming from the return expressions of the lambda - and that's because, I think, you can reason about exceptions being thrown by a lambda even if some return expressions are 'stuck'. Which means I guess, at least hypothetically, you could write a test where the spec picks ?/LambdaExpression/ ?_/throws/ T? and decides to process that ahead of? ?/LambdaExpression/ ? T? - while in javac the two happen at the same time (because javac doesn't have the distinction between these two constraints - throws constraints are evaluated as part of evaluating the lambda compatibility constraint). In other words, I'm not denying that there's a slight mismatch here - but I think the magnitude of that mismatch is very small - especially compared to the current situation. Moreover, I suspect that fixing this mismatch will require a lot of implementation changes - as I say above, in a way the mismatch reflects the different way in which the compiler goes about when reasoning about constraint formulas (which was mostly dictated out of compatibility constraints - e.g. make same inference engine work on both 8 and 7). So, while I'm not dismissing the concern, I think that's a candidate for a followup investigation. Maurizio > > Thanks, > Vicente > > On 10/19/2017 05:41 AM, Maurizio Cimadamore wrote: >> Updated webrev >> >> http://cr.openjdk.java.net/~mcimadamore/8178150_v2/ >> >> Maurizio >> >> >> On 19/10/17 09:38, Maurizio Cimadamore wrote: >>> I think you are right - this method was there when I first wrote the >>> patch but then got removed. I resurrected it for the purpose of this >>> patch, but it seems like it's not doing what we need. >>> >>> Maurizio >>> >>> >>> On 19/10/17 00:57, Vicente Romero wrote: >>>> Hi Maurizio, >>>> >>>> I'm not sure about the correctness or the objective of the >>>> closure() method. The termination condition seems to be: stop as >>>> soon as you find a cycle in the graph, at least this is my reading. >>>> But for some graphs this could imply finding a subset of the >>>> closure not the whole of it. It seems to me like implementing a >>>> graph traversal method should be what it is wanted here. Unless >>>> there is something I'm missing. >>>> >>>> Also in the same method the javadoc could have stall comments as it >>>> says that a kind of dependencies is given but there is no argument >>>> passed to the method. >>>> >>>> Thanks, >>>> Vicente >>>> >>>> On 10/18/2017 04:15 PM, Maurizio Cimadamore wrote: >>>>> Hi, >>>>> this issue has already been discussed in [1]. >>>>> >>>>> The issue has to do with the fact that logic for picking a >>>>> deferred node to unstick ignores the can-influence relationship >>>>> (aka inference graph dependencies). >>>>> >>>>> The implemented code is not optimized (almost deliberately); I >>>>> wanted the code to follow the spec more or less cleanly. While I'm >>>>> open to small improvements, I would please ask to focus on >>>>> correctness for the time being since (i) this code is not an hot >>>>> execution path and (ii) other performance improvements in this >>>>> area will follow, see [2]. >>>>> >>>>> http://cr.openjdk.java.net/~mcimadamore/8178150/ >>>>> >>>>> [1] - >>>>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011192.html >>>>> [2] - >>>>> http://mail.openjdk.java.net/pipermail/compiler-dev/2017-October/011126.html >>>>> >>>>> Cheers >>>>> Maurizio >>>>> >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Wed Oct 25 00:33:45 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 25 Oct 2017 01:33:45 +0100 Subject: RFR 8178150: Regression in logic for handling inference stuck constraints In-Reply-To: <4055d274-054c-605d-9d80-c8b28d68f431@oracle.com> References: <7ac44223-93da-f4d0-fc20-293b8db99707@oracle.com> <461326c8-f7fe-6f11-95e9-5da6c3ff7fa9@oracle.com> <4055d274-054c-605d-9d80-c8b28d68f431@oracle.com> Message-ID: On 25/10/17 00:43, Maurizio Cimadamore wrote: > lead to the same set of input variables; there is actually a very tiny > difference, in that the latter constraint doesn't add in the input > variable set the input variables of the constraints coming from the > return expressions of the lambda - and that's because, I think, you > can reason about exceptions being thrown by a lambda even if some > return expressions are 'stuck'. Which means I guess, at least > hypothetically, you could write a test where the spec picks > ?/LambdaExpression/ ?_/throws/ T? and decides to process that ahead of > ?/LambdaExpression/ ? T? - while in javac the two happen at the same > time (because javac doesn't have the distinction between these two > constraints - throws constraints are evaluated as part of evaluating > the lambda compatibility constraint). Actually, it's slightly different - that is: ?/LambdaExpression/ ?_/throws/ T? has a _broader_ set of input variables than ??/LambdaExpression/ ? T? As the former includes as input variables all variables mentioned in the return type of the function type derived from T. This reduces the mismatch even further - basically what the spec is saying is that you don't want to process checked exception constraints in cases where the target contains free variables, because such variables might affect the set of thrown types by the lambda. That said, I will have to think more about specific cases where the spec would consider ?/LambdaExpression/ ?_// T? ahead of the companion constraint ?/LambdaExpression/ ?_// throws T?, and see what's the impact in terms of real code. From the looks of it this looks like (i) something that was there even before the regression that this patch is attempting to fix and (ii) probably more in the corner case territory; while non conformance issues should be treated for what they are, I think there's enough of a case here to investigate this as part of a followup issue? Maurizio -------------- next part -------------- An HTML attachment was scrubbed... URL: From bsrbnd at gmail.com Wed Oct 25 13:41:44 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Wed, 25 Oct 2017 15:41:44 +0200 Subject: Linear implementation of Tarjan's algorithm In-Reply-To: References: <451662128.2472977.1508695563065.JavaMail.zimbra@u-pem.fr> <8b879ed0-1c88-1e6d-a477-88797190f202@oracle.com> Message-ID: On 23 October 2017 at 17:58, Maurizio Cimadamore wrote: > To have a better idea of the kind of performance issues we are having in > this area, take a look here: > > https://bugs.openjdk.java.net/browse/JDK-8152289 > > I'm slightly pessimistic that any of the performance fixes discussed here in > the last few weeks would actually make a difference here - the sad reality > is that the cost of doing incorporation dominates pretty much everything > else. And the name of the game to address these kind of issues seem to be to > attempt to reduce the size of the inference graph by finding similarities > between variables [1]/minimize number of propagation steps as much as > possible [2], etc. Of course, 'contains()' isn't the bottleneck here. But with an 'HashStack', this method is up to 10 times faster than with a 'List' (in this example). That said, I observed in the light of your comments that a very large number of same upper bound pairs are checked multiple times. So, I tried to put them in a cache that is cleared at every upper bound change, as here under. It seems to be 3-4 times faster than before for this issue with 60 nodes (on my computer). What do you think? Bernard diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java @@ -939,13 +939,15 @@ @Override void apply(InferenceContext inferenceContext, Warner warn) { List boundList = uv.getBounds(InferenceBound.UPPER).stream() + .filter(b2 -> t != b2) + .filter(b2 -> !upperBoundCache.contains(new Pair<>(t, b2))) .collect(types.closureCollector(true, types::isSameType)); + for (Type b2 : boundList) { - if (t == b2) continue; /* This wildcard check is temporary workaround. This code may need to be * revisited once spec bug JDK-7034922 is fixed. */ - if (t != b2 && !t.hasTag(WILDCARD) && !b2.hasTag(WILDCARD)) { + if (!t.hasTag(WILDCARD) && !b2.hasTag(WILDCARD)) { for (Pair commonSupers : getParameterizedSupers(t, b2)) { List allParamsSuperBound1 = commonSupers.fst.allparams(); List allParamsSuperBound2 = commonSupers.snd.allparams(); @@ -964,6 +966,8 @@ Assert.check(allParamsSuperBound1.isEmpty() && allParamsSuperBound2.isEmpty()); } } + upperBoundCache.add(new Pair<>(t, b2)); + upperBoundCache.add(new Pair<>(b2, t)); } } } @@ -1086,6 +1090,7 @@ } if (ib == InferenceBound.UPPER) { + upperBoundCache.clear(); actions.add(new CheckUpperBounds(uv, t)); } @@ -1125,6 +1130,7 @@ } } finally { incorporationCache.clear(); + upperBoundCache.clear(); } } @@ -1247,6 +1253,7 @@ /** an incorporation cache keeps track of all executed incorporation-related operations */ Map incorporationCache = new HashMap<>(); + HashSet> upperBoundCache = new HashSet<>(); protected static class BoundFilter implements Filter { > [1] - https://bugs.openjdk.java.net/browse/JDK-8046685 > [2] - https://bugs.openjdk.java.net/browse/JDK-8067767 > > Maurizio From maurizio.cimadamore at oracle.com Wed Oct 25 16:16:32 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 25 Oct 2017 17:16:32 +0100 Subject: Linear implementation of Tarjan's algorithm In-Reply-To: References: <451662128.2472977.1508695563065.JavaMail.zimbra@u-pem.fr> <8b879ed0-1c88-1e6d-a477-88797190f202@oracle.com> Message-ID: <6bb6b44c-c842-7c41-0d4b-3877cf5d0bad@oracle.com> On 25/10/17 14:41, B. Blaser wrote: > On 23 October 2017 at 17:58, Maurizio Cimadamore > wrote: >> To have a better idea of the kind of performance issues we are having in >> this area, take a look here: >> >> https://bugs.openjdk.java.net/browse/JDK-8152289 >> >> I'm slightly pessimistic that any of the performance fixes discussed here in >> the last few weeks would actually make a difference here - the sad reality >> is that the cost of doing incorporation dominates pretty much everything >> else. And the name of the game to address these kind of issues seem to be to >> attempt to reduce the size of the inference graph by finding similarities >> between variables [1]/minimize number of propagation steps as much as >> possible [2], etc. > Of course, 'contains()' isn't the bottleneck here. But with an > 'HashStack', this method is up to 10 times faster than with a 'List' > (in this example). > > That said, I observed in the light of your comments that a very large > number of same upper bound pairs are checked multiple times. So, I > tried to put them in a cache that is cleared at every upper bound > change, as here under. It seems to be 3-4 times faster than before for > this issue with 60 nodes (on my computer). > > What do you think? Did you try it with the test case in JDK-8152289? Maurizio > > Bernard > > > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java > b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java > @@ -939,13 +939,15 @@ > @Override > void apply(InferenceContext inferenceContext, Warner warn) { > List boundList = uv.getBounds(InferenceBound.UPPER).stream() > + .filter(b2 -> t != b2) > + .filter(b2 -> !upperBoundCache.contains(new Pair<>(t, b2))) > .collect(types.closureCollector(true, types::isSameType)); > + > for (Type b2 : boundList) { > - if (t == b2) continue; > /* This wildcard check is temporary workaround. > This code may need to be > * revisited once spec bug JDK-7034922 is fixed. > */ > - if (t != b2 && !t.hasTag(WILDCARD) && !b2.hasTag(WILDCARD)) { > + if (!t.hasTag(WILDCARD) && !b2.hasTag(WILDCARD)) { > for (Pair commonSupers : > getParameterizedSupers(t, b2)) { > List allParamsSuperBound1 = > commonSupers.fst.allparams(); > List allParamsSuperBound2 = > commonSupers.snd.allparams(); > @@ -964,6 +966,8 @@ > Assert.check(allParamsSuperBound1.isEmpty() > && allParamsSuperBound2.isEmpty()); > } > } > + upperBoundCache.add(new Pair<>(t, b2)); > + upperBoundCache.add(new Pair<>(b2, t)); > } > } > } > @@ -1086,6 +1090,7 @@ > } > > if (ib == InferenceBound.UPPER) { > + upperBoundCache.clear(); > actions.add(new CheckUpperBounds(uv, t)); > } > > @@ -1125,6 +1130,7 @@ > } > } finally { > incorporationCache.clear(); > + upperBoundCache.clear(); > } > } > > @@ -1247,6 +1253,7 @@ > > /** an incorporation cache keeps track of all executed > incorporation-related operations */ > Map incorporationCache = new HashMap<>(); > + HashSet> upperBoundCache = new HashSet<>(); > > protected static class BoundFilter implements Filter { > > >> [1] - https://bugs.openjdk.java.net/browse/JDK-8046685 >> [2] - https://bugs.openjdk.java.net/browse/JDK-8067767 >> >> Maurizio From bsrbnd at gmail.com Wed Oct 25 16:34:57 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Wed, 25 Oct 2017 18:34:57 +0200 Subject: Linear implementation of Tarjan's algorithm In-Reply-To: <6bb6b44c-c842-7c41-0d4b-3877cf5d0bad@oracle.com> References: <451662128.2472977.1508695563065.JavaMail.zimbra@u-pem.fr> <8b879ed0-1c88-1e6d-a477-88797190f202@oracle.com> <6bb6b44c-c842-7c41-0d4b-3877cf5d0bad@oracle.com> Message-ID: On 25 October 2017 at 18:16, Maurizio Cimadamore wrote: > > > On 25/10/17 14:41, B. Blaser wrote: >> >> On 23 October 2017 at 17:58, Maurizio Cimadamore >> wrote: >>> >>> To have a better idea of the kind of performance issues we are having in >>> this area, take a look here: >>> >>> https://bugs.openjdk.java.net/browse/JDK-8152289 >>> >>> I'm slightly pessimistic that any of the performance fixes discussed here >>> in >>> the last few weeks would actually make a difference here - the sad >>> reality >>> is that the cost of doing incorporation dominates pretty much everything >>> else. And the name of the game to address these kind of issues seem to be >>> to >>> attempt to reduce the size of the inference graph by finding similarities >>> between variables [1]/minimize number of propagation steps as much as >>> possible [2], etc. >> >> Of course, 'contains()' isn't the bottleneck here. But with an >> 'HashStack', this method is up to 10 times faster than with a 'List' >> (in this example). >> >> That said, I observed in the light of your comments that a very large >> number of same upper bound pairs are checked multiple times. So, I >> tried to put them in a cache that is cleared at every upper bound >> change, as here under. It seems to be 3-4 times faster than before for >> this issue with 60 nodes (on my computer). >> >> What do you think? > > Did you try it with the test case in JDK-8152289? Yes, with 20/60/100 points (the gain is different but always appreciable). Of course, only the cache is important (the gain with 'contains()' is only of some milliseconds). Bernard > Maurizio > >> >> Bernard >> >> >> diff --git >> a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >> @@ -939,13 +939,15 @@ >> @Override >> void apply(InferenceContext inferenceContext, Warner warn) { >> List boundList = >> uv.getBounds(InferenceBound.UPPER).stream() >> + .filter(b2 -> t != b2) >> + .filter(b2 -> !upperBoundCache.contains(new Pair<>(t, >> b2))) >> .collect(types.closureCollector(true, >> types::isSameType)); >> + >> for (Type b2 : boundList) { >> - if (t == b2) continue; >> /* This wildcard check is temporary workaround. >> This code may need to be >> * revisited once spec bug JDK-7034922 is fixed. >> */ >> - if (t != b2 && !t.hasTag(WILDCARD) && >> !b2.hasTag(WILDCARD)) { >> + if (!t.hasTag(WILDCARD) && !b2.hasTag(WILDCARD)) { >> for (Pair commonSupers : >> getParameterizedSupers(t, b2)) { >> List allParamsSuperBound1 = >> commonSupers.fst.allparams(); >> List allParamsSuperBound2 = >> commonSupers.snd.allparams(); >> @@ -964,6 +966,8 @@ >> Assert.check(allParamsSuperBound1.isEmpty() >> && allParamsSuperBound2.isEmpty()); >> } >> } >> + upperBoundCache.add(new Pair<>(t, b2)); >> + upperBoundCache.add(new Pair<>(b2, t)); >> } >> } >> } >> @@ -1086,6 +1090,7 @@ >> } >> >> if (ib == InferenceBound.UPPER) { >> + upperBoundCache.clear(); >> actions.add(new CheckUpperBounds(uv, t)); >> } >> >> @@ -1125,6 +1130,7 @@ >> } >> } finally { >> incorporationCache.clear(); >> + upperBoundCache.clear(); >> } >> } >> >> @@ -1247,6 +1253,7 @@ >> >> /** an incorporation cache keeps track of all executed >> incorporation-related operations */ >> Map incorporationCache = new >> HashMap<>(); >> + HashSet> upperBoundCache = new HashSet<>(); >> >> protected static class BoundFilter implements Filter { >> >> >>> [1] - https://bugs.openjdk.java.net/browse/JDK-8046685 >>> [2] - https://bugs.openjdk.java.net/browse/JDK-8067767 >>> >>> Maurizio > > From maurizio.cimadamore at oracle.com Wed Oct 25 16:51:34 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 25 Oct 2017 17:51:34 +0100 Subject: Linear implementation of Tarjan's algorithm In-Reply-To: References: <451662128.2472977.1508695563065.JavaMail.zimbra@u-pem.fr> <8b879ed0-1c88-1e6d-a477-88797190f202@oracle.com> <6bb6b44c-c842-7c41-0d4b-3877cf5d0bad@oracle.com> Message-ID: On 25/10/17 17:34, B. Blaser wrote: > On 25 October 2017 at 18:16, Maurizio Cimadamore > wrote: >> >> On 25/10/17 14:41, B. Blaser wrote: >>> On 23 October 2017 at 17:58, Maurizio Cimadamore >>> wrote: >>>> To have a better idea of the kind of performance issues we are having in >>>> this area, take a look here: >>>> >>>> https://bugs.openjdk.java.net/browse/JDK-8152289 >>>> >>>> I'm slightly pessimistic that any of the performance fixes discussed here >>>> in >>>> the last few weeks would actually make a difference here - the sad >>>> reality >>>> is that the cost of doing incorporation dominates pretty much everything >>>> else. And the name of the game to address these kind of issues seem to be >>>> to >>>> attempt to reduce the size of the inference graph by finding similarities >>>> between variables [1]/minimize number of propagation steps as much as >>>> possible [2], etc. >>> Of course, 'contains()' isn't the bottleneck here. But with an >>> 'HashStack', this method is up to 10 times faster than with a 'List' >>> (in this example). >>> >>> That said, I observed in the light of your comments that a very large >>> number of same upper bound pairs are checked multiple times. So, I >>> tried to put them in a cache that is cleared at every upper bound >>> change, as here under. It seems to be 3-4 times faster than before for >>> this issue with 60 nodes (on my computer). >>> >>> What do you think? >> Did you try it with the test case in JDK-8152289? > Yes, with 20/60/100 points (the gain is different but always appreciable). > Of course, only the cache is important (the gain with 'contains()' is > only of some milliseconds). Could you post some before/after times please? Thanks Maurizio > > Bernard > > >> Maurizio >> >>> Bernard >>> >>> >>> diff --git >>> a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>> @@ -939,13 +939,15 @@ >>> @Override >>> void apply(InferenceContext inferenceContext, Warner warn) { >>> List boundList = >>> uv.getBounds(InferenceBound.UPPER).stream() >>> + .filter(b2 -> t != b2) >>> + .filter(b2 -> !upperBoundCache.contains(new Pair<>(t, >>> b2))) >>> .collect(types.closureCollector(true, >>> types::isSameType)); >>> + >>> for (Type b2 : boundList) { >>> - if (t == b2) continue; >>> /* This wildcard check is temporary workaround. >>> This code may need to be >>> * revisited once spec bug JDK-7034922 is fixed. >>> */ >>> - if (t != b2 && !t.hasTag(WILDCARD) && >>> !b2.hasTag(WILDCARD)) { >>> + if (!t.hasTag(WILDCARD) && !b2.hasTag(WILDCARD)) { >>> for (Pair commonSupers : >>> getParameterizedSupers(t, b2)) { >>> List allParamsSuperBound1 = >>> commonSupers.fst.allparams(); >>> List allParamsSuperBound2 = >>> commonSupers.snd.allparams(); >>> @@ -964,6 +966,8 @@ >>> Assert.check(allParamsSuperBound1.isEmpty() >>> && allParamsSuperBound2.isEmpty()); >>> } >>> } >>> + upperBoundCache.add(new Pair<>(t, b2)); >>> + upperBoundCache.add(new Pair<>(b2, t)); >>> } >>> } >>> } >>> @@ -1086,6 +1090,7 @@ >>> } >>> >>> if (ib == InferenceBound.UPPER) { >>> + upperBoundCache.clear(); >>> actions.add(new CheckUpperBounds(uv, t)); >>> } >>> >>> @@ -1125,6 +1130,7 @@ >>> } >>> } finally { >>> incorporationCache.clear(); >>> + upperBoundCache.clear(); >>> } >>> } >>> >>> @@ -1247,6 +1253,7 @@ >>> >>> /** an incorporation cache keeps track of all executed >>> incorporation-related operations */ >>> Map incorporationCache = new >>> HashMap<>(); >>> + HashSet> upperBoundCache = new HashSet<>(); >>> >>> protected static class BoundFilter implements Filter { >>> >>> >>>> [1] - https://bugs.openjdk.java.net/browse/JDK-8046685 >>>> [2] - https://bugs.openjdk.java.net/browse/JDK-8067767 >>>> >>>> Maurizio >> From bsrbnd at gmail.com Wed Oct 25 17:45:21 2017 From: bsrbnd at gmail.com (B. Blaser) Date: Wed, 25 Oct 2017 19:45:21 +0200 Subject: Linear implementation of Tarjan's algorithm In-Reply-To: References: <451662128.2472977.1508695563065.JavaMail.zimbra@u-pem.fr> <8b879ed0-1c88-1e6d-a477-88797190f202@oracle.com> <6bb6b44c-c842-7c41-0d4b-3877cf5d0bad@oracle.com> Message-ID: On 25 October 2017 at 18:51, Maurizio Cimadamore wrote: > > > On 25/10/17 17:34, B. Blaser wrote: >> >> On 25 October 2017 at 18:16, Maurizio Cimadamore >> wrote: >>> >>> >>> On 25/10/17 14:41, B. Blaser wrote: >>>> >>>> On 23 October 2017 at 17:58, Maurizio Cimadamore >>>> wrote: >>>>> >>>>> To have a better idea of the kind of performance issues we are having >>>>> in >>>>> this area, take a look here: >>>>> >>>>> https://bugs.openjdk.java.net/browse/JDK-8152289 >>>>> >>>>> I'm slightly pessimistic that any of the performance fixes discussed >>>>> here >>>>> in >>>>> the last few weeks would actually make a difference here - the sad >>>>> reality >>>>> is that the cost of doing incorporation dominates pretty much >>>>> everything >>>>> else. And the name of the game to address these kind of issues seem to >>>>> be >>>>> to >>>>> attempt to reduce the size of the inference graph by finding >>>>> similarities >>>>> between variables [1]/minimize number of propagation steps as much as >>>>> possible [2], etc. >>>> >>>> Of course, 'contains()' isn't the bottleneck here. But with an >>>> 'HashStack', this method is up to 10 times faster than with a 'List' >>>> (in this example). >>>> >>>> That said, I observed in the light of your comments that a very large >>>> number of same upper bound pairs are checked multiple times. So, I >>>> tried to put them in a cache that is cleared at every upper bound >>>> change, as here under. It seems to be 3-4 times faster than before for >>>> this issue with 60 nodes (on my computer). >>>> >>>> What do you think? >>> >>> Did you try it with the test case in JDK-8152289? >> >> Yes, with 20/60/100 points (the gain is different but always appreciable). >> Of course, only the cache is important (the gain with 'contains()' is >> only of some milliseconds). > > Could you post some before/after times please? On a quite slow CPU (before -> after): * 20 points - 13s -> 6s * 60 points - 90s -> 24s * 100 points - 551s -> 110s Bernard > Thanks > Maurizio > >> >> Bernard >> >> >>> Maurizio >>> >>>> Bernard >>>> >>>> >>>> diff --git >>>> a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>>> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>>> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>>> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>>> @@ -939,13 +939,15 @@ >>>> @Override >>>> void apply(InferenceContext inferenceContext, Warner warn) { >>>> List boundList = >>>> uv.getBounds(InferenceBound.UPPER).stream() >>>> + .filter(b2 -> t != b2) >>>> + .filter(b2 -> !upperBoundCache.contains(new >>>> Pair<>(t, >>>> b2))) >>>> .collect(types.closureCollector(true, >>>> types::isSameType)); >>>> + >>>> for (Type b2 : boundList) { >>>> - if (t == b2) continue; >>>> /* This wildcard check is temporary workaround. >>>> This code may need to be >>>> * revisited once spec bug JDK-7034922 is fixed. >>>> */ >>>> - if (t != b2 && !t.hasTag(WILDCARD) && >>>> !b2.hasTag(WILDCARD)) { >>>> + if (!t.hasTag(WILDCARD) && !b2.hasTag(WILDCARD)) { >>>> for (Pair commonSupers : >>>> getParameterizedSupers(t, b2)) { >>>> List allParamsSuperBound1 = >>>> commonSupers.fst.allparams(); >>>> List allParamsSuperBound2 = >>>> commonSupers.snd.allparams(); >>>> @@ -964,6 +966,8 @@ >>>> Assert.check(allParamsSuperBound1.isEmpty() >>>> && allParamsSuperBound2.isEmpty()); >>>> } >>>> } >>>> + upperBoundCache.add(new Pair<>(t, b2)); >>>> + upperBoundCache.add(new Pair<>(b2, t)); >>>> } >>>> } >>>> } >>>> @@ -1086,6 +1090,7 @@ >>>> } >>>> >>>> if (ib == InferenceBound.UPPER) { >>>> + upperBoundCache.clear(); >>>> actions.add(new CheckUpperBounds(uv, t)); >>>> } >>>> >>>> @@ -1125,6 +1130,7 @@ >>>> } >>>> } finally { >>>> incorporationCache.clear(); >>>> + upperBoundCache.clear(); >>>> } >>>> } >>>> >>>> @@ -1247,6 +1253,7 @@ >>>> >>>> /** an incorporation cache keeps track of all executed >>>> incorporation-related operations */ >>>> Map incorporationCache = new >>>> HashMap<>(); >>>> + HashSet> upperBoundCache = new HashSet<>(); >>>> >>>> protected static class BoundFilter implements Filter { >>>> >>>> >>>>> [1] - https://bugs.openjdk.java.net/browse/JDK-8046685 >>>>> [2] - https://bugs.openjdk.java.net/browse/JDK-8067767 >>>>> >>>>> Maurizio >>> >>> > From maurizio.cimadamore at oracle.com Wed Oct 25 20:16:51 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Wed, 25 Oct 2017 21:16:51 +0100 Subject: Linear implementation of Tarjan's algorithm In-Reply-To: References: <451662128.2472977.1508695563065.JavaMail.zimbra@u-pem.fr> <8b879ed0-1c88-1e6d-a477-88797190f202@oracle.com> <6bb6b44c-c842-7c41-0d4b-3877cf5d0bad@oracle.com> Message-ID: <7ba40e17-cb0b-1641-9e49-5391f55bae1c@oracle.com> Thanks for testing - I imagined something similar - our target here is what is said in the bug report: "In JDK 7, compilation takes less than a second." (this is with 100 points). Your tests show that the smaller the inference graph, the smaller the gain (you start from 2x, and you end with 5x). But for bigger graphs, these kind of improvements are not going to cut it (still 2mins against <1s in JDK 7). And, if you fix this at a deeper level, so that the incorporation has to do less work, then you go back to subsecond compilation, in which case the contribution of your optimization is likely to be negligible. So, I don't want to sound overly critical (I realize I can sound that way sometimes) - you did a great experiment, and it's showing some good numbers - but the real problem here is that in JDK 7, _no matter how many nodes you had_ compilation always stayed subsecond. So, when I see a compilation time that increase depending on how many nested call you add, I worry - because, no matter how you optimize, you can always add few extra nodes and go back being as slow as you were (or more!) before the optimization. During JDK 9 we did a great job at optimizing this pattern: m1(m2(m3 .... mN() ) ) ) ) I think it's time we do something similar for m(g1(), g2(), ... gN()) Note that when we made incorporation smart enough to detect the first case, all other performance related concerns became negligible - I'm hoping we can pull a similar trick here (and we have few ideas on how to do that). Cheers Maurizio On 25/10/17 18:45, B. Blaser wrote: > On 25 October 2017 at 18:51, Maurizio Cimadamore > wrote: >> >> On 25/10/17 17:34, B. Blaser wrote: >>> On 25 October 2017 at 18:16, Maurizio Cimadamore >>> wrote: >>>> >>>> On 25/10/17 14:41, B. Blaser wrote: >>>>> On 23 October 2017 at 17:58, Maurizio Cimadamore >>>>> wrote: >>>>>> To have a better idea of the kind of performance issues we are having >>>>>> in >>>>>> this area, take a look here: >>>>>> >>>>>> https://bugs.openjdk.java.net/browse/JDK-8152289 >>>>>> >>>>>> I'm slightly pessimistic that any of the performance fixes discussed >>>>>> here >>>>>> in >>>>>> the last few weeks would actually make a difference here - the sad >>>>>> reality >>>>>> is that the cost of doing incorporation dominates pretty much >>>>>> everything >>>>>> else. And the name of the game to address these kind of issues seem to >>>>>> be >>>>>> to >>>>>> attempt to reduce the size of the inference graph by finding >>>>>> similarities >>>>>> between variables [1]/minimize number of propagation steps as much as >>>>>> possible [2], etc. >>>>> Of course, 'contains()' isn't the bottleneck here. But with an >>>>> 'HashStack', this method is up to 10 times faster than with a 'List' >>>>> (in this example). >>>>> >>>>> That said, I observed in the light of your comments that a very large >>>>> number of same upper bound pairs are checked multiple times. So, I >>>>> tried to put them in a cache that is cleared at every upper bound >>>>> change, as here under. It seems to be 3-4 times faster than before for >>>>> this issue with 60 nodes (on my computer). >>>>> >>>>> What do you think? >>>> Did you try it with the test case in JDK-8152289? >>> Yes, with 20/60/100 points (the gain is different but always appreciable). >>> Of course, only the cache is important (the gain with 'contains()' is >>> only of some milliseconds). >> Could you post some before/after times please? > On a quite slow CPU (before -> after): > * 20 points - 13s -> 6s > * 60 points - 90s -> 24s > * 100 points - 551s -> 110s > > Bernard > >> Thanks >> Maurizio >> >>> Bernard >>> >>> >>>> Maurizio >>>> >>>>> Bernard >>>>> >>>>> >>>>> diff --git >>>>> a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>>>> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>>>> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>>>> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java >>>>> @@ -939,13 +939,15 @@ >>>>> @Override >>>>> void apply(InferenceContext inferenceContext, Warner warn) { >>>>> List boundList = >>>>> uv.getBounds(InferenceBound.UPPER).stream() >>>>> + .filter(b2 -> t != b2) >>>>> + .filter(b2 -> !upperBoundCache.contains(new >>>>> Pair<>(t, >>>>> b2))) >>>>> .collect(types.closureCollector(true, >>>>> types::isSameType)); >>>>> + >>>>> for (Type b2 : boundList) { >>>>> - if (t == b2) continue; >>>>> /* This wildcard check is temporary workaround. >>>>> This code may need to be >>>>> * revisited once spec bug JDK-7034922 is fixed. >>>>> */ >>>>> - if (t != b2 && !t.hasTag(WILDCARD) && >>>>> !b2.hasTag(WILDCARD)) { >>>>> + if (!t.hasTag(WILDCARD) && !b2.hasTag(WILDCARD)) { >>>>> for (Pair commonSupers : >>>>> getParameterizedSupers(t, b2)) { >>>>> List allParamsSuperBound1 = >>>>> commonSupers.fst.allparams(); >>>>> List allParamsSuperBound2 = >>>>> commonSupers.snd.allparams(); >>>>> @@ -964,6 +966,8 @@ >>>>> Assert.check(allParamsSuperBound1.isEmpty() >>>>> && allParamsSuperBound2.isEmpty()); >>>>> } >>>>> } >>>>> + upperBoundCache.add(new Pair<>(t, b2)); >>>>> + upperBoundCache.add(new Pair<>(b2, t)); >>>>> } >>>>> } >>>>> } >>>>> @@ -1086,6 +1090,7 @@ >>>>> } >>>>> >>>>> if (ib == InferenceBound.UPPER) { >>>>> + upperBoundCache.clear(); >>>>> actions.add(new CheckUpperBounds(uv, t)); >>>>> } >>>>> >>>>> @@ -1125,6 +1130,7 @@ >>>>> } >>>>> } finally { >>>>> incorporationCache.clear(); >>>>> + upperBoundCache.clear(); >>>>> } >>>>> } >>>>> >>>>> @@ -1247,6 +1253,7 @@ >>>>> >>>>> /** an incorporation cache keeps track of all executed >>>>> incorporation-related operations */ >>>>> Map incorporationCache = new >>>>> HashMap<>(); >>>>> + HashSet> upperBoundCache = new HashSet<>(); >>>>> >>>>> protected static class BoundFilter implements Filter { >>>>> >>>>> >>>>>> [1] - https://bugs.openjdk.java.net/browse/JDK-8046685 >>>>>> [2] - https://bugs.openjdk.java.net/browse/JDK-8067767 >>>>>> >>>>>> Maurizio >>>> From jan.lahoda at oracle.com Thu Oct 26 09:35:46 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Thu, 26 Oct 2017 11:35:46 +0200 Subject: RFR: JDK-8189778: Jshell crash on tab for StringBuilder.append( Message-ID: <59F1AC72.4020202@oracle.com> Hi, Typing: jshell> StringBuilder sb = new StringBuilder(); jshell> sb.append( Will lead to an exception: jshell> sb.append(Exception in thread "main" java.lang.StringIndexOutOfBoundsException: start -59, end -59, length 238 [snip] jdk.compiler/jdk.internal.shellsupport.doc.JavadocHelper$OnDemandJavadocHelper.getResolvedDocComment(JavadocHelper.java:481) The reason is that the javadoc for StringBuilder.append(CharSequence, int, int) is: /** * @throws IndexOutOfBoundsException {@inheritDoc} */ The JavadocHelper tries to fill in the missing javadoc entries, but that fails because it tries to insert the preceding entries at an uninitialized place. The proposed patch: -fixes the above -adds a test that runs the JavadocHelper on all methods/fields/constructors of top-level types in all exported packages (this runs for a considerable time, and we may need to disable this test if it proves to be too heavyweight) -adds a few more test cases for problems found by the above test -fixes the javadoc resolution to treat missing javadoc body as {@inheritDoc} (so that the overridden method's javadoc text is used if missing in this method) Bug: https://bugs.openjdk.java.net/browse/JDK-8189778 Webrev: http://cr.openjdk.java.net/~jlahoda/8189778/webrev.00/ Feedback is welcome. Thanks, Jan From maurizio.cimadamore at oracle.com Thu Oct 26 15:09:23 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 26 Oct 2017 16:09:23 +0100 Subject: RFR 8189838: Stack overflow when computing upward projection of an intersection type with fbounds Message-ID: <34b1c0e3-f102-287f-0277-0f62e5157c69@oracle.com> Hi, the patch fixes a bug in the logic for detecting fbounds loop in the LVTI upward projection logic. Basically when we recurse projection on a type-variable (upper) bound, we must keep track of the variable somewhere, as the bound can contain the variable itself, and lead to infinite loops. I was aware of the situation and the original code was already doing something in this regard - however, the try/finally used to add/remove the variable to the list of seen variables was too broad, and it ended up also removing type-var in case of cycles, thus defeating the purpose of the logic, at least in certain examples. I've rectified the logic so that now a variable is removed from the list at the end of its projection _only_ if no cycle has been detected. Also, when a cycle is indeed detected, we need to return either Object or depending on the projection kind. Webrev here: http://cr.openjdk.java.net/~mcimadamore/8189838/ Cheers Maurizio From paul.sandoz at oracle.com Thu Oct 26 17:03:15 2017 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 26 Oct 2017 10:03:15 -0700 Subject: [10] RFR 8186046 Minimal ConstantDynamic support Message-ID: Hi, Please review the following patch for minimal dynamic constant support: http://cr.openjdk.java.net/~psandoz/jdk10/JDK-8186046-minimal-condy-support-hs/webrev/ https://bugs.openjdk.java.net/browse/JDK-8186046 https://bugs.openjdk.java.net/browse/JDK-8186209 This patch is based on the JDK 10 unified HotSpot repository. Testing so far looks good. By minimal i mean just the support in the runtime for a dynamic constant pool entry to be referenced by a LDC instruction or a bootstrap method argument. Much of the work leverages the foundations built by invoke dynamic but is arguably simpler since resolution is less complex. A small set of bootstrap methods will be proposed as a follow on issue for 10 (these are currently being refined in the amber repository). Bootstrap method invocation has not changed (and the rules are the same for dynamic constants and indy). It is planned to enhance this in a further major release to support lazy resolution of bootstrap method arguments. The CSR for the VM specification is here: https://bugs.openjdk.java.net/browse/JDK-8189199 the j.l.invoke package documentation was also updated but please consider the VM specification as the definitive "source of truth" (we may clean up this area further later on so it becomes more informative, and that may also apply to duplicative text on MethodHandles/VarHandles). Any AoT-related work will be deferred to a future release. ? This patch only supports x64 platforms. There is a small set of changes specific to x64 (specifically to support null and primitives constants, as prior to this patch null was used as a sentinel for resolution and certain primitives types would never have been encountered, such as say byte). We will need to follow up with the SPARC platform and it is hoped/anticipated that OpenJDK members responsible for other platforms (namely ARM and PPC) will separately provide patches. ? Many of tests rely on an experimental byte code API that supports the generation of byte code with dynamic constants. One test uses class file bytes produced from a modified version of asmtools. The modifications have now been pushed but a new version of asmtools need to be rolled into jtreg before the test can operate directly on asmtools information rather than embedding class file bytes directly in the test. ? Paul. -------------- next part -------------- An HTML attachment was scrubbed... URL: From joe.darcy at oracle.com Thu Oct 26 17:13:29 2017 From: joe.darcy at oracle.com (joe darcy) Date: Thu, 26 Oct 2017 10:13:29 -0700 Subject: JDK 10 RFR of JDK-8172818: Add since=9 deprecation information to javax.lang.model classes Message-ID: Hello, Now that JDK 10 is used JDK 9 for bootstrapping, the deprecated elements in the java.compiler package can indicate the new-in-9 "since" information for a deprecated annotation. (Since java.compiler is compiled using the boot JDK, in JDK 9 the since information could not be included because Deprecated.since is not usable with JDK 8.) Unix tools find, grep, sed, etc. were used to locate and replace @Deprecated with @Deprecated(since="9") in the java.compiler module. Patch below. I'll double-check the copyright years before pushing. Thanks, -Joe diff -r fd458b0b7749 src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java Wed Oct 25 10:40:45 2017 -0700 +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java Thu Oct 26 10:10:19 2017 -0700 @@ -75,7 +75,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected AbstractAnnotationValueVisitor6() {} /** diff -r fd458b0b7749 src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java Wed Oct 25 10:40:45 2017 -0700 +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java Thu Oct 26 10:10:19 2017 -0700 @@ -75,7 +75,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected AbstractElementVisitor6(){} /** diff -r fd458b0b7749 src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java --- a/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java Wed Oct 25 10:40:45 2017 -0700 +++ b/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java Thu Oct 26 10:10:19 2017 -0700 @@ -74,7 +74,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected AbstractTypeVisitor6() {} /** diff -r fd458b0b7749 src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor6.java --- a/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor6.java Wed Oct 25 10:40:45 2017 -0700 +++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor6.java Thu Oct 26 10:10:19 2017 -0700 @@ -91,7 +91,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected ElementKindVisitor6() { super(null); } @@ -104,7 +104,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected ElementKindVisitor6(R defaultValue) { super(defaultValue); } diff -r fd458b0b7749 src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java --- a/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java Wed Oct 25 10:40:45 2017 -0700 +++ b/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java Thu Oct 26 10:10:19 2017 -0700 @@ -106,7 +106,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected ElementScanner6(){ DEFAULT_VALUE = null; } @@ -119,7 +119,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected ElementScanner6(R defaultValue){ DEFAULT_VALUE = defaultValue; } diff -r fd458b0b7749 src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java Wed Oct 25 10:40:45 2017 -0700 +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java Thu Oct 26 10:10:19 2017 -0700 @@ -92,7 +92,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected SimpleAnnotationValueVisitor6() { super(); DEFAULT_VALUE = null; @@ -106,7 +106,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected SimpleAnnotationValueVisitor6(R defaultValue) { super(); DEFAULT_VALUE = defaultValue; diff -r fd458b0b7749 src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor6.java --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor6.java Wed Oct 25 10:40:45 2017 -0700 +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor6.java Thu Oct 26 10:10:19 2017 -0700 @@ -94,7 +94,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected SimpleElementVisitor6(){ DEFAULT_VALUE = null; } @@ -107,7 +107,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected SimpleElementVisitor6(R defaultValue){ DEFAULT_VALUE = defaultValue; } diff -r fd458b0b7749 src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java --- a/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java Wed Oct 25 10:40:45 2017 -0700 +++ b/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java Thu Oct 26 10:10:19 2017 -0700 @@ -94,7 +94,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected SimpleTypeVisitor6(){ DEFAULT_VALUE = null; } @@ -107,7 +107,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected SimpleTypeVisitor6(R defaultValue){ DEFAULT_VALUE = defaultValue; } diff -r fd458b0b7749 src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java --- a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java Wed Oct 25 10:40:45 2017 -0700 +++ b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java Thu Oct 26 10:10:19 2017 -0700 @@ -85,7 +85,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected TypeKindVisitor6() { super(null); } @@ -99,7 +99,7 @@ * @deprecated Release 6 is obsolete; update to a visitor for a newer * release level. */ - @Deprecated + @Deprecated(since="9") protected TypeKindVisitor6(R defaultValue) { super(defaultValue); } diff -r fd458b0b7749 src/java.compiler/share/classes/javax/tools/ToolProvider.java --- a/src/java.compiler/share/classes/javax/tools/ToolProvider.java Wed Oct 25 10:40:45 2017 -0700 +++ b/src/java.compiler/share/classes/javax/tools/ToolProvider.java Thu Oct 26 10:10:19 2017 -0700 @@ -96,7 +96,7 @@ * locate system tools as well as user-installed tools. * @return a class loader, or {@code null} */ - @Deprecated + @Deprecated(since="9") public static ClassLoader getSystemToolClassLoader() { return null; } From vicente.romero at oracle.com Thu Oct 26 17:36:43 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 26 Oct 2017 13:36:43 -0400 Subject: RFR 8189838: Stack overflow when computing upward projection of an intersection type with fbounds In-Reply-To: <34b1c0e3-f102-287f-0277-0f62e5157c69@oracle.com> References: <34b1c0e3-f102-287f-0277-0f62e5157c69@oracle.com> Message-ID: <6dbcbf2b-db9f-be99-bda1-d2f3578b4001@oracle.com> looks good, Vicente On 10/26/2017 11:09 AM, Maurizio Cimadamore wrote: > Hi, > the patch fixes a bug in the logic for detecting fbounds loop in the > LVTI upward projection logic. Basically when we recurse projection on > a type-variable (upper) bound, we must keep track of the variable > somewhere, as the bound can contain the variable itself, and lead to > infinite loops. > > I was aware of the situation and the original code was already doing > something in this regard - however, the try/finally used to add/remove > the variable to the list of seen variables was too broad, and it ended > up also removing type-var in case of cycles, thus defeating the > purpose of the logic, at least in certain examples. > > I've rectified the logic so that now a variable is removed from the > list at the end of its projection _only_ if no cycle has been > detected. Also, when a cycle is indeed detected, we need to return > either Object or depending on the projection kind. > > Webrev here: > > http://cr.openjdk.java.net/~mcimadamore/8189838/ > > Cheers > Maurizio > From maurizio.cimadamore at oracle.com Thu Oct 26 17:49:02 2017 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 26 Oct 2017 18:49:02 +0100 Subject: RFR 8189838: Stack overflow when computing upward projection of an intersection type with fbounds In-Reply-To: <6dbcbf2b-db9f-be99-bda1-d2f3578b4001@oracle.com> References: <34b1c0e3-f102-287f-0277-0f62e5157c69@oracle.com> <6dbcbf2b-db9f-be99-bda1-d2f3578b4001@oracle.com> Message-ID: <78f00a0e-9f3d-024f-f939-e9a81cd6589a@oracle.com> Thanks - pushed. Maurizio On 26/10/17 18:36, Vicente Romero wrote: > looks good, > > Vicente > > On 10/26/2017 11:09 AM, Maurizio Cimadamore wrote: >> Hi, >> the patch fixes a bug in the logic for detecting fbounds loop in the >> LVTI upward projection logic. Basically when we recurse projection on >> a type-variable (upper) bound, we must keep track of the variable >> somewhere, as the bound can contain the variable itself, and lead to >> infinite loops. >> >> I was aware of the situation and the original code was already doing >> something in this regard - however, the try/finally used to >> add/remove the variable to the list of seen variables was too broad, >> and it ended up also removing type-var in case of cycles, thus >> defeating the purpose of the logic, at least in certain examples. >> >> I've rectified the logic so that now a variable is removed from the >> list at the end of its projection _only_ if no cycle has been >> detected. Also, when a cycle is indeed detected, we need to return >> either Object or depending on the projection kind. >> >> Webrev here: >> >> http://cr.openjdk.java.net/~mcimadamore/8189838/ >> >> Cheers >> Maurizio >> > From joe.darcy at oracle.com Thu Oct 26 18:17:09 2017 From: joe.darcy at oracle.com (joe darcy) Date: Thu, 26 Oct 2017 11:17:09 -0700 Subject: JDK 10 RFR of JDK-8146726: Refactor AbstractProcessor to use Set.of and related methods Message-ID: Hello, With JDK 9 APIs now available for use in java.compiler, please the patch below to address JDK-8146726: Refactor AbstractProcessor to use Set.of and related methods Thanks, -Joe diff -r fd458b0b7749 src/java.compiler/share/classes/javax/annotation/processing/AbstractProcessor.java --- a/src/java.compiler/share/classes/javax/annotation/processing/AbstractProcessor.java Wed Oct 25 10:40:45 2017 -0700 +++ b/src/java.compiler/share/classes/javax/annotation/processing/AbstractProcessor.java Thu Oct 26 11:15:58 2017 -0700 @@ -80,10 +80,7 @@ */ public Set getSupportedOptions() { SupportedOptions so = this.getClass().getAnnotation(SupportedOptions.class); - if (so == null) - return Collections.emptySet(); - else - return arrayToSet(so.value(), false); + return (so == null) ? Collections.emptySet() : Set.of(so.value()); } /** @@ -198,15 +195,15 @@ private static Set arrayToSet(String[] array, boolean stripModulePrefixes) { assert array != null; - Set set = new HashSet<>(array.length); - for (String s : array) { - if (stripModulePrefixes) { + if (stripModulePrefixes) { + array = array.clone(); + for (int i = 0; i < array.length; i++) { + String s = array[i]; int index = s.indexOf('/'); if (index != -1) - s = s.substring(index + 1); + array[i] = s.substring(index + 1); } - set.add(s); } - return Collections.unmodifiableSet(set); + return Set.of(array); } } From vicente.romero at oracle.com Thu Oct 26 23:05:09 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 26 Oct 2017 19:05:09 -0400 Subject: JDK 10 RFR of JDK-8172818: Add since=9 deprecation information to javax.lang.model classes In-Reply-To: References: Message-ID: <575c1126-81ed-7c4e-d2b5-55d2dec1482c@oracle.com> looks good, Vicente On 10/26/2017 01:13 PM, joe darcy wrote: > Hello, > > Now that JDK 10 is used JDK 9 for bootstrapping, the deprecated > elements in the java.compiler package can indicate the new-in-9 > "since" information for a deprecated annotation. (Since java.compiler > is compiled using the boot JDK, in JDK 9 the since information could > not be included because Deprecated.since is not usable with JDK 8.) > > Unix tools find, grep, sed, etc. were used to locate and replace > > ??? @Deprecated > > with > > @Deprecated(since="9") > > in the java.compiler module. > > Patch below. I'll double-check the copyright years before pushing. > > Thanks, > > -Joe > > > diff -r fd458b0b7749 > src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java > --- > a/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java > Wed Oct 25 10:40:45 2017 -0700 > +++ > b/src/java.compiler/share/classes/javax/lang/model/util/AbstractAnnotationValueVisitor6.java > Thu Oct 26 10:10:19 2017 -0700 > @@ -75,7 +75,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected AbstractAnnotationValueVisitor6() {} > > ???? /** > diff -r fd458b0b7749 > src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java > --- > a/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java > Wed Oct 25 10:40:45 2017 -0700 > +++ > b/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java > Thu Oct 26 10:10:19 2017 -0700 > @@ -75,7 +75,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected AbstractElementVisitor6(){} > > ???? /** > diff -r fd458b0b7749 > src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java > --- > a/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java > Wed Oct 25 10:40:45 2017 -0700 > +++ > b/src/java.compiler/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java > Thu Oct 26 10:10:19 2017 -0700 > @@ -74,7 +74,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected AbstractTypeVisitor6() {} > > ???? /** > diff -r fd458b0b7749 > src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor6.java > --- > a/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor6.java > Wed Oct 25 10:40:45 2017 -0700 > +++ > b/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor6.java > Thu Oct 26 10:10:19 2017 -0700 > @@ -91,7 +91,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected ElementKindVisitor6() { > ???????? super(null); > ???? } > @@ -104,7 +104,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected ElementKindVisitor6(R defaultValue) { > ???????? super(defaultValue); > ???? } > diff -r fd458b0b7749 > src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java > --- > a/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java > Wed Oct 25 10:40:45 2017 -0700 > +++ > b/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner6.java > Thu Oct 26 10:10:19 2017 -0700 > @@ -106,7 +106,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected ElementScanner6(){ > ???????? DEFAULT_VALUE = null; > ???? } > @@ -119,7 +119,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected ElementScanner6(R defaultValue){ > ???????? DEFAULT_VALUE = defaultValue; > ???? } > diff -r fd458b0b7749 > src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java > --- > a/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java > Wed Oct 25 10:40:45 2017 -0700 > +++ > b/src/java.compiler/share/classes/javax/lang/model/util/SimpleAnnotationValueVisitor6.java > Thu Oct 26 10:10:19 2017 -0700 > @@ -92,7 +92,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected SimpleAnnotationValueVisitor6() { > ???????? super(); > ???????? DEFAULT_VALUE = null; > @@ -106,7 +106,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected SimpleAnnotationValueVisitor6(R defaultValue) { > ???????? super(); > ???????? DEFAULT_VALUE = defaultValue; > diff -r fd458b0b7749 > src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor6.java > --- > a/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor6.java > Wed Oct 25 10:40:45 2017 -0700 > +++ > b/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor6.java > Thu Oct 26 10:10:19 2017 -0700 > @@ -94,7 +94,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected SimpleElementVisitor6(){ > ???????? DEFAULT_VALUE = null; > ???? } > @@ -107,7 +107,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected SimpleElementVisitor6(R defaultValue){ > ???????? DEFAULT_VALUE = defaultValue; > ???? } > diff -r fd458b0b7749 > src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java > --- > a/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java > Wed Oct 25 10:40:45 2017 -0700 > +++ > b/src/java.compiler/share/classes/javax/lang/model/util/SimpleTypeVisitor6.java > Thu Oct 26 10:10:19 2017 -0700 > @@ -94,7 +94,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected SimpleTypeVisitor6(){ > ???????? DEFAULT_VALUE = null; > ???? } > @@ -107,7 +107,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected SimpleTypeVisitor6(R defaultValue){ > ???????? DEFAULT_VALUE = defaultValue; > ???? } > diff -r fd458b0b7749 > src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java > --- > a/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java > Wed Oct 25 10:40:45 2017 -0700 > +++ > b/src/java.compiler/share/classes/javax/lang/model/util/TypeKindVisitor6.java > Thu Oct 26 10:10:19 2017 -0700 > @@ -85,7 +85,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected TypeKindVisitor6() { > ???????? super(null); > ???? } > @@ -99,7 +99,7 @@ > ????? * @deprecated Release 6 is obsolete; update to a visitor for a > newer > ????? * release level. > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? protected TypeKindVisitor6(R defaultValue) { > ???????? super(defaultValue); > ???? } > diff -r fd458b0b7749 > src/java.compiler/share/classes/javax/tools/ToolProvider.java > --- a/src/java.compiler/share/classes/javax/tools/ToolProvider.java > Wed Oct 25 10:40:45 2017 -0700 > +++ b/src/java.compiler/share/classes/javax/tools/ToolProvider.java > Thu Oct 26 10:10:19 2017 -0700 > @@ -96,7 +96,7 @@ > ????? * locate system tools as well as user-installed tools. > ????? * @return a class loader, or {@code null} > ????? */ > -??? @Deprecated > +??? @Deprecated(since="9") > ???? public static ClassLoader getSystemToolClassLoader() { > ???????? return null; > ???? } > From vicente.romero at oracle.com Fri Oct 27 00:31:42 2017 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 26 Oct 2017 20:31:42 -0400 Subject: JDK 10 RFR of JDK-8146726: Refactor AbstractProcessor to use Set.of and related methods In-Reply-To: References: Message-ID: does it make sense to remove method arrayToSet() and inline the code in its only client? Thanks, Vicente On 10/26/2017 02:17 PM, joe darcy wrote: > Hello, > > With JDK 9 APIs now available for use in java.compiler, please the > patch below to address > > ??? JDK-8146726: Refactor AbstractProcessor to use Set.of and related > methods > > Thanks, > > -Joe > > diff -r fd458b0b7749 > src/java.compiler/share/classes/javax/annotation/processing/AbstractProcessor.java > --- > a/src/java.compiler/share/classes/javax/annotation/processing/AbstractProcessor.java > Wed Oct 25 10:40:45 2017 -0700 > +++ > b/src/java.compiler/share/classes/javax/annotation/processing/AbstractProcessor.java > Thu Oct 26 11:15:58 2017 -0700 > @@ -80,10 +80,7 @@ > ????? */ > ???? public Set getSupportedOptions() { > ???????? SupportedOptions so = > this.getClass().getAnnotation(SupportedOptions.class); > -??????? if? (so == null) > -??????????? return Collections.emptySet(); > -??????? else > -??????????? return arrayToSet(so.value(), false); > +??????? return (so == null) ? Collections.emptySet() : > Set.of(so.value()); > ???? } > > ???? /** > @@ -198,15 +195,15 @@ > ???? private static Set arrayToSet(String[] array, > ?????????????????????????????????????????? boolean stripModulePrefixes) { > ???????? assert array != null; > -??????? Set set = new HashSet<>(array.length); > -??????? for (String s : array) { > -??????????? if (stripModulePrefixes) { > +??????? if (stripModulePrefixes) { > +??????????? array = array.clone(); > +??????????? for (int i = 0; i < array.length; i++) { > +??????????????? String s = array[i]; > ???????????????? int index = s.indexOf('/'); > ???????????????? if (index != -1) > -??????????????????? s = s.substring(index + 1); > +??????????????????? array[i] = s.substring(index + 1); > ???????????? } > -??????????? set.add(s); > ???????? } > -??????? return Collections.unmodifiableSet(set); > +??????? return Set.of(array); > ???? } > ?} > > From paul.sandoz at oracle.com Mon Oct 30 19:44:54 2017 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 30 Oct 2017 12:44:54 -0700 Subject: [10] RFR 8186046 Minimal ConstantDynamic support In-Reply-To: References: Message-ID: <93431280-9CBF-4722-961D-F2D2D0F83B4E@oracle.com> Hi, Thanks for reviewing. > On 30 Oct 2017, at 11:05, Dmitry Samersoff wrote: > > Paul, > > templateTable_x86.cpp: > > 564 const Register flags = rcx; > 565 const Register rarg = NOT_LP64(rcx) LP64_ONLY(c_rarg1); > > Should we use another register for rarg under NOT_LP64 ? > I think it should be ok, it i ain?t an expert here on the interpreter and the calling conventions, so please correct me. Some more context: + const Register flags = rcx; + const Register rarg = NOT_LP64(rcx) LP64_ONLY(c_rarg1); + __ movl(rarg, (int)bytecode()); The current bytecode code is loaded into ?rarg? + call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc), rarg); Then ?rarg" is the argument to the call to InterpreterRuntime::resolve_ldc, after which it is no longer referred to. +#ifndef _LP64 + // borrow rdi from locals + __ get_thread(rdi); + __ get_vm_result_2(flags, rdi); + __ restore_locals(); +#else + __ get_vm_result_2(flags, r15_thread); +#endif The result from the call is then loaded into flags. So i don?t think it matters in this case if rcx is aliased. Paul. > -Dmitry > > > On 10/26/2017 08:03 PM, Paul Sandoz wrote: >> Hi, >> >> Please review the following patch for minimal dynamic constant support: >> >> http://cr.openjdk.java.net/~psandoz/jdk10/JDK-8186046-minimal-condy-support-hs/webrev/ >> >> https://bugs.openjdk.java.net/browse/JDK-8186046 >> https://bugs.openjdk.java.net/browse/JDK-8186209 >> >> This patch is based on the JDK 10 unified HotSpot repository. Testing so far looks good. >> >> By minimal i mean just the support in the runtime for a dynamic constant pool entry to be referenced by a LDC instruction or a bootstrap method argument. Much of the work leverages the foundations built by invoke dynamic but is arguably simpler since resolution is less complex. >> >> A small set of bootstrap methods will be proposed as a follow on issue for 10 (these are currently being refined in the amber repository). >> >> Bootstrap method invocation has not changed (and the rules are the same for dynamic constants and indy). It is planned to enhance this in a further major release to support lazy resolution of bootstrap method arguments. >> >> The CSR for the VM specification is here: >> >> https://bugs.openjdk.java.net/browse/JDK-8189199 >> >> the j.l.invoke package documentation was also updated but please consider the VM specification as the definitive "source of truth" (we may clean up this area further later on so it becomes more informative, and that may also apply to duplicative text on MethodHandles/VarHandles). >> >> Any AoT-related work will be deferred to a future release. >> >> ? >> >> This patch only supports x64 platforms. There is a small set of changes specific to x64 (specifically to support null and primitives constants, as prior to this patch null was used as a sentinel for resolution and certain primitives types would never have been encountered, such as say byte). >> >> We will need to follow up with the SPARC platform and it is hoped/anticipated that OpenJDK members responsible for other platforms (namely ARM and PPC) will separately provide patches. >> >> ? >> >> Many of tests rely on an experimental byte code API that supports the generation of byte code with dynamic constants. >> >> One test uses class file bytes produced from a modified version of asmtools. The modifications have now been pushed but a new version of asmtools need to be rolled into jtreg before the test can operate directly on asmtools information rather than embedding class file bytes directly in the test. >> >> ? >> >> Paul. >> > From jan.lahoda at oracle.com Mon Oct 30 20:35:19 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Mon, 30 Oct 2017 21:35:19 +0100 Subject: RFR JDK-8190315: Test tools/javac/tree/NoPrivateTypesExported.java failing Message-ID: <59F78D07.8050508@oracle.com> Hi, test/langtools/tools/javac/tree/NoPrivateTypesExported.java is failing. The intent of the test is to verify the API elements don't refer to non-public types. This is similar to Xlint:exports, but older. Seems reasonable to keep the test for now, despite it might be superseded by -Xlint:exports. The issue why the test is failing is that it does not ignore constant annotation values, which the proposed fix is doing: Bug: https://bugs.openjdk.java.net/browse/JDK-8190315 Webrev: http://cr.openjdk.java.net/~jlahoda/8190315/webrev.00/ Thanks, Jan From frederic.parain at oracle.com Mon Oct 30 21:56:37 2017 From: frederic.parain at oracle.com (Frederic Parain) Date: Mon, 30 Oct 2017 17:56:37 -0400 Subject: [10] RFR 8186046 Minimal ConstantDynamic support In-Reply-To: <93431280-9CBF-4722-961D-F2D2D0F83B4E@oracle.com> References: <93431280-9CBF-4722-961D-F2D2D0F83B4E@oracle.com> Message-ID: I?m seeing no issue with rcx being aliased in this code. Fred > On Oct 30, 2017, at 15:44, Paul Sandoz wrote: > > Hi, > > Thanks for reviewing. > >> On 30 Oct 2017, at 11:05, Dmitry Samersoff wrote: >> >> Paul, >> >> templateTable_x86.cpp: >> >> 564 const Register flags = rcx; >> 565 const Register rarg = NOT_LP64(rcx) LP64_ONLY(c_rarg1); >> >> Should we use another register for rarg under NOT_LP64 ? >> > > I think it should be ok, it i ain?t an expert here on the interpreter and the calling conventions, so please correct me. > > Some more context: > > + const Register flags = rcx; > + const Register rarg = NOT_LP64(rcx) LP64_ONLY(c_rarg1); > + __ movl(rarg, (int)bytecode()); > > The current bytecode code is loaded into ?rarg? > > + call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc), rarg); > > Then ?rarg" is the argument to the call to InterpreterRuntime::resolve_ldc, after which it is no longer referred to. > > +#ifndef _LP64 > + // borrow rdi from locals > + __ get_thread(rdi); > + __ get_vm_result_2(flags, rdi); > + __ restore_locals(); > +#else > + __ get_vm_result_2(flags, r15_thread); > +#endif > > The result from the call is then loaded into flags. > > So i don?t think it matters in this case if rcx is aliased. > > Paul. > >> -Dmitry >> >> >> On 10/26/2017 08:03 PM, Paul Sandoz wrote: >>> Hi, >>> >>> Please review the following patch for minimal dynamic constant support: >>> >>> http://cr.openjdk.java.net/~psandoz/jdk10/JDK-8186046-minimal-condy-support-hs/webrev/ >>> >>> https://bugs.openjdk.java.net/browse/JDK-8186046 >>> https://bugs.openjdk.java.net/browse/JDK-8186209 >>> >>> This patch is based on the JDK 10 unified HotSpot repository. Testing so far looks good. >>> >>> By minimal i mean just the support in the runtime for a dynamic constant pool entry to be referenced by a LDC instruction or a bootstrap method argument. Much of the work leverages the foundations built by invoke dynamic but is arguably simpler since resolution is less complex. >>> >>> A small set of bootstrap methods will be proposed as a follow on issue for 10 (these are currently being refined in the amber repository). >>> >>> Bootstrap method invocation has not changed (and the rules are the same for dynamic constants and indy). It is planned to enhance this in a further major release to support lazy resolution of bootstrap method arguments. >>> >>> The CSR for the VM specification is here: >>> >>> https://bugs.openjdk.java.net/browse/JDK-8189199 >>> >>> the j.l.invoke package documentation was also updated but please consider the VM specification as the definitive "source of truth" (we may clean up this area further later on so it becomes more informative, and that may also apply to duplicative text on MethodHandles/VarHandles). >>> >>> Any AoT-related work will be deferred to a future release. >>> >>> ? >>> >>> This patch only supports x64 platforms. There is a small set of changes specific to x64 (specifically to support null and primitives constants, as prior to this patch null was used as a sentinel for resolution and certain primitives types would never have been encountered, such as say byte). >>> >>> We will need to follow up with the SPARC platform and it is hoped/anticipated that OpenJDK members responsible for other platforms (namely ARM and PPC) will separately provide patches. >>> >>> ? >>> >>> Many of tests rely on an experimental byte code API that supports the generation of byte code with dynamic constants. >>> >>> One test uses class file bytes produced from a modified version of asmtools. The modifications have now been pushed but a new version of asmtools need to be rolled into jtreg before the test can operate directly on asmtools information rather than embedding class file bytes directly in the test. >>> >>> ? >>> >>> Paul. >>> >> > From sha.jiang at oracle.com Tue Oct 31 07:21:01 2017 From: sha.jiang at oracle.com (sha.jiang at oracle.com) Date: Tue, 31 Oct 2017 15:21:01 +0800 Subject: RFR[10] JDK-8190399: ProblemList tools/javac/tree/NoPrivateTypesExported.java due to JDK-8190315 Message-ID: Hi, Because of JDK-8190315, test tools/javac/tree/NoPrivateTypesExported.java always fails. So, it has to put it to ProblemList until JDK-8190315 is fixed. diff -r 438e0c9f2f17 test/langtools/ProblemList.txt --- a/test/langtools/ProblemList.txt??? Mon Oct 30 17:49:33 2017 -0700 +++ b/test/langtools/ProblemList.txt??? Tue Oct 31 15:18:03 2017 +0800 @@ -54,6 +54,7 @@ ?tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java 8057687??? generic-all??? emit correct byte code an attributes for type annotations ?tools/javac/warnings/suppress/TypeAnnotations.java 8057683??? generic-all??? improve ordering of errors with type annotations ?tools/javac/modules/SourceInSymlinkTest.java 8180263??? windows-all??? fails when run on a subst drive +tools/javac/tree/NoPrivateTypesExported.java 8190315??? generic-all ?########################################################################### ?# Best regards, John Jiang From forax at univ-mlv.fr Tue Oct 31 08:47:50 2017 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 31 Oct 2017 09:47:50 +0100 (CET) Subject: Fix Parameter Runtime*ParameterAnnotations spec Message-ID: <803691474.399683.1509439670003.JavaMail.zimbra@u-pem.fr> [I've trouble to find what is the right list for the JVMS spec change describe below, so i apologize in advance for the spam] Hi all, the spec of the Runtime*ParameterAnnotations attribute [1], allow the number of parameter annotations to be different from the number of parameter from the method descriptor but it fails to provide a way to retrieve/compute the mapping between a parameter and a parameter annotation. So people try to guess and fail, here is by example the ASM bug when we tried to provide such mapping to our user [2]. We (the ASM team) believe the only way to fix that is to require that if the number of parameters from the descriptor and the number of parameter annotations doesn't match then compilers should also emit a Parameter attribute which already indicate if a parameter is synthetic or not. The Parameter attribute is not emitted by default by compilers because it will make the class files too fat, here we are proposing to only emit the Parameter attribute in the case where there are annotations on parameters and the method has synthetic parameters, so it should not be a problem. regards, R?mi [1] https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18 [2] https://gitlab.ow2.org/asm/asm/issues/317788 From joe.darcy at oracle.com Tue Oct 31 16:31:46 2017 From: joe.darcy at oracle.com (joe darcy) Date: Tue, 31 Oct 2017 09:31:46 -0700 Subject: RFR[10] JDK-8190399: ProblemList tools/javac/tree/NoPrivateTypesExported.java due to JDK-8190315 In-Reply-To: References: Message-ID: Hi John, This looks fine to push, assuming JDK-8190315 doesn't get fixed in the interim. Thanks, -Joe On 10/31/2017 12:21 AM, sha.jiang at oracle.com wrote: > Hi, > Because of JDK-8190315, test > tools/javac/tree/NoPrivateTypesExported.java always fails. So, it has > to put it to ProblemList until JDK-8190315 is fixed. > > diff -r 438e0c9f2f17 test/langtools/ProblemList.txt > --- a/test/langtools/ProblemList.txt Mon Oct 30 17:49:33 2017 -0700 > +++ b/test/langtools/ProblemList.txt Tue Oct 31 15:18:03 2017 +0800 > @@ -54,6 +54,7 @@ > tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java > 8057687 generic-all emit correct byte code an attributes for > type annotations > tools/javac/warnings/suppress/TypeAnnotations.java 8057683 > generic-all improve ordering of errors with type annotations > tools/javac/modules/SourceInSymlinkTest.java 8180263 windows-all > fails when run on a subst drive > +tools/javac/tree/NoPrivateTypesExported.java 8190315 generic-all > > ########################################################################### > > # > > Best regards, > John Jiang > From jan.lahoda at oracle.com Tue Oct 31 16:46:30 2017 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Tue, 31 Oct 2017 17:46:30 +0100 Subject: RFR: JDK-8189778: Jshell crash on tab for StringBuilder.append( In-Reply-To: <59F1AC72.4020202@oracle.com> References: <59F1AC72.4020202@oracle.com> Message-ID: <59F8A8E6.6030609@oracle.com> I've updated to patch to have some comments at places that seemed important: http://cr.openjdk.java.net/~jlahoda/8189778/webrev.01/ Jan On 26.10.2017 11:35, Jan Lahoda wrote: > Hi, > > Typing: > jshell> StringBuilder sb = new StringBuilder(); > jshell> sb.append( > > Will lead to an exception: > jshell> sb.append(Exception in thread "main" > java.lang.StringIndexOutOfBoundsException: start -59, end -59, length 238 > [snip] > jdk.compiler/jdk.internal.shellsupport.doc.JavadocHelper$OnDemandJavadocHelper.getResolvedDocComment(JavadocHelper.java:481) > > > The reason is that the javadoc for StringBuilder.append(CharSequence, > int, int) is: > /** > * @throws IndexOutOfBoundsException {@inheritDoc} > */ > > The JavadocHelper tries to fill in the missing javadoc entries, but that > fails because it tries to insert the preceding entries at an > uninitialized place. > > The proposed patch: > -fixes the above > -adds a test that runs the JavadocHelper on all > methods/fields/constructors of top-level types in all exported packages > (this runs for a considerable time, and we may need to disable this test > if it proves to be too heavyweight) > -adds a few more test cases for problems found by the above test > -fixes the javadoc resolution to treat missing javadoc body as > {@inheritDoc} (so that the overridden method's javadoc text is used if > missing in this method) > > Bug: https://bugs.openjdk.java.net/browse/JDK-8189778 > Webrev: http://cr.openjdk.java.net/~jlahoda/8189778/webrev.00/ > > Feedback is welcome. > > Thanks, > Jan From paul.sandoz at oracle.com Tue Oct 31 17:32:25 2017 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 31 Oct 2017 10:32:25 -0700 Subject: [10] RFR 8186046 Minimal ConstantDynamic support In-Reply-To: References: <93431280-9CBF-4722-961D-F2D2D0F83B4E@oracle.com> Message-ID: <58726425-BA16-482B-A02E-3B0613CD5010@oracle.com> > On 31 Oct 2017, at 05:58, Dmitry Samersoff wrote: > > Paul and Frederic, > > Thank you. > > One more question. Do we need to call verify_oop below? > > 509 { // Check for the null sentinel. > ... > 517 xorptr(result, result); // NULL object reference > ... > > 521 if (VerifyOops) { > 522 verify_oop(result); > 523 } > I believe it?s harmless. When the flag is on it eventually results in a call to the stub generated by generate_verify_oop: http://hg.openjdk.java.net/jdk10/hs/file/tip/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp#l1023 // make sure object is 'reasonable' __ testptr(rax, rax); __ jcc(Assembler::zero, exit); // if obj is NULL it is OK If the oop is null the verification will exit safely. Paul. > -Dmitry > > > On 31.10.2017 00:56, Frederic Parain wrote: >> I?m seeing no issue with rcx being aliased in this code. >> >> Fred >> >>> On Oct 30, 2017, at 15:44, Paul Sandoz wrote: >>> >>> Hi, >>> >>> Thanks for reviewing. >>> >>>> On 30 Oct 2017, at 11:05, Dmitry Samersoff wrote: >>>> >>>> Paul, >>>> >>>> templateTable_x86.cpp: >>>> >>>> 564 const Register flags = rcx; >>>> 565 const Register rarg = NOT_LP64(rcx) LP64_ONLY(c_rarg1); >>>> >>>> Should we use another register for rarg under NOT_LP64 ? >>>> >>> >>> I think it should be ok, it i ain?t an expert here on the interpreter and the calling conventions, so please correct me. >>> >>> Some more context: >>> >>> + const Register flags = rcx; >>> + const Register rarg = NOT_LP64(rcx) LP64_ONLY(c_rarg1); >>> + __ movl(rarg, (int)bytecode()); >>> >>> The current bytecode code is loaded into ?rarg? >>> >>> + call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc), rarg); >>> >>> Then ?rarg" is the argument to the call to InterpreterRuntime::resolve_ldc, after which it is no longer referred to. >>> >>> +#ifndef _LP64 >>> + // borrow rdi from locals >>> + __ get_thread(rdi); >>> + __ get_vm_result_2(flags, rdi); >>> + __ restore_locals(); >>> +#else >>> + __ get_vm_result_2(flags, r15_thread); >>> +#endif >>> >>> The result from the call is then loaded into flags. >>> >>> So i don?t think it matters in this case if rcx is aliased. >>> >>> Paul. >>> >>>> -Dmitry >>>> >>>> >>>> On 10/26/2017 08:03 PM, Paul Sandoz wrote: >>>>> Hi, >>>>> >>>>> Please review the following patch for minimal dynamic constant support: >>>>> >>>>> http://cr.openjdk.java.net/~psandoz/jdk10/JDK-8186046-minimal-condy-support-hs/webrev/ >>>>> >>>>> https://bugs.openjdk.java.net/browse/JDK-8186046 >>>>> https://bugs.openjdk.java.net/browse/JDK-8186209 >>>>> >>>>> This patch is based on the JDK 10 unified HotSpot repository. Testing so far looks good. >>>>> >>>>> By minimal i mean just the support in the runtime for a dynamic constant pool entry to be referenced by a LDC instruction or a bootstrap method argument. Much of the work leverages the foundations built by invoke dynamic but is arguably simpler since resolution is less complex. >>>>> >>>>> A small set of bootstrap methods will be proposed as a follow on issue for 10 (these are currently being refined in the amber repository). >>>>> >>>>> Bootstrap method invocation has not changed (and the rules are the same for dynamic constants and indy). It is planned to enhance this in a further major release to support lazy resolution of bootstrap method arguments. >>>>> >>>>> The CSR for the VM specification is here: >>>>> >>>>> https://bugs.openjdk.java.net/browse/JDK-8189199 >>>>> >>>>> the j.l.invoke package documentation was also updated but please consider the VM specification as the definitive "source of truth" (we may clean up this area further later on so it becomes more informative, and that may also apply to duplicative text on MethodHandles/VarHandles). >>>>> >>>>> Any AoT-related work will be deferred to a future release. >>>>> >>>>> ? >>>>> >>>>> This patch only supports x64 platforms. There is a small set of changes specific to x64 (specifically to support null and primitives constants, as prior to this patch null was used as a sentinel for resolution and certain primitives types would never have been encountered, such as say byte). >>>>> >>>>> We will need to follow up with the SPARC platform and it is hoped/anticipated that OpenJDK members responsible for other platforms (namely ARM and PPC) will separately provide patches. >>>>> >>>>> ? >>>>> >>>>> Many of tests rely on an experimental byte code API that supports the generation of byte code with dynamic constants. >>>>> >>>>> One test uses class file bytes produced from a modified version of asmtools. The modifications have now been pushed but a new version of asmtools need to be rolled into jtreg before the test can operate directly on asmtools information rather than embedding class file bytes directly in the test. >>>>> >>>>> ? >>>>> >>>>> Paul. >>>>> >>>> >>> >> > > From alex.buckley at oracle.com Tue Oct 31 19:11:26 2017 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 31 Oct 2017 12:11:26 -0700 Subject: Fix Parameter Runtime*ParameterAnnotations spec In-Reply-To: <803691474.399683.1509439670003.JavaMail.zimbra@u-pem.fr> References: <803691474.399683.1509439670003.JavaMail.zimbra@u-pem.fr> Message-ID: <59F8CADE.9040106@oracle.com> On 10/31/2017 1:47 AM, Remi Forax wrote: > Hi all, the spec of the Runtime*ParameterAnnotations attribute [1], > allow the number of parameter annotations to be different from the > number of parameter from the method descriptor but it fails to > provide a way to retrieve/compute the mapping between a parameter and > a parameter annotation. > > So people try to guess and fail, here is by example the ASM bug when > we tried to provide such mapping to our user [2]. > > We (the ASM team) believe the only way to fix that is to require that > if the number of parameters from the descriptor and the number of > parameter annotations doesn't match then compilers should also emit a > Parameter attribute which already indicate if a parameter is > synthetic or not. I recognize that constructor parameters are a painful cause of discrepancy between the method descriptor and various attributes -- not just Runtime*ParameterAnnotations but also Signature (see the note "A method signature encoded by ..." in https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1). However, the decision in JDK-8067975 was to loosen the JVMS' description so that it admitted the class files emitted by javac and ecj. If you want javac and ecj to emit something different than they do today, then your best bet is to write up a "State of the Parameters" page that shows the "interesting" programs, and what javac and ecj emit. Only then can suggestions like "Emit a MethodParameters attribute if ..." be evaluated. Alex From paul.sandoz at oracle.com Tue Oct 31 19:32:28 2017 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 31 Oct 2017 12:32:28 -0700 Subject: [10] RFR 8186046 Minimal ConstantDynamic support In-Reply-To: References: Message-ID: Lois identified and fixed a bug found when running the JCK VM tests. I merged the changes below into the current webrev. Paul. --- old/src/hotspot/share/interpreter/linkResolver.cpp 2017-10-31 11:56:30.541287505 -0400 +++ new/src/hotspot/share/interpreter/linkResolver.cpp 2017-10-31 11:56:29.215676272 -0400 @@ -301,14 +301,14 @@ if (vca_result != Reflection::ACCESS_OK) { ResourceMark rm(THREAD); char* msg = Reflection::verify_class_access_msg(ref_klass, - InstanceKlass::cast(sel_klass), + InstanceKlass::cast(base_klass), vca_result); if (msg == NULL) { Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalAccessError(), "failed to access class %s from class %s", - sel_klass->external_name(), + base_klass->external_name(), ref_klass->external_name()); } else { // Use module specific message returned by verify_class_access_msg(). > On 26 Oct 2017, at 10:03, Paul Sandoz wrote: > > Hi, > > Please review the following patch for minimal dynamic constant support: > > http://cr.openjdk.java.net/~psandoz/jdk10/JDK-8186046-minimal-condy-support-hs/webrev/ > > https://bugs.openjdk.java.net/browse/JDK-8186046 > https://bugs.openjdk.java.net/browse/JDK-8186209 > > This patch is based on the JDK 10 unified HotSpot repository. Testing so far looks good. > > By minimal i mean just the support in the runtime for a dynamic constant pool entry to be referenced by a LDC instruction or a bootstrap method argument. Much of the work leverages the foundations built by invoke dynamic but is arguably simpler since resolution is less complex. > > A small set of bootstrap methods will be proposed as a follow on issue for 10 (these are currently being refined in the amber repository). > > Bootstrap method invocation has not changed (and the rules are the same for dynamic constants and indy). It is planned to enhance this in a further major release to support lazy resolution of bootstrap method arguments. > > The CSR for the VM specification is here: > > https://bugs.openjdk.java.net/browse/JDK-8189199 > > the j.l.invoke package documentation was also updated but please consider the VM specification as the definitive "source of truth" (we may clean up this area further later on so it becomes more informative, and that may also apply to duplicative text on MethodHandles/VarHandles). > > Any AoT-related work will be deferred to a future release. > > ? > > This patch only supports x64 platforms. There is a small set of changes specific to x64 (specifically to support null and primitives constants, as prior to this patch null was used as a sentinel for resolution and certain primitives types would never have been encountered, such as say byte). > > We will need to follow up with the SPARC platform and it is hoped/anticipated that OpenJDK members responsible for other platforms (namely ARM and PPC) will separately provide patches. > > ? > > Many of tests rely on an experimental byte code API that supports the generation of byte code with dynamic constants. > > One test uses class file bytes produced from a modified version of asmtools. The modifications have now been pushed but a new version of asmtools need to be rolled into jtreg before the test can operate directly on asmtools information rather than embedding class file bytes directly in the test. > > ? > > Paul. From jonathan.gibbons at oracle.com Tue Oct 31 20:27:50 2017 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Tue, 31 Oct 2017 13:27:50 -0700 Subject: RFR: JDK-8187681: Compiling for target 9 while also using --patch-module In-Reply-To: <59DF8ED5.30501@oracle.com> References: <59DF8481.7010103@oracle.com> <330badc4-4175-b349-8556-bb446adbc909@oracle.com> <59DF8ED5.30501@oracle.com> Message-ID: <59F8DCC6.3040408@oracle.com> Basic patch is OK. I understand Maurizio's use case, but I also agree with Jan's analysis of what is entailed. If we want to relax the restriction of -source and --patch-module, it should be a separate patch. -- Jon On 10/12/2017 08:48 AM, Jan Lahoda wrote: > On 12.10.2017 17:26, Maurizio Cimadamore wrote: >> Whoops - hit send too fast - wanted to ask a question; do you also plan >> to remove similar restriction for -source ? I've hit that a couple of >> times, and currently this restriction is preventing me from running >> langtools tests on a patched compiler; that is, I can patch the VM to >> run the tests and that works, but I can't pass same set of patches to >> the javac used by jtreg, as that will result in errors whenever a test >> has e.g. -source 8 flag set. > > I am afraid this is more involved. The restriction removed here is > mostly for consistency with restricting --add-exports for system > modules with --release, which is mostly for safety. So this is mostly > deleting a check. > > Allowing --patch-module with -source < 9 is more complex, as it means > actually changing the file manager to reflect the option for > StandardLocation.PLATFORM_CLASS_PATH (and check there's no > -bootclasspath, combined with --patch-module, as that would not make > much sense). But might still be possible. Jon, any comment? > > Thanks, > Jan > >> >> Maurizio >> >> >> >> On 12/10/17 16:24, Maurizio Cimadamore wrote: >>> Looks good >>> >>> Maurizio >>> >>> >>> On 12/10/17 16:04, Jan Lahoda wrote: >>>> Hello, >>>> >>>> I'd like to ask for a review for: >>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8187681 >>>> Webrev: http://cr.openjdk.java.net/~jlahoda/8187681/webrev.00/ >>>> >>>> The patch is basically to remove the limitation on use of >>>> --patch-module for a system module in combination with --release. >>>> >>>> Thanks, >>>> Jan >>> >> From jonathan.gibbons at oracle.com Tue Oct 31 20:39:04 2017 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Tue, 31 Oct 2017 13:39:04 -0700 Subject: RFR: JDK-8180744: Update ct.sym for JDK 10 In-Reply-To: <59E8E4E2.5060208@oracle.com> References: <59E0B1DE.3000701@oracle.com> <59E7C298.1060803@oracle.com> <59E8E4E2.5060208@oracle.com> Message-ID: <59F8DF68.8090306@oracle.com> +1. Re: > There are other jdk.compiler packages already exported to jdk.jdeps. > And the current implementation of jdeprscan is already depending on > details of --release implementation in javac (that the > improve-platformprovider patch is trying to improve and breaks > jdeprscan, so this is an attempt to make it work again). I don't think we should change anything here, but I think we should work to reduce the use of javac internals in the jdk.jdeps module. I definitely see some low hanging fruit in javap, but at a higher level, getting access to different flavors of filemanager would be good. -- Jon On 10/19/2017 10:46 AM, Jan Lahoda wrote: > Hi, > > Thanks for the comments. > > I've split the work into three parts: > -the change to PlatformProvider to return a file manager: > http://cr.openjdk.java.net/~jlahoda/8180744/webrev.02/improve-platformprovider/ > > -the changes to support --release 9 (modular environment): > http://cr.openjdk.java.net/~jlahoda/8180744/webrev.02/release-infrastructure/ > > -the update to the historical data: > http://cr.openjdk.java.net/~jlahoda/8180744/webrev.02/release-data/ > > I was tried to limit the lengths of the lines. > > On 18.10.2017 23:07, Jonathan Gibbons wrote: >> On a pragmatic level, I note that there are some excessively long lines >> here. I know we don't rigidly adhere to an 80 character limit, but some >> of the lines are perversely long, and will be tedious to review in >> followup webrevs. A quick grep of the changeset shows 67 lines over >> 100 characters and 36 over 120. (This is not counting the long lines in >> the generated files.) >> >> This webrev seems to include changes for another review, 8188035. >> >> There are distinct blobs of work here: for example, the javac work for >> JDKPlatformProvider seems logically distinct from the changes for >> CreateSymbols. It seems a shame the work could not have been separated >> into distinct changesets. >> >> Generally, we need more documentation on the overall process for >> creating these files, including details on the tool(s), and the various >> file and file formats involved. >> >> It feels wrong to export javac internals to jdeps. Maybe this should >> (eventually) evolve into a more supported service API? > > There are other jdk.compiler packages already exported to jdk.jdeps. > And the current implementation of jdeprscan is already depending on > details of --release implementation in javac (that the > improve-platformprovider patch is trying to improve and breaks > jdeprscan, so this is an attempt to make it work again). > > Jan > >> >> -- Jon >> >> >> On 10/13/2017 05:30 AM, Jan Lahoda wrote: >>> Hi, >>> >>> The patch here adds a support for --release 9 to OpenJDK. This >>> includes adding a snapshot of the JDK 9 APIs. >>> >>> Notes: >>> -several changes to the historical data in make/data/symbols: >>> --java.management.rmi-8.sym.txt contains a few classes that were >>> originally in java.management-8.sym.txt (this change is adjusting the >>> structure to adhere more to the final JDK 9 module layout) >>> --java.annotations.common-* renamed to java.xml.ws.annotation-* to >>> adhere to the final layout >>> --diffing of classes across releases has been improved to avoid some >>> unnecessary class header notices in the historical data >>> --empty files are now not written for the historical data >>> -the (JDK)PlatformProvider.PlatformDescription(Impl) now returns a >>> file manager, instead of a list of paths. This makes the contract >>> cleaner, and allow to handle the ".sig" extension mostly in the file >>> manager instead of ClassFinder. (Due to this change, JDK-8139607: >>> '-release option forces StandardJavaFileManager' is also resolved by >>> this patch, although it is not the primary goal of this patch.) >>> >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8180744 >>> Webrev: http://cr.openjdk.java.net/~jlahoda/8180744/webrev.00/ >>> >>> I'll send to build-dev as well after the javac changes will look OK. >>> >>> Any feedback is welcome. >>> >>> Thanks, >>> Jan >> From mandy.chung at oracle.com Tue Oct 31 21:43:59 2017 From: mandy.chung at oracle.com (mandy chung) Date: Tue, 31 Oct 2017 14:43:59 -0700 Subject: [10] RFR 8186046 Minimal ConstantDynamic support In-Reply-To: References: Message-ID: <230aad0f-8649-baf2-71e8-8efc75d0cb16@oracle.com> On 10/26/17 10:03 AM, Paul Sandoz wrote: > Hi, > > Please review the following patch for minimal dynamic constant support: > > http://cr.openjdk.java.net/~psandoz/jdk10/JDK-8186046-minimal-condy-support-hs/webrev/ I reviewed the non-hotspot change as a learning exercise (I am not close to j.l.invoke implementation).? I assume DynamicConstant intends to be non-public in this patch, right? 30 public final class DynamicConstant Mandy -------------- next part -------------- An HTML attachment was scrubbed... URL: From paul.sandoz at oracle.com Tue Oct 31 22:53:30 2017 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 31 Oct 2017 15:53:30 -0700 Subject: [10] RFR 8186046 Minimal ConstantDynamic support In-Reply-To: <230aad0f-8649-baf2-71e8-8efc75d0cb16@oracle.com> References: <230aad0f-8649-baf2-71e8-8efc75d0cb16@oracle.com> Message-ID: <05E86643-EE91-49BB-9A57-B291AA087211@oracle.com> > On 31 Oct 2017, at 14:43, mandy chung wrote: > > > > On 10/26/17 10:03 AM, Paul Sandoz wrote: >> Hi, >> >> Please review the following patch for minimal dynamic constant support: >> >> >> http://cr.openjdk.java.net/~psandoz/jdk10/JDK-8186046-minimal-condy-support-hs/webrev/ > > > I reviewed the non-hotspot change as a learning exercise (I am not close to j.l.invoke implementation). I assume DynamicConstant intends to be non-public in this patch, right? > 30 public final class DynamicConstant > Well spotted. More likely to be renamed to ConstantBootstraps when a minimal set of dynamic constant bootstraps will be proposed (likely this week) as a follow on patch. I?ll made it non-public in the updated webrev so as to keep this patch self-contained. Paul. From dmitry.samersoff at bell-sw.com Mon Oct 30 18:08:47 2017 From: dmitry.samersoff at bell-sw.com (Dmitry Samersoff) Date: Mon, 30 Oct 2017 18:08:47 -0000 Subject: [10] RFR 8186046 Minimal ConstantDynamic support In-Reply-To: References: Message-ID: Paul, templateTable_x86.cpp: 564 const Register flags = rcx; 565 const Register rarg = NOT_LP64(rcx) LP64_ONLY(c_rarg1); Should we use another register for rarg under NOT_LP64 ? -Dmitry On 10/26/2017 08:03 PM, Paul Sandoz wrote: > Hi, > > Please review the following patch for minimal dynamic constant support: > > http://cr.openjdk.java.net/~psandoz/jdk10/JDK-8186046-minimal-condy-support-hs/webrev/ > > https://bugs.openjdk.java.net/browse/JDK-8186046 > https://bugs.openjdk.java.net/browse/JDK-8186209 > > This patch is based on the JDK 10 unified HotSpot repository. Testing so far looks good. > > By minimal i mean just the support in the runtime for a dynamic constant pool entry to be referenced by a LDC instruction or a bootstrap method argument. Much of the work leverages the foundations built by invoke dynamic but is arguably simpler since resolution is less complex. > > A small set of bootstrap methods will be proposed as a follow on issue for 10 (these are currently being refined in the amber repository). > > Bootstrap method invocation has not changed (and the rules are the same for dynamic constants and indy). It is planned to enhance this in a further major release to support lazy resolution of bootstrap method arguments. > > The CSR for the VM specification is here: > > https://bugs.openjdk.java.net/browse/JDK-8189199 > > the j.l.invoke package documentation was also updated but please consider the VM specification as the definitive "source of truth" (we may clean up this area further later on so it becomes more informative, and that may also apply to duplicative text on MethodHandles/VarHandles). > > Any AoT-related work will be deferred to a future release. > > ? > > This patch only supports x64 platforms. There is a small set of changes specific to x64 (specifically to support null and primitives constants, as prior to this patch null was used as a sentinel for resolution and certain primitives types would never have been encountered, such as say byte). > > We will need to follow up with the SPARC platform and it is hoped/anticipated that OpenJDK members responsible for other platforms (namely ARM and PPC) will separately provide patches. > > ? > > Many of tests rely on an experimental byte code API that supports the generation of byte code with dynamic constants. > > One test uses class file bytes produced from a modified version of asmtools. The modifications have now been pushed but a new version of asmtools need to be rolled into jtreg before the test can operate directly on asmtools information rather than embedding class file bytes directly in the test. > > ? > > Paul. > From dmitry.samersoff at bell-sw.com Tue Oct 31 13:01:57 2017 From: dmitry.samersoff at bell-sw.com (Dmitry Samersoff) Date: Tue, 31 Oct 2017 13:01:57 -0000 Subject: [10] RFR 8186046 Minimal ConstantDynamic support In-Reply-To: References: <93431280-9CBF-4722-961D-F2D2D0F83B4E@oracle.com> Message-ID: Paul and Frederic, Thank you. One more question. Do we need to call verify_oop below? 509 { // Check for the null sentinel. ... 517 xorptr(result, result); // NULL object reference ... 521 if (VerifyOops) { 522 verify_oop(result); 523 } -Dmitry On 31.10.2017 00:56, Frederic Parain wrote: > I?m seeing no issue with rcx being aliased in this code. > > Fred > >> On Oct 30, 2017, at 15:44, Paul Sandoz wrote: >> >> Hi, >> >> Thanks for reviewing. >> >>> On 30 Oct 2017, at 11:05, Dmitry Samersoff wrote: >>> >>> Paul, >>> >>> templateTable_x86.cpp: >>> >>> 564 const Register flags = rcx; >>> 565 const Register rarg = NOT_LP64(rcx) LP64_ONLY(c_rarg1); >>> >>> Should we use another register for rarg under NOT_LP64 ? >>> >> >> I think it should be ok, it i ain?t an expert here on the interpreter and the calling conventions, so please correct me. >> >> Some more context: >> >> + const Register flags = rcx; >> + const Register rarg = NOT_LP64(rcx) LP64_ONLY(c_rarg1); >> + __ movl(rarg, (int)bytecode()); >> >> The current bytecode code is loaded into ?rarg? >> >> + call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc), rarg); >> >> Then ?rarg" is the argument to the call to InterpreterRuntime::resolve_ldc, after which it is no longer referred to. >> >> +#ifndef _LP64 >> + // borrow rdi from locals >> + __ get_thread(rdi); >> + __ get_vm_result_2(flags, rdi); >> + __ restore_locals(); >> +#else >> + __ get_vm_result_2(flags, r15_thread); >> +#endif >> >> The result from the call is then loaded into flags. >> >> So i don?t think it matters in this case if rcx is aliased. >> >> Paul. >> >>> -Dmitry >>> >>> >>> On 10/26/2017 08:03 PM, Paul Sandoz wrote: >>>> Hi, >>>> >>>> Please review the following patch for minimal dynamic constant support: >>>> >>>> http://cr.openjdk.java.net/~psandoz/jdk10/JDK-8186046-minimal-condy-support-hs/webrev/ >>>> >>>> https://bugs.openjdk.java.net/browse/JDK-8186046 >>>> https://bugs.openjdk.java.net/browse/JDK-8186209 >>>> >>>> This patch is based on the JDK 10 unified HotSpot repository. Testing so far looks good. >>>> >>>> By minimal i mean just the support in the runtime for a dynamic constant pool entry to be referenced by a LDC instruction or a bootstrap method argument. Much of the work leverages the foundations built by invoke dynamic but is arguably simpler since resolution is less complex. >>>> >>>> A small set of bootstrap methods will be proposed as a follow on issue for 10 (these are currently being refined in the amber repository). >>>> >>>> Bootstrap method invocation has not changed (and the rules are the same for dynamic constants and indy). It is planned to enhance this in a further major release to support lazy resolution of bootstrap method arguments. >>>> >>>> The CSR for the VM specification is here: >>>> >>>> https://bugs.openjdk.java.net/browse/JDK-8189199 >>>> >>>> the j.l.invoke package documentation was also updated but please consider the VM specification as the definitive "source of truth" (we may clean up this area further later on so it becomes more informative, and that may also apply to duplicative text on MethodHandles/VarHandles). >>>> >>>> Any AoT-related work will be deferred to a future release. >>>> >>>> ? >>>> >>>> This patch only supports x64 platforms. There is a small set of changes specific to x64 (specifically to support null and primitives constants, as prior to this patch null was used as a sentinel for resolution and certain primitives types would never have been encountered, such as say byte). >>>> >>>> We will need to follow up with the SPARC platform and it is hoped/anticipated that OpenJDK members responsible for other platforms (namely ARM and PPC) will separately provide patches. >>>> >>>> ? >>>> >>>> Many of tests rely on an experimental byte code API that supports the generation of byte code with dynamic constants. >>>> >>>> One test uses class file bytes produced from a modified version of asmtools. The modifications have now been pushed but a new version of asmtools need to be rolled into jtreg before the test can operate directly on asmtools information rather than embedding class file bytes directly in the test. >>>> >>>> ? >>>> >>>> Paul. >>>> >>> >> > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 473 bytes Desc: OpenPGP digital signature URL: