From daniel.fuchs at oracle.com Wed Oct 1 10:00:29 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Wed, 01 Oct 2014 12:00:29 +0200 Subject: 8025690: Default FileHandler constructor doesn't throw NullPointerException if pattern is empty and count > 1 In-Reply-To: References: <542AB873.1070005@oracle.com> <542B1EB4.10508@oracle.com> Message-ID: <542BD0BD.4060408@oracle.com> Hi Lance, On 30/09/14 23:55, Lance Andersen wrote: > On Sep 30, 2014, at 5:20 PM, Daniel Fuchs > wrote: >> On 9/30/14 9:09 PM, Lance Andersen wrote: >>> Shouldn't the other constructors indicate that an NPE will occur >>> similar to the default constructor if the pattern is null? >> >> I assume that for the other constructors the NPE falls in the category >> "parameters should not be null unless otherwise specified" which is >> the usual rule for java.util.logging. > > I have gotten mixed views on this and have gone and clarified this in > some cases. Just think consistency would be good but your call Thanks. I'd prefer not to modify the API documentation in this patch, just to make it clear that the patch does not modify the spec. There's some text somewhere in java.util.logging javadoc - either package description or LogManager description that explicitely says that unless otherwise specified null parameters will trigger NPE. I can't say I like it very much but in the present case I think I'm going to take advantage of it ;-) . [...] >>> Just curious why you chose to put the check into openFiles() if the >>> issue is just with the default constructor? [...] >> I could have placed the check in the default constructor between >> the call to configure() and the call to openFiles() - but I thought >> it was better to put it in openFiles() - since the spirit of the spec >> seems to be that pattern should be neither null nor empty >> when openFiles() is called. > > Guess the question is whether you feel the check is redundant for the > other code paths to openFiles(). Your call either way as the change > seems fine otherwise It's a good remark. I reworked the patch to do the check in the default constructor, and put an assert in openFiles(). It's much clearer this way. http://cr.openjdk.java.net/~dfuchs/webrev_8025690/webrev.01 Thanks Lance! -- daniel > > Best > Lance >> >> best regards, >> >> -- daniel >>> >>> Best, >>> Lance >>> On Sep 30, 2014, at 10:04 AM, Daniel Fuchs >> > wrote: >>> >>>> Hi, >>>> >>>> Please find below a fix for >>>> >>>> 8025690: Default FileHandler constructor doesn't >>>> throw NullPointerException if pattern is empty and count > 1 >>>> https://bugs.openjdk.java.net/browse/JDK-8025690 >>>> >>>> The default constructor of FileHandler is specified to throw >>>> a NullPointerException if the pattern property string is an >>>> empty string. >>>> (see >>>> ) >>>> >>>> However it strangely does so only when count=1 >>>> >>>> The fix adds an additional check in openFiles() to verify that >>>> the pattern is not empty. At this point the other constructors >>>> (which take a pattern as parameter) will already have thrown an >>>> IAE if the pattern was empty (or an NPE if it was null). >>>> >>>> http://cr.openjdk.java.net/~dfuchs/webrev_8025690/webrev.00 >>>> >>>> best regards, >>>> >>>> -- daniel >>> >>> >>> >>> >>> Lance >>> Andersen| Principal Member of Technical Staff | +1.781.442.2037 >>> Oracle Java Engineering >>> 1 Network Drive >>> Burlington, MA 01803 >>> Lance.Andersen at oracle.com >>> >>> >>> >> > > > > Lance Andersen| > Principal Member of Technical Staff | +1.781.442.2037 > Oracle Java Engineering > 1 Network Drive > Burlington, MA 01803 > Lance.Andersen at oracle.com > > > From lance.andersen at oracle.com Wed Oct 1 11:04:57 2014 From: lance.andersen at oracle.com (Lance @ Oracle) Date: Wed, 1 Oct 2014 07:04:57 -0400 Subject: 8025690: Default FileHandler constructor doesn't throw NullPointerException if pattern is empty and count > 1 In-Reply-To: <542BD0BD.4060408@oracle.com> References: <542AB873.1070005@oracle.com> <542B1EB4.10508@oracle.com> <542BD0BD.4060408@oracle.com> Message-ID: <1EBB7D71-0818-4BDC-B953-CF63FDA0516F@oracle.com> Hi Daniel, The revised changes look fine. Best, Lance Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com Sent from my iPad > On Oct 1, 2014, at 6:00 AM, Daniel Fuchs wrote: > > Hi Lance, > >> On 30/09/14 23:55, Lance Andersen wrote: >> On Sep 30, 2014, at 5:20 PM, Daniel Fuchs > > wrote: >>> On 9/30/14 9:09 PM, Lance Andersen wrote: >>>> Shouldn't the other constructors indicate that an NPE will occur >>>> similar to the default constructor if the pattern is null? >>> >>> I assume that for the other constructors the NPE falls in the category >>> "parameters should not be null unless otherwise specified" which is >>> the usual rule for java.util.logging. >> >> I have gotten mixed views on this and have gone and clarified this in >> some cases. Just think consistency would be good but your call > > Thanks. I'd prefer not to modify the API documentation in this patch, > just to make it clear that the patch does not modify the spec. > There's some text somewhere in java.util.logging javadoc - either > package description or LogManager description that explicitely says > that unless otherwise specified null parameters will trigger NPE. > I can't say I like it very much but in the present case I think > I'm going to take advantage of it ;-) . > > [...] > >>>> Just curious why you chose to put the check into openFiles() if the >>>> issue is just with the default constructor? > [...] >>> I could have placed the check in the default constructor between >>> the call to configure() and the call to openFiles() - but I thought >>> it was better to put it in openFiles() - since the spirit of the spec >>> seems to be that pattern should be neither null nor empty >>> when openFiles() is called. >> >> Guess the question is whether you feel the check is redundant for the >> other code paths to openFiles(). Your call either way as the change >> seems fine otherwise > > It's a good remark. I reworked the patch to do the check in the > default constructor, and put an assert in openFiles(). > It's much clearer this way. > > http://cr.openjdk.java.net/~dfuchs/webrev_8025690/webrev.01 > > Thanks Lance! > > -- daniel > >> >> Best >> Lance >>> >>> best regards, >>> >>> -- daniel >>>> >>>> Best, >>>> Lance >>>> On Sep 30, 2014, at 10:04 AM, Daniel Fuchs >>> > wrote: >>>> >>>>> Hi, >>>>> >>>>> Please find below a fix for >>>>> >>>>> 8025690: Default FileHandler constructor doesn't >>>>> throw NullPointerException if pattern is empty and count > 1 >>>>> https://bugs.openjdk.java.net/browse/JDK-8025690 >>>>> >>>>> The default constructor of FileHandler is specified to throw >>>>> a NullPointerException if the pattern property string is an >>>>> empty string. >>>>> (see >>>>> ) >>>>> >>>>> However it strangely does so only when count=1 >>>>> >>>>> The fix adds an additional check in openFiles() to verify that >>>>> the pattern is not empty. At this point the other constructors >>>>> (which take a pattern as parameter) will already have thrown an >>>>> IAE if the pattern was empty (or an NPE if it was null). >>>>> >>>>> http://cr.openjdk.java.net/~dfuchs/webrev_8025690/webrev.00 >>>>> >>>>> best regards, >>>>> >>>>> -- daniel >>>> >>>> >>>> >>>> >>>> Lance >>>> Andersen| Principal Member of Technical Staff | +1.781.442.2037 >>>> Oracle Java Engineering >>>> 1 Network Drive >>>> Burlington, MA 01803 >>>> Lance.Andersen at oracle.com >>>> >>>> >>>> >>> >> >> >> >> Lance Andersen| >> Principal Member of Technical Staff | +1.781.442.2037 >> Oracle Java Engineering >> 1 Network Drive >> Burlington, MA 01803 >> Lance.Andersen at oracle.com >> >> >> > From konstantin.shefov at oracle.com Wed Oct 1 12:20:39 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Wed, 01 Oct 2014 16:20:39 +0400 Subject: [9] Review request : JDK-8058695: [TESTBUG] Reinvokers with arity >253 can't be cached In-Reply-To: <5422E931.2040509@oracle.com> References: <5422E931.2040509@oracle.com> Message-ID: <542BF197.90505@oracle.com> Hi, I have updated the webrev: http://cr.openjdk.java.net/~kshefov/8058695/webrev.01 Also I will move fix to JDK-8058733 to other request. -Konstantin On 24.09.2014 19:54, Konstantin Shefov wrote: > Hello, > > Please review the test bug fix > https://bugs.openjdk.java.net/browse/JDK-8058695 > Webrev is http://cr.openjdk.java.net/~kshefov/8058695/webrev.00/ > > There is also a fix to > https://bugs.openjdk.java.net/browse/JDK-8058733 in this diff. > > Thanks > > -Konstantin From vladimir.x.ivanov at oracle.com Wed Oct 1 12:43:10 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Wed, 01 Oct 2014 16:43:10 +0400 Subject: [9] Review request : JDK-8058695: [TESTBUG] Reinvokers with arity >253 can't be cached In-Reply-To: <542BF197.90505@oracle.com> References: <5422E931.2040509@oracle.com> <542BF197.90505@oracle.com> Message-ID: <542BF6DE.1060001@oracle.com> Good. Best regards, Vladimir Ivanov On 10/1/14, 4:20 PM, Konstantin Shefov wrote: > Hi, > > I have updated the webrev: > http://cr.openjdk.java.net/~kshefov/8058695/webrev.01 > > Also I will move fix to JDK-8058733 to other request. > > -Konstantin > > On 24.09.2014 19:54, Konstantin Shefov wrote: >> Hello, >> >> Please review the test bug fix >> https://bugs.openjdk.java.net/browse/JDK-8058695 >> Webrev is http://cr.openjdk.java.net/~kshefov/8058695/webrev.00/ >> >> There is also a fix to >> https://bugs.openjdk.java.net/browse/JDK-8058733 in this diff. >> >> Thanks >> >> -Konstantin > From igor.ignatyev at oracle.com Wed Oct 1 13:30:24 2014 From: igor.ignatyev at oracle.com (Igor Ignatyev) Date: Wed, 1 Oct 2014 06:30:24 -0700 (PDT) Subject: [9] Review request : JDK-8058695: [TESTBUG] Reinvokers with arity >253 can't be cached Message-ID: <9a1314e8-b304-4c96-985d-f9682fb1dbab@default> Hi Konstantin, 0. could you please introduce a ctor which sets the default value for 'maxArity' and use it instead of explicitly passed 'Helper.MAX_ARITY'? 1. there is a existing solution for your case w/ access to an private field of an outer class: > int desiredArity = Helper.RNG.nextInt(super.maxArity); otherwise changes look good to me. Thanks, Igor ----- Original Message ----- From: konstantin.shefov at oracle.com To: vladimir.x.ivanov at oracle.com, igor.ignatyev at oracle.com Cc: core-libs-dev at openjdk.java.net, mlvm-dev at openjdk.java.net Sent: Wednesday, October 1, 2014 4:20:54 PM GMT +04:00 Abu Dhabi / Muscat Subject: Re: [9] Review request : JDK-8058695: [TESTBUG] Reinvokers with arity >253 can't be cached Hi, I have updated the webrev: http://cr.openjdk.java.net/~kshefov/8058695/webrev.01 Also I will move fix to JDK-8058733 to other request. -Konstantin On 24.09.2014 19:54, Konstantin Shefov wrote: > Hello, > > Please review the test bug fix > https://bugs.openjdk.java.net/browse/JDK-8058695 > Webrev is http://cr.openjdk.java.net/~kshefov/8058695/webrev.00/ > > There is also a fix to > https://bugs.openjdk.java.net/browse/JDK-8058733 in this diff. > > Thanks > > -Konstantin From konstantin.shefov at oracle.com Wed Oct 1 13:46:44 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Wed, 01 Oct 2014 17:46:44 +0400 Subject: [9] Review request : JDK-8058695: [TESTBUG] Reinvokers with arity >253 can't be cached In-Reply-To: <9a1314e8-b304-4c96-985d-f9682fb1dbab@default> References: <9a1314e8-b304-4c96-985d-f9682fb1dbab@default> Message-ID: <542C05C4.4080206@oracle.com> Thanks for reviewing http://cr.openjdk.java.net/~kshefov/8058695/webrev.02 -Konstantin On 01.10.2014 17:30, Igor Ignatyev wrote: > Hi Konstantin, > > 0. could you please introduce a ctor which sets the default value for 'maxArity' and use it instead of explicitly passed 'Helper.MAX_ARITY'? > 1. there is a existing solution for your case w/ access to an private field of an outer class: >> int desiredArity = Helper.RNG.nextInt(super.maxArity); > otherwise changes look good to me. > > Thanks, > Igor > > ----- Original Message ----- > From: konstantin.shefov at oracle.com > To: vladimir.x.ivanov at oracle.com, igor.ignatyev at oracle.com > Cc: core-libs-dev at openjdk.java.net, mlvm-dev at openjdk.java.net > Sent: Wednesday, October 1, 2014 4:20:54 PM GMT +04:00 Abu Dhabi / Muscat > Subject: Re: [9] Review request : JDK-8058695: [TESTBUG] Reinvokers with arity >253 can't be cached > > Hi, > > I have updated the webrev: > http://cr.openjdk.java.net/~kshefov/8058695/webrev.01 > > Also I will move fix to JDK-8058733 to other request. > > -Konstantin > > On 24.09.2014 19:54, Konstantin Shefov wrote: >> Hello, >> >> Please review the test bug fix >> https://bugs.openjdk.java.net/browse/JDK-8058695 >> Webrev is http://cr.openjdk.java.net/~kshefov/8058695/webrev.00/ >> >> There is also a fix to >> https://bugs.openjdk.java.net/browse/JDK-8058733 in this diff. >> >> Thanks >> >> -Konstantin From otaviojava at java.net Wed Oct 1 14:33:59 2014 From: otaviojava at java.net (=?UTF-8?Q?Ot=C3=A1vio_Gon=C3=A7alves_de_Santana?=) Date: Wed, 1 Oct 2014 07:33:59 -0700 Subject: JEP 198: Light-Weight JSON API In-Reply-To: References: <20140725144505.71736316D8@eggemoggin.niobe.net> <53D98F34.6000907@univ-mlv.fr> Message-ID: Hi everyone. Is there any reason to not implement the JSR that already exist and that was born? https://jcp.org/en/jsr/detail?id=367 https://jcp.org/en/jsr/detail?id=353 Which especific cases what the OpenJDK need and this JSR don't care? Why just work together with these JSRs and each one has your implementation? For example, one to OpenJDK and another to JavaEE, this way each one implements according your necessity. The question is: it's really make sense have two APIs with similar goal? It would great to the Java developer should to know two API to do the same thing? obs: Sorry to question a lot, I just would like know more to be more useful. On Thu, Jul 31, 2014 at 1:28 AM, Mario Torre wrote: > I never gave a +1 with more enthusiasm! :) > > Cheers, > Mario > Il 31/lug/2014 03:27 "Wang Weijun" ha scritto: > > > > > On Jul 31, 2014, at 8:35, Remi Forax wrote: > > > > > > > > On 07/25/2014 04:45 PM, mark.reinhold at oracle.com wrote: > > >> New JEP Candidate: http://openjdk.java.net/jeps/198 > > >> > > >> - Mark > > > > > > Hi Mark, Hi Mike, > > > Implementing a json API was one of the use case I've used during the > > development of the lambdas, > > > so maybe you are interested by this gist > > > https://gist.github.com/forax/81a56cf2684bfa2e46ec > > > > I am reading "[ \"foo\", \"bar\" ]" and feel we need a JEP for new styles > > of literal strings. Long long ago there was a proposal for multi-line raw > > strings. Still alive? > > > > Thanks > > Max > > > > > > > -- Ot?vio Gon?alves de Santana blog: http://otaviosantana.blogspot.com.br/ twitter: http://twitter.com/otaviojava site: *http://about.me/otaviojava * 55 (11) 98255-3513 From lance.andersen at oracle.com Wed Oct 1 17:55:03 2014 From: lance.andersen at oracle.com (Lance Andersen) Date: Wed, 1 Oct 2014 13:55:03 -0400 Subject: RFR: 8059570, Addition of tests for RowSetFactory and RowSetProvider Message-ID: Hi all, Looking for a reviewer for the unit tests being added for RowSetFactory and RowSetProvider. The webrev can be found at http://cr.openjdk.java.net/~lancea/8059570/webrev.00/ Best, Lance Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From igor.ignatyev at oracle.com Thu Oct 2 01:10:06 2014 From: igor.ignatyev at oracle.com (Igor Ignatyev) Date: Thu, 02 Oct 2014 05:10:06 +0400 Subject: [9] Review request : JDK-8058695: [TESTBUG] Reinvokers with arity >253 can't be cached In-Reply-To: <542C05C4.4080206@oracle.com> References: <9a1314e8-b304-4c96-985d-f9682fb1dbab@default> <542C05C4.4080206@oracle.com> Message-ID: <542CA5EE.4040401@oracle.com> Konstantin, > + private TestMethods(String name, int maxArity) { > + this.name = name; > + this.maxArity = maxArity; > + } > + > private TestMethods(String name) { > this.name = name; > + this.maxArity = Helper.MAX_ARITY; > } please call TestMethods(String, int) from TestMethods(String) instead of copy&paste. Thanks, Igor On 10/01/2014 05:46 PM, Konstantin Shefov wrote: > Thanks for reviewing > > http://cr.openjdk.java.net/~kshefov/8058695/webrev.02 > > -Konstantin > > On 01.10.2014 17:30, Igor Ignatyev wrote: >> Hi Konstantin, >> >> 0. could you please introduce a ctor which sets the default value for >> 'maxArity' and use it instead of explicitly passed 'Helper.MAX_ARITY'? >> 1. there is a existing solution for your case w/ access to an private >> field of an outer class: >>> int desiredArity = Helper.RNG.nextInt(super.maxArity); >> otherwise changes look good to me. >> >> Thanks, >> Igor >> >> ----- Original Message ----- >> From: konstantin.shefov at oracle.com >> To: vladimir.x.ivanov at oracle.com, igor.ignatyev at oracle.com >> Cc: core-libs-dev at openjdk.java.net, mlvm-dev at openjdk.java.net >> Sent: Wednesday, October 1, 2014 4:20:54 PM GMT +04:00 Abu Dhabi / Muscat >> Subject: Re: [9] Review request : JDK-8058695: [TESTBUG] Reinvokers >> with arity >253 can't be cached >> >> Hi, >> >> I have updated the webrev: >> http://cr.openjdk.java.net/~kshefov/8058695/webrev.01 >> >> Also I will move fix to JDK-8058733 to other request. >> >> -Konstantin >> >> On 24.09.2014 19:54, Konstantin Shefov wrote: >>> Hello, >>> >>> Please review the test bug fix >>> https://bugs.openjdk.java.net/browse/JDK-8058695 >>> Webrev is http://cr.openjdk.java.net/~kshefov/8058695/webrev.00/ >>> >>> There is also a fix to >>> https://bugs.openjdk.java.net/browse/JDK-8058733 in this diff. >>> >>> Thanks >>> >>> -Konstantin > From konstantin.shefov at oracle.com Thu Oct 2 07:06:33 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Thu, 02 Oct 2014 11:06:33 +0400 Subject: [9] Review request : JDK-8058695: [TESTBUG] Reinvokers with arity >253 can't be cached In-Reply-To: <542CA5EE.4040401@oracle.com> References: <9a1314e8-b304-4c96-985d-f9682fb1dbab@default> <542C05C4.4080206@oracle.com> <542CA5EE.4040401@oracle.com> Message-ID: <542CF979.8090402@oracle.com> Hi, I have updated the webrev http://cr.openjdk.java.net/~kshefov/8058695/webrev.03/ -Konstantin On 02.10.2014 5:10, Igor Ignatyev wrote: > Konstantin, > >> + private TestMethods(String name, int maxArity) { >> + this.name = name; >> + this.maxArity = maxArity; >> + } >> + >> private TestMethods(String name) { >> this.name = name; >> + this.maxArity = Helper.MAX_ARITY; >> } > > please call TestMethods(String, int) from TestMethods(String) instead > of copy&paste. > > Thanks, > Igor > > On 10/01/2014 05:46 PM, Konstantin Shefov wrote: >> Thanks for reviewing >> >> http://cr.openjdk.java.net/~kshefov/8058695/webrev.02 >> >> -Konstantin >> >> On 01.10.2014 17:30, Igor Ignatyev wrote: >>> Hi Konstantin, >>> >>> 0. could you please introduce a ctor which sets the default value for >>> 'maxArity' and use it instead of explicitly passed 'Helper.MAX_ARITY'? >>> 1. there is a existing solution for your case w/ access to an private >>> field of an outer class: >>>> int desiredArity = Helper.RNG.nextInt(super.maxArity); >>> otherwise changes look good to me. >>> >>> Thanks, >>> Igor >>> >>> ----- Original Message ----- >>> From: konstantin.shefov at oracle.com >>> To: vladimir.x.ivanov at oracle.com, igor.ignatyev at oracle.com >>> Cc: core-libs-dev at openjdk.java.net, mlvm-dev at openjdk.java.net >>> Sent: Wednesday, October 1, 2014 4:20:54 PM GMT +04:00 Abu Dhabi / >>> Muscat >>> Subject: Re: [9] Review request : JDK-8058695: [TESTBUG] Reinvokers >>> with arity >253 can't be cached >>> >>> Hi, >>> >>> I have updated the webrev: >>> http://cr.openjdk.java.net/~kshefov/8058695/webrev.01 >>> >>> Also I will move fix to JDK-8058733 to other request. >>> >>> -Konstantin >>> >>> On 24.09.2014 19:54, Konstantin Shefov wrote: >>>> Hello, >>>> >>>> Please review the test bug fix >>>> https://bugs.openjdk.java.net/browse/JDK-8058695 >>>> Webrev is http://cr.openjdk.java.net/~kshefov/8058695/webrev.00/ >>>> >>>> There is also a fix to >>>> https://bugs.openjdk.java.net/browse/JDK-8058733 in this diff. >>>> >>>> Thanks >>>> >>>> -Konstantin >> From daniel.fuchs at oracle.com Thu Oct 2 10:39:59 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Thu, 02 Oct 2014 12:39:59 +0200 Subject: RFR: 8059570, Addition of tests for RowSetFactory and RowSetProvider In-Reply-To: References: Message-ID: <542D2B7F.9030202@oracle.com> Hi Lance, I probably don't know enough about rowset to qualify as reviewer for this change, but I had a look at the tests - and I believe they look good. I wonder whether there should be some additional tests that would run with a security manager on? The only thing unusual I noticed is that the jars seem to have a .DS_Store in their META-INF ;-) best regards, -- daniel On 01/10/14 19:55, Lance Andersen wrote: > Hi all, > > Looking for a reviewer for the unit tests being added for RowSetFactory and RowSetProvider. > > The webrev can be found at http://cr.openjdk.java.net/~lancea/8059570/webrev.00/ > > Best, > Lance > > > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 > Oracle Java Engineering > 1 Network Drive > Burlington, MA 01803 > Lance.Andersen at oracle.com > > > From lance.andersen at oracle.com Thu Oct 2 11:08:09 2014 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 2 Oct 2014 07:08:09 -0400 Subject: RFR: 8059570, Addition of tests for RowSetFactory and RowSetProvider In-Reply-To: <542D2B7F.9030202@oracle.com> References: <542D2B7F.9030202@oracle.com> Message-ID: Hi Daniel, Thank you for you review. On Oct 2, 2014, at 6:39 AM, Daniel Fuchs wrote: > Hi Lance, > > I probably don't know enough about rowset to qualify as reviewer > for this change, but I had a look at the tests - and I believe > they look good. Thank you. > I wonder whether there should be some additional tests that would > run with a security manager on? There are tests elsewhere which run with a SecurityManager. I might add some here later but will be in a different test file > > The only thing unusual I noticed is that the jars seem to have a > .DS_Store in their META-INF ;-) thanks, deleted that. Have hidden files enabled on my mac and forgot to remove it. Best Lance > > best regards, > > -- daniel > > On 01/10/14 19:55, Lance Andersen wrote: >> Hi all, >> >> Looking for a reviewer for the unit tests being added for RowSetFactory and RowSetProvider. >> >> The webrev can be found at http://cr.openjdk.java.net/~lancea/8059570/webrev.00/ >> >> Best, >> Lance >> >> >> Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 >> Oracle Java Engineering >> 1 Network Drive >> Burlington, MA 01803 >> Lance.Andersen at oracle.com >> >> >> > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From vladimir.x.ivanov at oracle.com Thu Oct 2 15:52:04 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Thu, 02 Oct 2014 19:52:04 +0400 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl Message-ID: <542D74A4.9050303@oracle.com> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/ https://bugs.openjdk.java.net/browse/JDK-8058892 Core j.l.i classes are preloaded during VM startup in order to avoid possible deadlock when accessing JSR292-related functionality from multiple threads. After LF sharing-related changes, FILL_ARRAYS and ARRAYS are initialized too early. It affects startup time & footprint of applications that don't use JSR292. The fix is to move these fields into MHI.Lazy class, thus delaying their initialization to the first usage of JSR292 API. Testing: failing test, manual (measured HelloWorld app startup time; compared -XX:+PrintCompilation logs) Best regards, Vladimir Ivanov From olivier.lagneau at oracle.com Thu Oct 2 16:08:45 2014 From: olivier.lagneau at oracle.com (olivier.lagneau at oracle.com) Date: Thu, 02 Oct 2014 18:08:45 +0200 Subject: Urgent [9], 2nd round, RFR (S) : JDK-8039915 NumberFormat.format() does not consider required no. of fraction digits properly Message-ID: <542D788D.50808@oracle.com> Please review this 2nd version of the fix taking into account your feedback. Bug : https://bugs.openjdk.java.net/browse/JDK-8039915 webrev : http://cr.openjdk.java.net/~olagneau/8039915/webrev.00 From olivier.lagneau at oracle.com Thu Oct 2 16:29:31 2014 From: olivier.lagneau at oracle.com (olivier.lagneau at oracle.com) Date: Thu, 02 Oct 2014 18:29:31 +0200 Subject: Urgent [9], 2nd round, RFR (S) : JDK-8039915 NumberFormat.format() does not consider required no. of fraction digits properly Message-ID: <542D7D6B.6000108@oracle.com> Please review this 2nd version of the fix taking into account your feedback. Bug : https://bugs.openjdk.java.net/browse/JDK-8039915 webrev : http://cr.openjdk.java.net/~olagneau/8039915/webrev.01 I have changed the code following your remarks Testing: lot of testing on jtreg, jck8, code coverage, jprt. Below are more details on the changes in this webrev. For the new work in question, it might be clearer to me if the HALF_UP and HALF_DOWN cases > were combined into a single block since they > share much of the logic. > The unique logic for each mode would be easier to see if the > differences were placed together. I have merged HALF_UP and HALF_DOWN cases into a single switch case. I also tested a fully merged version where HALF_UP, HALF_DOWN, and also HALF_EVEN are merge into a single switch case. So merging the three is even possible. If you want to have the three HALF_* cases we can quickly move to that. > My only suggestions are trivial: 1) enhance the method javadoc of > shouldRoundUp(), e.g., there are no @param tags for the boolean > parameters, Fixed that. @param tags are available for shouldRoundUp method > 2) use braces around all the statements contained in if/else blocks > (see below). Comment #2 is nit-picky. Took care to follow this rule in this new version. > If the test is already printing out the information you showed above > (?Error formatting ??) then I think it is enough but the verbiage > should perhaps match the reminder, e.g., ?Failure: Error formatting > double ?? Changed test code to provide this consistent wording. Thanks, Olivier. From olivier.lagneau at oracle.com Thu Oct 2 16:33:45 2014 From: olivier.lagneau at oracle.com (olivier.lagneau at oracle.com) Date: Thu, 02 Oct 2014 18:33:45 +0200 Subject: Urgent [9], 2nd round, RFR (S) : JDK-8039915 NumberFormat.format() does not consider required no. of fraction digits properly In-Reply-To: <542D788D.50808@oracle.com> References: <542D788D.50808@oracle.com> Message-ID: <542D7E69.2060208@oracle.com> Oops, please forget this one that is missing text of what is done in this webrev. wrong gui manipulation ... Sorry for this, Olivier. On 02/10/2014 18:08, olivier.lagneau at oracle.com wrote: > Please review this 2nd version of the fix taking into account your > feedback. > > Bug : https://bugs.openjdk.java.net/browse/JDK-8039915 > webrev : http://cr.openjdk.java.net/~olagneau/8039915/webrev.00 > > > > > From vladimir.x.ivanov at oracle.com Thu Oct 2 16:55:12 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Thu, 02 Oct 2014 20:55:12 +0400 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542D74A4.9050303@oracle.com> References: <542D74A4.9050303@oracle.com> Message-ID: <542D8370.1030107@oracle.com> Small update: http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/ Need to reorder initialization sequence in MHI.Lazy. Initialized FILL_ARRAYS and ARRAYS are required for later MH lookups. Additional testing: * jck (api/java_lang/invoke) * jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea -esa" and COMPILE_THRESHOLD={0,30} Best regards, Vladimir Ivanov On 10/2/14, 7:52 PM, Vladimir Ivanov wrote: > http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/ > https://bugs.openjdk.java.net/browse/JDK-8058892 > > Core j.l.i classes are preloaded during VM startup in order to avoid > possible deadlock when accessing JSR292-related functionality from > multiple threads. After LF sharing-related changes, FILL_ARRAYS and > ARRAYS are initialized too early. It affects startup time & footprint of > applications that don't use JSR292. > > The fix is to move these fields into MHI.Lazy class, thus delaying their > initialization to the first usage of JSR292 API. > > Testing: failing test, manual (measured HelloWorld app startup time; > compared -XX:+PrintCompilation logs) > > Best regards, > Vladimir Ivanov From aleksey.shipilev at oracle.com Thu Oct 2 17:00:43 2014 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Thu, 02 Oct 2014 21:00:43 +0400 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542D8370.1030107@oracle.com> References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> Message-ID: <542D84BB.9070407@oracle.com> I have three comments: * Since initialization order is important, why don't put the initialization in the existing static initializer? This will secure for inadvertent field reordering in future. * Any reason two new fields are "private"? All other seem package-private. * Any performance problems if we actually count FILL_ARRAYS_COUNT in during the static initialization, instead of putting a magic value? -Aleksey. On 10/02/2014 08:55 PM, Vladimir Ivanov wrote: > Small update: > http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/ > > Need to reorder initialization sequence in MHI.Lazy. Initialized > FILL_ARRAYS and ARRAYS are required for later MH lookups. > > Additional testing: > * jck (api/java_lang/invoke) > * jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea -esa" and > COMPILE_THRESHOLD={0,30} > > Best regards, > Vladimir Ivanov > > On 10/2/14, 7:52 PM, Vladimir Ivanov wrote: >> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/ >> https://bugs.openjdk.java.net/browse/JDK-8058892 >> >> Core j.l.i classes are preloaded during VM startup in order to avoid >> possible deadlock when accessing JSR292-related functionality from >> multiple threads. After LF sharing-related changes, FILL_ARRAYS and >> ARRAYS are initialized too early. It affects startup time & footprint of >> applications that don't use JSR292. >> >> The fix is to move these fields into MHI.Lazy class, thus delaying their >> initialization to the first usage of JSR292 API. >> >> Testing: failing test, manual (measured HelloWorld app startup time; >> compared -XX:+PrintCompilation logs) >> >> Best regards, >> Vladimir Ivanov > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev From forax at univ-mlv.fr Thu Oct 2 17:09:59 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 02 Oct 2014 19:09:59 +0200 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542D84BB.9070407@oracle.com> References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> <542D84BB.9070407@oracle.com> Message-ID: <542D86E7.9020705@univ-mlv.fr> On 10/02/2014 07:00 PM, Aleksey Shipilev wrote: > I have three comments: > > * Since initialization order is important, why don't put the > initialization in the existing static initializer? This will secure for > inadvertent field reordering in future. good idea. > > * Any reason two new fields are "private"? All other seem package-private. They should be package-private otherwise javac generates accessors (method access$xxx) > > * Any performance problems if we actually count FILL_ARRAYS_COUNT in > during the static initialization, instead of putting a magic value? > > -Aleksey. R?mi > > On 10/02/2014 08:55 PM, Vladimir Ivanov wrote: >> Small update: >> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/ >> >> Need to reorder initialization sequence in MHI.Lazy. Initialized >> FILL_ARRAYS and ARRAYS are required for later MH lookups. >> >> Additional testing: >> * jck (api/java_lang/invoke) >> * jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea -esa" and >> COMPILE_THRESHOLD={0,30} >> >> Best regards, >> Vladimir Ivanov >> >> On 10/2/14, 7:52 PM, Vladimir Ivanov wrote: >>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/ >>> https://bugs.openjdk.java.net/browse/JDK-8058892 >>> >>> Core j.l.i classes are preloaded during VM startup in order to avoid >>> possible deadlock when accessing JSR292-related functionality from >>> multiple threads. After LF sharing-related changes, FILL_ARRAYS and >>> ARRAYS are initialized too early. It affects startup time & footprint of >>> applications that don't use JSR292. >>> >>> The fix is to move these fields into MHI.Lazy class, thus delaying their >>> initialization to the first usage of JSR292 API. >>> >>> Testing: failing test, manual (measured HelloWorld app startup time; >>> compared -XX:+PrintCompilation logs) >>> >>> Best regards, >>> Vladimir Ivanov >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From vladimir.x.ivanov at oracle.com Thu Oct 2 17:26:32 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Thu, 02 Oct 2014 21:26:32 +0400 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542D84BB.9070407@oracle.com> References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> <542D84BB.9070407@oracle.com> Message-ID: <542D8AC8.7030506@oracle.com> Aleksey, Thanks for the review. Updated version: http://cr.openjdk.java.net/~vlivanov/8058892/webrev.02/ > * Since initialization order is important, why don't put the > initialization in the existing static initializer? This will secure for > inadvertent field reordering in future. Good idea. Fixed. > * Any reason two new fields are "private"? All other seem package-private. These fields are intended for usage only in MHI.varargsArray/buildFiller. They were private before and I decided to keep that. It is fine for MH_*/NF_* to be used from other places in j.l.i (e.g. NF_checkSpreadArgument is used in LambdaFormEditor). > * Any performance problems if we actually count FILL_ARRAYS_COUNT in > during the static initialization, instead of putting a magic value? It's more about code structure than performance. There's a dependency between FILL_ARRAYS size & LEFT_ARGS. If FILL_ARRAYS_COUNT is moved to Lazy, LEFT_ARGS should be moved to Lazy as well or LEFT_ARGS should be lazily initialized separately. IMO it doesn't worth an effort. Best regards, Vladimir Ivanov > > -Aleksey. > > On 10/02/2014 08:55 PM, Vladimir Ivanov wrote: >> Small update: >> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/ >> >> Need to reorder initialization sequence in MHI.Lazy. Initialized >> FILL_ARRAYS and ARRAYS are required for later MH lookups. >> >> Additional testing: >> * jck (api/java_lang/invoke) >> * jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea -esa" and >> COMPILE_THRESHOLD={0,30} >> >> Best regards, >> Vladimir Ivanov >> >> On 10/2/14, 7:52 PM, Vladimir Ivanov wrote: >>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/ >>> https://bugs.openjdk.java.net/browse/JDK-8058892 >>> >>> Core j.l.i classes are preloaded during VM startup in order to avoid >>> possible deadlock when accessing JSR292-related functionality from >>> multiple threads. After LF sharing-related changes, FILL_ARRAYS and >>> ARRAYS are initialized too early. It affects startup time & footprint of >>> applications that don't use JSR292. >>> >>> The fix is to move these fields into MHI.Lazy class, thus delaying their >>> initialization to the first usage of JSR292 API. >>> >>> Testing: failing test, manual (measured HelloWorld app startup time; >>> compared -XX:+PrintCompilation logs) >>> >>> Best regards, >>> Vladimir Ivanov >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > > From aleksey.shipilev at oracle.com Thu Oct 2 18:02:29 2014 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Thu, 02 Oct 2014 22:02:29 +0400 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542D8AC8.7030506@oracle.com> References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> <542D84BB.9070407@oracle.com> <542D8AC8.7030506@oracle.com> Message-ID: <542D9335.4050705@oracle.com> On 10/02/2014 09:26 PM, Vladimir Ivanov wrote: > Aleksey, > > Thanks for the review. > Updated version: > http://cr.openjdk.java.net/~vlivanov/8058892/webrev.02/ Looks good. >> * Since initialization order is important, why don't put the >> initialization in the existing static initializer? This will secure for >> inadvertent field reordering in future. > Good idea. Fixed. > >> * Any reason two new fields are "private"? All other seem >> package-private. > These fields are intended for usage only in > MHI.varargsArray/buildFiller. They were private before and I decided to > keep that. It is fine for MH_*/NF_* to be used from other places in > j.l.i (e.g. NF_checkSpreadArgument is used in LambdaFormEditor). Okay. My sentiment was on par with Remi's: needless access methods for private fields. Now that these fields are in Lazy, the access methods are generated when the fields are accessed from the enclosing class (MethodHandleImpl). >> * Any performance problems if we actually count FILL_ARRAYS_COUNT in >> during the static initialization, instead of putting a magic value? > It's more about code structure than performance. > > There's a dependency between FILL_ARRAYS size & LEFT_ARGS. > If FILL_ARRAYS_COUNT is moved to Lazy, LEFT_ARGS should be moved to Lazy > as well or LEFT_ARGS should be lazily initialized separately. > IMO it doesn't worth an effort. I am not talking about moving FILL_ARRAYS_COUNT to Lazy. I am talking about computing the FILL_ARRAYS_COUNT in the new static initializer of MethodHandleImpl itself -- so that we would not get bugs when adding new fillArray override. But, given there are asserts in the code, it seems excessive. Leave it as is. -Aleksey. From peter.levart at gmail.com Thu Oct 2 18:33:47 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 02 Oct 2014 20:33:47 +0200 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542D8370.1030107@oracle.com> References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> Message-ID: <542D9A8B.1000009@gmail.com> On 10/02/2014 06:55 PM, Vladimir Ivanov wrote: > Small update: > http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/ > > Need to reorder initialization sequence in MHI.Lazy. Initialized > FILL_ARRAYS and ARRAYS are required for later MH lookups. > > Additional testing: > * jck (api/java_lang/invoke) > * jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea -esa" and > COMPILE_THRESHOLD={0,30} > > Best regards, > Vladimir Ivanov Hi Vladimir, I have a comment that does not directly pertain to the code changes (the initialization of arrays) but to the sub-optimal implementation of "fillArray" methods I noticed by the way. While it is nice to use varargs "makeArray" helper method with "array" methods to construct the array, the same strategy used with "fillWithArguments" in "fillArray" methods makes a redundant array that is then copied to target array and discarded. The redundant copying has a price. Here's a benchmark (Aleksey, please bear with me): @State(Scope.Benchmark) public class FillArrayTest { private Object a0 = new Object(), a1 = new Object(), a2 = new Object(), a3 = new Object(), a4 = new Object(), a5 = new Object(), a6 = new Object(), a7 = new Object(); private static void fillWithArguments(Object[] a, int pos, Object... args) { System.arraycopy(args, 0, a, pos, args.length); } private static Object[] fillArray( Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7 ) { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; } private static Object[] fillArrayAlt( Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7 ) { int i = pos; a[i++] = a0; a[i++] = a1; a[i++] = a2; a[i++] = a3; a[i++] = a4; a[i++] = a5; a[i++] = a6; a[i++] = a7; return a; } @Benchmark public Object[] fillArray() { return fillArray(0, new Object[8], a0, a1, a2, a3, a4, a5, a6, a7); } @Benchmark public Object[] fillArrayAlt() { return fillArrayAlt(0, new Object[8], a0, a1, a2, a3, a4, a5, a6, a7); } } The results on my i7 with JMH arguments "-i 8 -wi 5 -f 1 -gc true": Benchmark Mode Samples Score Score error Units j.t.FillArrayTest.fillArray thrpt 8 48601447.674 5414853.634 ops/s j.t.FillArrayTest.fillArrayAlt thrpt 8 90044973.732 8713725.735 ops/s So fillArrayAlt is nearly twice as fast... Regards, Peter > > On 10/2/14, 7:52 PM, Vladimir Ivanov wrote: >> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/ >> https://bugs.openjdk.java.net/browse/JDK-8058892 >> >> Core j.l.i classes are preloaded during VM startup in order to avoid >> possible deadlock when accessing JSR292-related functionality from >> multiple threads. After LF sharing-related changes, FILL_ARRAYS and >> ARRAYS are initialized too early. It affects startup time & footprint of >> applications that don't use JSR292. >> >> The fix is to move these fields into MHI.Lazy class, thus delaying their >> initialization to the first usage of JSR292 API. >> >> Testing: failing test, manual (measured HelloWorld app startup time; >> compared -XX:+PrintCompilation logs) >> >> Best regards, >> Vladimir Ivanov > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev From vitalyd at gmail.com Thu Oct 2 18:42:07 2014 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Thu, 2 Oct 2014 14:42:07 -0400 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542D9A8B.1000009@gmail.com> References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> <542D9A8B.1000009@gmail.com> Message-ID: AFIK, varargs (up to something like 64 args) should be eliminated by EA. Peter, can you add another jmh test that uses varargs but doesn't call into System.arraycopy but uses the hand rolled version like your at method? I'm wondering if that makes EA not kick in. Sent from my phone On Oct 2, 2014 2:34 PM, "Peter Levart" wrote: > > On 10/02/2014 06:55 PM, Vladimir Ivanov wrote: > >> Small update: >> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/ >> >> Need to reorder initialization sequence in MHI.Lazy. Initialized >> FILL_ARRAYS and ARRAYS are required for later MH lookups. >> >> Additional testing: >> * jck (api/java_lang/invoke) >> * jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea -esa" and >> COMPILE_THRESHOLD={0,30} >> >> Best regards, >> Vladimir Ivanov >> > > Hi Vladimir, > > I have a comment that does not directly pertain to the code changes (the > initialization of arrays) but to the sub-optimal implementation of > "fillArray" methods I noticed by the way. While it is nice to use varargs > "makeArray" helper method with "array" methods to construct the array, the > same strategy used with "fillWithArguments" in "fillArray" methods makes a > redundant array that is then copied to target array and discarded. The > redundant copying has a price. Here's a benchmark (Aleksey, please bear > with me): > > @State(Scope.Benchmark) > public class FillArrayTest { > > private Object > a0 = new Object(), > a1 = new Object(), > a2 = new Object(), > a3 = new Object(), > a4 = new Object(), > a5 = new Object(), > a6 = new Object(), > a7 = new Object(); > > > private static void fillWithArguments(Object[] a, int pos, Object... > args) { > System.arraycopy(args, 0, a, pos, args.length); > } > > private static Object[] fillArray( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); > return a; > } > > private static Object[] fillArrayAlt( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > int i = pos; > a[i++] = a0; > a[i++] = a1; > a[i++] = a2; > a[i++] = a3; > a[i++] = a4; > a[i++] = a5; > a[i++] = a6; > a[i++] = a7; > return a; > } > > @Benchmark > public Object[] fillArray() { > return fillArray(0, new Object[8], a0, a1, a2, a3, a4, a5, a6, a7); > } > > @Benchmark > public Object[] fillArrayAlt() { > return fillArrayAlt(0, new Object[8], a0, a1, a2, a3, a4, a5, a6, > a7); > } > } > > > The results on my i7 with JMH arguments "-i 8 -wi 5 -f 1 -gc true": > > Benchmark Mode Samples Score Score > error Units > j.t.FillArrayTest.fillArray thrpt 8 48601447.674 5414853.634 > ops/s > j.t.FillArrayTest.fillArrayAlt thrpt 8 90044973.732 8713725.735 > ops/s > > > So fillArrayAlt is nearly twice as fast... > > Regards, Peter > > > >> On 10/2/14, 7:52 PM, Vladimir Ivanov wrote: >> >>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/ >>> https://bugs.openjdk.java.net/browse/JDK-8058892 >>> >>> Core j.l.i classes are preloaded during VM startup in order to avoid >>> possible deadlock when accessing JSR292-related functionality from >>> multiple threads. After LF sharing-related changes, FILL_ARRAYS and >>> ARRAYS are initialized too early. It affects startup time & footprint of >>> applications that don't use JSR292. >>> >>> The fix is to move these fields into MHI.Lazy class, thus delaying their >>> initialization to the first usage of JSR292 API. >>> >>> Testing: failing test, manual (measured HelloWorld app startup time; >>> compared -XX:+PrintCompilation logs) >>> >>> Best regards, >>> Vladimir Ivanov >>> >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >> > > From peter.levart at gmail.com Thu Oct 2 18:54:40 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 02 Oct 2014 20:54:40 +0200 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> <542D9A8B.1000009@gmail.com> Message-ID: <542D9F70.5040802@gmail.com> On 10/02/2014 08:42 PM, Vitaly Davidovich wrote: > > AFIK, varargs (up to something like 64 args) should be eliminated by > EA. Peter, can you add another jmh test that uses varargs but doesn't > call into System.arraycopy but uses the hand rolled version like your > at method? I'm wondering if that makes EA not kick in. > Hm, here is a modified benchmark (I also eliminated repeatable allocation of target array): @State(Scope.Benchmark) public class FillArrayTest { private Object a0 = new Object(), a1 = new Object(), a2 = new Object(), a3 = new Object(), a4 = new Object(), a5 = new Object(), a6 = new Object(), a7 = new Object(); private Object[] target = new Object[8]; private static void fillWithArguments(Object[] a, int pos, Object... args) { System.arraycopy(args, 0, a, pos, args.length); } private static Object[] fillArray( Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7 ) { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; } private static void fillWithArgumentsCopyLoop(Object[] a, int pos, Object... args) { for (int i = 0; i < args.length; i++) { a[i + pos] = args[i]; } } private static Object[] fillArrayCopyLoop( Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7 ) { fillWithArgumentsCopyLoop(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; } private static Object[] fillArrayAlt( Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7 ) { int i = pos; a[i++] = a0; a[i++] = a1; a[i++] = a2; a[i++] = a3; a[i++] = a4; a[i++] = a5; a[i++] = a6; a[i++] = a7; return a; } @Benchmark public Object[] fillArray() { return fillArray(0, target, a0, a1, a2, a3, a4, a5, a6, a7); } @Benchmark public Object[] fillCopyLoop() { return fillArrayCopyLoop(0, target, a0, a1, a2, a3, a4, a5, a6, a7); } @Benchmark public Object[] fillArrayAlt() { return fillArrayAlt(0, target, a0, a1, a2, a3, a4, a5, a6, a7); } } The results: Benchmark Mode Samples Score Score error Units j.t.FillArrayTest.fillArray thrpt 8 76534019.978 3063590.310 ops/s j.t.FillArrayTest.fillArrayAlt thrpt 8 141640280.270 7815152.038 ops/s j.t.FillArrayTest.fillCopyLoop thrpt 8 82050640.406 4055652.247 ops/s The fillCopyLoop seems a little faster. I don't know if this is because of possible elimination of allocation. The fillArrayAlt is still almost 2x as fast. Peter > Sent from my phone > > On Oct 2, 2014 2:34 PM, "Peter Levart" > wrote: > > > On 10/02/2014 06:55 PM, Vladimir Ivanov wrote: > > Small update: > http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/ > > > Need to reorder initialization sequence in MHI.Lazy. > Initialized FILL_ARRAYS and ARRAYS are required for later MH > lookups. > > Additional testing: > * jck (api/java_lang/invoke) > * jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea -esa" > and COMPILE_THRESHOLD={0,30} > > Best regards, > Vladimir Ivanov > > > Hi Vladimir, > > I have a comment that does not directly pertain to the code > changes (the initialization of arrays) but to the sub-optimal > implementation of "fillArray" methods I noticed by the way. While > it is nice to use varargs "makeArray" helper method with "array" > methods to construct the array, the same strategy used with > "fillWithArguments" in "fillArray" methods makes a redundant array > that is then copied to target array and discarded. The redundant > copying has a price. Here's a benchmark (Aleksey, please bear with > me): > > @State(Scope.Benchmark) > public class FillArrayTest { > > private Object > a0 = new Object(), > a1 = new Object(), > a2 = new Object(), > a3 = new Object(), > a4 = new Object(), > a5 = new Object(), > a6 = new Object(), > a7 = new Object(); > > > private static void fillWithArguments(Object[] a, int pos, > Object... args) { > System.arraycopy(args, 0, a, pos, args.length); > } > > private static Object[] fillArray( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); > return a; > } > > private static Object[] fillArrayAlt( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > int i = pos; > a[i++] = a0; > a[i++] = a1; > a[i++] = a2; > a[i++] = a3; > a[i++] = a4; > a[i++] = a5; > a[i++] = a6; > a[i++] = a7; > return a; > } > > @Benchmark > public Object[] fillArray() { > return fillArray(0, new Object[8], a0, a1, a2, a3, a4, a5, > a6, a7); > } > > @Benchmark > public Object[] fillArrayAlt() { > return fillArrayAlt(0, new Object[8], a0, a1, a2, a3, a4, > a5, a6, a7); > } > } > > > The results on my i7 with JMH arguments "-i 8 -wi 5 -f 1 -gc true": > > Benchmark Mode Samples Score > Score error Units > j.t.FillArrayTest.fillArray thrpt 8 48601447.674 > 5414853.634 ops/s > j.t.FillArrayTest.fillArrayAlt thrpt 8 90044973.732 > 8713725 .735 ops/s > > > So fillArrayAlt is nearly twice as fast... > > Regards, Peter > > > > On 10/2/14, 7:52 PM, Vladimir Ivanov wrote: > > http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/ > > https://bugs.openjdk.java.net/browse/JDK-8058892 > > Core j.l.i classes are preloaded during VM startup in > order to avoid > possible deadlock when accessing JSR292-related > functionality from > multiple threads. After LF sharing-related changes, > FILL_ARRAYS and > ARRAYS are initialized too early. It affects startup time > & footprint of > applications that don't use JSR292. > > The fix is to move these fields into MHI.Lazy class, thus > delaying their > initialization to the first usage of JSR292 API. > > Testing: failing test, manual (measured HelloWorld app > startup time; > compared -XX:+PrintCompilation logs) > > Best regards, > Vladimir Ivanov > > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > > From peter.levart at gmail.com Thu Oct 2 19:12:28 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 02 Oct 2014 21:12:28 +0200 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542D9F70.5040802@gmail.com> References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> <542D9A8B.1000009@gmail.com> <542D9F70.5040802@gmail.com> Message-ID: <542DA39C.5020402@gmail.com> Well, if I add the following variant to the mix: private static void fillWith8Arguments(Object[] a, int pos, Object... args) { a[pos] = args[0]; a[pos + 1] = args[1]; a[pos + 2] = args[2]; a[pos + 3] = args[3]; a[pos + 4] = args[4]; a[pos + 5] = args[5]; a[pos + 6] = args[6]; a[pos + 7] = args[7]; } private static Object[] fillArrayByHand( Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7 ) { fillWith8Arguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; } @Benchmark public Object[] fillByHand() { return fillArrayByHand(0, target, a0, a1, a2, a3, a4, a5, a6, a7); } The results: Benchmark Mode Samples Score Score error Units j.t.FillArrayTest.fillArray thrpt 8 75994667.408 4169836.951 ops/s j.t.FillArrayTest.fillArrayAlt thrpt 8 142761145.565 7127589.095 ops/s j.t.FillArrayTest.fillByHand thrpt 8 141206898.861 6435932.932 ops/s j.t.FillArrayTest.fillCopyLoop thrpt 8 82395900.795 2794747.540 ops/s ...show that with fillByHand, varargs array is indeed eliminated. But then the "helper" method is not of any help, since it's not reusable for different array lengths... Regards, Peter On 10/02/2014 08:54 PM, Peter Levart wrote: > > On 10/02/2014 08:42 PM, Vitaly Davidovich wrote: >> >> AFIK, varargs (up to something like 64 args) should be eliminated by >> EA. Peter, can you add another jmh test that uses varargs but >> doesn't call into System.arraycopy but uses the hand rolled version >> like your at method? I'm wondering if that makes EA not kick in. >> > > Hm, here is a modified benchmark (I also eliminated repeatable > allocation of target array): > > > @State(Scope.Benchmark) > public class FillArrayTest { > > private Object > a0 = new Object(), > a1 = new Object(), > a2 = new Object(), > a3 = new Object(), > a4 = new Object(), > a5 = new Object(), > a6 = new Object(), > a7 = new Object(); > > > private Object[] target = new Object[8]; > > private static void fillWithArguments(Object[] a, int pos, > Object... args) { > System.arraycopy(args, 0, a, pos, args.length); > } > > private static Object[] fillArray( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); > return a; > } > > private static void fillWithArgumentsCopyLoop(Object[] a, int pos, > Object... args) { > for (int i = 0; i < args.length; i++) { > a[i + pos] = args[i]; > } > } > > private static Object[] fillArrayCopyLoop( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > fillWithArgumentsCopyLoop(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); > return a; > } > > private static Object[] fillArrayAlt( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > int i = pos; > a[i++] = a0; > a[i++] = a1; > a[i++] = a2; > a[i++] = a3; > a[i++] = a4; > a[i++] = a5; > a[i++] = a6; > a[i++] = a7; > return a; > } > > @Benchmark > public Object[] fillArray() { > return fillArray(0, target, a0, a1, a2, a3, a4, a5, a6, a7); > } > > @Benchmark > public Object[] fillCopyLoop() { > return fillArrayCopyLoop(0, target, a0, a1, a2, a3, a4, a5, > a6, a7); > } > > @Benchmark > public Object[] fillArrayAlt() { > return fillArrayAlt(0, target, a0, a1, a2, a3, a4, a5, a6, a7); > } > } > > > > The results: > > > Benchmark Mode Samples Score Score > error Units > j.t.FillArrayTest.fillArray thrpt 8 76534019.978 > 3063590.310 ops/s > j.t.FillArrayTest.fillArrayAlt thrpt 8 141640280.270 > 7815152.038 ops/s > j.t.FillArrayTest.fillCopyLoop thrpt 8 82050640.406 > 4055652.247 ops/s > > > The fillCopyLoop seems a little faster. I don't know if this is > because of possible elimination of allocation. The fillArrayAlt is > still almost 2x as fast. > > Peter > >> Sent from my phone >> >> On Oct 2, 2014 2:34 PM, "Peter Levart" > > wrote: >> >> >> On 10/02/2014 06:55 PM, Vladimir Ivanov wrote: >> >> Small update: >> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/ >> >> >> Need to reorder initialization sequence in MHI.Lazy. >> Initialized FILL_ARRAYS and ARRAYS are required for later MH >> lookups. >> >> Additional testing: >> * jck (api/java_lang/invoke) >> * jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea -esa" >> and COMPILE_THRESHOLD={0,30} >> >> Best regards, >> Vladimir Ivanov >> >> >> Hi Vladimir, >> >> I have a comment that does not directly pertain to the code >> changes (the initialization of arrays) but to the sub-optimal >> implementation of "fillArray" methods I noticed by the way. While >> it is nice to use varargs "makeArray" helper method with "array" >> methods to construct the array, the same strategy used with >> "fillWithArguments" in "fillArray" methods makes a redundant >> array that is then copied to target array and discarded. The >> redundant copying has a price. Here's a benchmark (Aleksey, >> please bear with me): >> >> @State(Scope.Benchmark) >> public class FillArrayTest { >> >> private Object >> a0 = new Object(), >> a1 = new Object(), >> a2 = new Object(), >> a3 = new Object(), >> a4 = new Object(), >> a5 = new Object(), >> a6 = new Object(), >> a7 = new Object(); >> >> >> private static void fillWithArguments(Object[] a, int pos, >> Object... args) { >> System.arraycopy(args, 0, a, pos, args.length); >> } >> >> private static Object[] fillArray( >> Integer pos, Object[] a, >> Object a0, Object a1, Object a2, Object a3, >> Object a4, Object a5, Object a6, Object a7 >> ) { >> fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); >> return a; >> } >> >> private static Object[] fillArrayAlt( >> Integer pos, Object[] a, >> Object a0, Object a1, Object a2, Object a3, >> Object a4, Object a5, Object a6, Object a7 >> ) { >> int i = pos; >> a[i++] = a0; >> a[i++] = a1; >> a[i++] = a2; >> a[i++] = a3; >> a[i++] = a4; >> a[i++] = a5; >> a[i++] = a6; >> a[i++] = a7; >> return a; >> } >> >> @Benchmark >> public Object[] fillArray() { >> return fillArray(0, new Object[8], a0, a1, a2, a3, a4, >> a5, a6, a7); >> } >> >> @Benchmark >> public Object[] fillArrayAlt() { >> return fillArrayAlt(0, new Object[8], a0, a1, a2, a3, a4, >> a5, a6, a7); >> } >> } >> >> >> The results on my i7 with JMH arguments "-i 8 -wi 5 -f 1 -gc true": >> >> Benchmark Mode Samples Score Score >> error Units >> j.t.FillArrayTest.fillArray thrpt 8 48601447.674 >> 5414853.634 ops/s >> j.t.FillArrayTest.fillArrayAlt thrpt 8 90044973.732 >> 8713725 .735 ops/s >> >> >> So fillArrayAlt is nearly twice as fast... >> >> Regards, Peter >> >> >> >> On 10/2/14, 7:52 PM, Vladimir Ivanov wrote: >> >> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/ >> >> https://bugs.openjdk.java.net/browse/JDK-8058892 >> >> Core j.l.i classes are preloaded during VM startup in >> order to avoid >> possible deadlock when accessing JSR292-related >> functionality from >> multiple threads. After LF sharing-related changes, >> FILL_ARRAYS and >> ARRAYS are initialized too early. It affects startup time >> & footprint of >> applications that don't use JSR292. >> >> The fix is to move these fields into MHI.Lazy class, thus >> delaying their >> initialization to the first usage of JSR292 API. >> >> Testing: failing test, manual (measured HelloWorld app >> startup time; >> compared -XX:+PrintCompilation logs) >> >> Best regards, >> Vladimir Ivanov >> >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >> >> > From vitalyd at gmail.com Thu Oct 2 19:28:54 2014 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Thu, 2 Oct 2014 15:28:54 -0400 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542DA39C.5020402@gmail.com> References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> <542D9A8B.1000009@gmail.com> <542D9F70.5040802@gmail.com> <542DA39C.5020402@gmail.com> Message-ID: Yes, this is the version I wanted to see (i.e. where the only diff is varargs, and not any anything else like array iteration, etc). Why did fillCopyLoop() get some much worse than in your prior email though? On Thu, Oct 2, 2014 at 3:12 PM, Peter Levart wrote: > Well, if I add the following variant to the mix: > > private static void fillWith8Arguments(Object[] a, int pos, Object... > args) { > a[pos] = args[0]; > a[pos + 1] = args[1]; > a[pos + 2] = args[2]; > a[pos + 3] = args[3]; > a[pos + 4] = args[4]; > a[pos + 5] = args[5]; > a[pos + 6] = args[6]; > a[pos + 7] = args[7]; > } > > private static Object[] fillArrayByHand( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > fillWith8Arguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); > return a; > } > > @Benchmark > public Object[] fillByHand() { > return fillArrayByHand(0, target, a0, a1, a2, a3, a4, a5, a6, a7); > } > > The results: > > Benchmark Mode Samples Score Score > error Units > j.t.FillArrayTest.fillArray thrpt 8 75994667.408 > 4169836.951 ops/s > j.t.FillArrayTest.fillArrayAlt thrpt 8 142761145.565 > 7127589.095 ops/s > j.t.FillArrayTest.fillByHand thrpt 8 141206898.861 > 6435932.932 ops/s > j.t.FillArrayTest.fillCopyLoop thrpt 8 82395900.795 > 2794747.540 ops/s > > > ...show that with fillByHand, varargs array is indeed eliminated. But then > the "helper" method is not of any help, since it's not reusable for > different array lengths... > > > Regards, Peter > > > On 10/02/2014 08:54 PM, Peter Levart wrote: > > > On 10/02/2014 08:42 PM, Vitaly Davidovich wrote: > > AFIK, varargs (up to something like 64 args) should be eliminated by EA. > Peter, can you add another jmh test that uses varargs but doesn't call into > System.arraycopy but uses the hand rolled version like your at method? I'm > wondering if that makes EA not kick in. > > > Hm, here is a modified benchmark (I also eliminated repeatable allocation > of target array): > > > @State(Scope.Benchmark) > public class FillArrayTest { > > private Object > a0 = new Object(), > a1 = new Object(), > a2 = new Object(), > a3 = new Object(), > a4 = new Object(), > a5 = new Object(), > a6 = new Object(), > a7 = new Object(); > > > private Object[] target = new Object[8]; > > private static void fillWithArguments(Object[] a, int pos, Object... > args) { > System.arraycopy(args, 0, a, pos, args.length); > } > > private static Object[] fillArray( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); > return a; > } > > private static void fillWithArgumentsCopyLoop(Object[] a, int pos, > Object... args) { > for (int i = 0; i < args.length; i++) { > a[i + pos] = args[i]; > } > } > > private static Object[] fillArrayCopyLoop( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > fillWithArgumentsCopyLoop(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); > return a; > } > > private static Object[] fillArrayAlt( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > int i = pos; > a[i++] = a0; > a[i++] = a1; > a[i++] = a2; > a[i++] = a3; > a[i++] = a4; > a[i++] = a5; > a[i++] = a6; > a[i++] = a7; > return a; > } > > @Benchmark > public Object[] fillArray() { > return fillArray(0, target, a0, a1, a2, a3, a4, a5, a6, a7); > } > > @Benchmark > public Object[] fillCopyLoop() { > return fillArrayCopyLoop(0, target, a0, a1, a2, a3, a4, a5, a6, > a7); > } > > @Benchmark > public Object[] fillArrayAlt() { > return fillArrayAlt(0, target, a0, a1, a2, a3, a4, a5, a6, a7); > } > } > > > > The results: > > > Benchmark Mode Samples Score Score > error Units > j.t.FillArrayTest.fillArray thrpt 8 76534019.978 > 3063590.310 ops/s > j.t.FillArrayTest.fillArrayAlt thrpt 8 141640280.270 > 7815152.038 ops/s > j.t.FillArrayTest.fillCopyLoop thrpt 8 82050640.406 > 4055652.247 ops/s > > > The fillCopyLoop seems a little faster. I don't know if this is because of > possible elimination of allocation. The fillArrayAlt is still almost 2x as > fast. > > Peter > > Sent from my phone > On Oct 2, 2014 2:34 PM, "Peter Levart" wrote: > >> >> On 10/02/2014 06:55 PM, Vladimir Ivanov wrote: >> >>> Small update: >>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/ >>> >>> Need to reorder initialization sequence in MHI.Lazy. Initialized >>> FILL_ARRAYS and ARRAYS are required for later MH lookups. >>> >>> Additional testing: >>> * jck (api/java_lang/invoke) >>> * jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea -esa" and >>> COMPILE_THRESHOLD={0,30} >>> >>> Best regards, >>> Vladimir Ivanov >>> >> >> Hi Vladimir, >> >> I have a comment that does not directly pertain to the code changes (the >> initialization of arrays) but to the sub-optimal implementation of >> "fillArray" methods I noticed by the way. While it is nice to use varargs >> "makeArray" helper method with "array" methods to construct the array, the >> same strategy used with "fillWithArguments" in "fillArray" methods makes a >> redundant array that is then copied to target array and discarded. The >> redundant copying has a price. Here's a benchmark (Aleksey, please bear >> with me): >> >> @State(Scope.Benchmark) >> public class FillArrayTest { >> >> private Object >> a0 = new Object(), >> a1 = new Object(), >> a2 = new Object(), >> a3 = new Object(), >> a4 = new Object(), >> a5 = new Object(), >> a6 = new Object(), >> a7 = new Object(); >> >> >> private static void fillWithArguments(Object[] a, int pos, Object... >> args) { >> System.arraycopy(args, 0, a, pos, args.length); >> } >> >> private static Object[] fillArray( >> Integer pos, Object[] a, >> Object a0, Object a1, Object a2, Object a3, >> Object a4, Object a5, Object a6, Object a7 >> ) { >> fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); >> return a; >> } >> >> private static Object[] fillArrayAlt( >> Integer pos, Object[] a, >> Object a0, Object a1, Object a2, Object a3, >> Object a4, Object a5, Object a6, Object a7 >> ) { >> int i = pos; >> a[i++] = a0; >> a[i++] = a1; >> a[i++] = a2; >> a[i++] = a3; >> a[i++] = a4; >> a[i++] = a5; >> a[i++] = a6; >> a[i++] = a7; >> return a; >> } >> >> @Benchmark >> public Object[] fillArray() { >> return fillArray(0, new Object[8], a0, a1, a2, a3, a4, a5, a6, >> a7); >> } >> >> @Benchmark >> public Object[] fillArrayAlt() { >> return fillArrayAlt(0, new Object[8], a0, a1, a2, a3, a4, a5, a6, >> a7); >> } >> } >> >> >> The results on my i7 with JMH arguments "-i 8 -wi 5 -f 1 -gc true": >> >> Benchmark Mode Samples Score Score >> error Units >> j.t.FillArrayTest.fillArray thrpt 8 48601447.674 >> 5414853.634 ops/s >> j.t.FillArrayTest.fillArrayAlt thrpt 8 90044973.732 8713725.735 >> ops/s >> >> >> So fillArrayAlt is nearly twice as fast... >> >> Regards, Peter >> >> >> >>> On 10/2/14, 7:52 PM, Vladimir Ivanov wrote: >>> >>>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/ >>>> https://bugs.openjdk.java.net/browse/JDK-8058892 >>>> >>>> Core j.l.i classes are preloaded during VM startup in order to avoid >>>> possible deadlock when accessing JSR292-related functionality from >>>> multiple threads. After LF sharing-related changes, FILL_ARRAYS and >>>> ARRAYS are initialized too early. It affects startup time & footprint of >>>> applications that don't use JSR292. >>>> >>>> The fix is to move these fields into MHI.Lazy class, thus delaying their >>>> initialization to the first usage of JSR292 API. >>>> >>>> Testing: failing test, manual (measured HelloWorld app startup time; >>>> compared -XX:+PrintCompilation logs) >>>> >>>> Best regards, >>>> Vladimir Ivanov >>>> >>> _______________________________________________ >>> mlvm-dev mailing list >>> mlvm-dev at openjdk.java.net >>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >>> >> >> > > From peter.levart at gmail.com Thu Oct 2 20:47:45 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 02 Oct 2014 22:47:45 +0200 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> <542D9A8B.1000009@gmail.com> <542D9F70.5040802@gmail.com> <542DA39C.5020402@gmail.com> Message-ID: <542DB9F1.7040702@gmail.com> On 10/02/2014 09:28 PM, Vitaly Davidovich wrote: > Yes, this is the version I wanted to see (i.e. where the only diff is > varargs, and not any anything else like array iteration, etc). > Why did fillCopyLoop() get some much worse than in your prior email > though? 82050640.406 (+-4055652.247) vs. 82395900.795 (+-2794747.540) I don't see a noticeable difference (there's a lot of jitter - didn't turn off tiered compilation). Regards, Peter > > > > On Thu, Oct 2, 2014 at 3:12 PM, Peter Levart > wrote: > > Well, if I add the following variant to the mix: > > private static void fillWith8Arguments(Object[] a, int pos, > Object... args) { > a[pos] = args[0]; > a[pos + 1] = args[1]; > a[pos + 2] = args[2]; > a[pos + 3] = args[3]; > a[pos + 4] = args[4]; > a[pos + 5] = args[5]; > a[pos + 6] = args[6]; > a[pos + 7] = args[7]; > } > > private static Object[] fillArrayByHand( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > fillWith8Arguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); > return a; > } > > @Benchmark > public Object[] fillByHand() { > return fillArrayByHand(0, target, a0, a1, a2, a3, a4, a5, > a6, a7); > } > > The results: > > Benchmark Mode Samples Score Score > error Units > j.t.FillArrayTest.fillArray thrpt 8 75994667.408 > 4169836.951 ops/s > j.t.FillArrayTest.fillArrayAlt thrpt 8 142761145.565 > 7127589.095 ops/s > j.t.FillArrayTest.fillByHand thrpt 8 141206898.861 > 6435932.932 ops/s > j.t.FillArrayTest.fillCopyLoop thrpt 8 82395900.795 > 2794747.540 ops/s > > > ...show that with fillByHand, varargs array is indeed eliminated. > But then the "helper" method is not of any help, since it's not > reusable for different array lengths... > > > Regards, Peter > > > On 10/02/2014 08:54 PM, Peter Levart wrote: >> >> On 10/02/2014 08:42 PM, Vitaly Davidovich wrote: >>> >>> AFIK, varargs (up to something like 64 args) should be >>> eliminated by EA. Peter, can you add another jmh test that uses >>> varargs but doesn't call into System.arraycopy but uses the hand >>> rolled version like your at method? I'm wondering if that makes >>> EA not kick in. >>> >> >> Hm, here is a modified benchmark (I also eliminated repeatable >> allocation of target array): >> >> >> @State(Scope.Benchmark) >> public class FillArrayTest { >> >> private Object >> a0 = new Object(), >> a1 = new Object(), >> a2 = new Object(), >> a3 = new Object(), >> a4 = new Object(), >> a5 = new Object(), >> a6 = new Object(), >> a7 = new Object(); >> >> >> private Object[] target = new Object[8]; >> >> private static void fillWithArguments(Object[] a, int pos, >> Object... args) { >> System.arraycopy(args, 0, a, pos, args.length); >> } >> >> private static Object[] fillArray( >> Integer pos, Object[] a, >> Object a0, Object a1, Object a2, Object a3, >> Object a4, Object a5, Object a6, Object a7 >> ) { >> fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); >> return a; >> } >> >> private static void fillWithArgumentsCopyLoop(Object[] a, int >> pos, Object... args) { >> for (int i = 0; i < args.length; i++) { >> a[i + pos] = args[i]; >> } >> } >> >> private static Object[] fillArrayCopyLoop( >> Integer pos, Object[] a, >> Object a0, Object a1, Object a2, Object a3, >> Object a4, Object a5, Object a6, Object a7 >> ) { >> fillWithArgumentsCopyLoop(a, pos, a0, a1, a2, a3, a4, a5, >> a6, a7); >> return a; >> } >> >> private static Object[] fillArrayAlt( >> Integer pos, Object[] a, >> Object a0, Object a1, Object a2, Object a3, >> Object a4, Object a5, Object a6, Object a7 >> ) { >> int i = pos; >> a[i++] = a0; >> a[i++] = a1; >> a[i++] = a2; >> a[i++] = a3; >> a[i++] = a4; >> a[i++] = a5; >> a[i++] = a6; >> a[i++] = a7; >> return a; >> } >> >> @Benchmark >> public Object[] fillArray() { >> return fillArray(0, target, a0, a1, a2, a3, a4, a5, a6, a7); >> } >> >> @Benchmark >> public Object[] fillCopyLoop() { >> return fillArrayCopyLoop(0, target, a0, a1, a2, a3, a4, >> a5, a6, a7); >> } >> >> @Benchmark >> public Object[] fillArrayAlt() { >> return fillArrayAlt(0, target, a0, a1, a2, a3, a4, a5, >> a6, a7); >> } >> } >> >> >> >> The results: >> >> >> Benchmark Mode Samples Score >> Score error Units >> j.t.FillArrayTest.fillArray thrpt 8 76534019.978 >> 3063590.310 ops/s >> j.t.FillArrayTest.fillArrayAlt thrpt 8 141640280.270 >> 7815152.038 ops/s >> j.t.FillArrayTest.fillCopyLoop thrpt 8 82050640.406 >> 4055652.247 ops/s >> >> >> The fillCopyLoop seems a little faster. I don't know if this is >> because of possible elimination of allocation. The fillArrayAlt >> is still almost 2x as fast. >> >> Peter >> >>> Sent from my phone >>> >>> On Oct 2, 2014 2:34 PM, "Peter Levart" >> > wrote: >>> >>> >>> On 10/02/2014 06:55 PM, Vladimir Ivanov wrote: >>> >>> Small update: >>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/ >>> >>> >>> Need to reorder initialization sequence in MHI.Lazy. >>> Initialized FILL_ARRAYS and ARRAYS are required for >>> later MH lookups. >>> >>> Additional testing: >>> * jck (api/java_lang/invoke) >>> * jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea >>> -esa" and COMPILE_THRESHOLD={0,30} >>> >>> Best regards, >>> Vladimir Ivanov >>> >>> >>> Hi Vladimir, >>> >>> I have a comment that does not directly pertain to the code >>> changes (the initialization of arrays) but to the >>> sub-optimal implementation of "fillArray" methods I noticed >>> by the way. While it is nice to use varargs "makeArray" >>> helper method with "array" methods to construct the array, >>> the same strategy used with "fillWithArguments" in >>> "fillArray" methods makes a redundant array that is then >>> copied to target array and discarded. The redundant copying >>> has a price. Here's a benchmark (Aleksey, please bear with me): >>> >>> @State(Scope.Benchmark) >>> public class FillArrayTest { >>> >>> private Object >>> a0 = new Object(), >>> a1 = new Object(), >>> a2 = new Object(), >>> a3 = new Object(), >>> a4 = new Object(), >>> a5 = new Object(), >>> a6 = new Object(), >>> a7 = new Object(); >>> >>> >>> private static void fillWithArguments(Object[] a, int >>> pos, Object... args) { >>> System.arraycopy(args, 0, a, pos, args.length); >>> } >>> >>> private static Object[] fillArray( >>> Integer pos, Object[] a, >>> Object a0, Object a1, Object a2, Object a3, >>> Object a4, Object a5, Object a6, Object a7 >>> ) { >>> fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, >>> a6, a7); >>> return a; >>> } >>> >>> private static Object[] fillArrayAlt( >>> Integer pos, Object[] a, >>> Object a0, Object a1, Object a2, Object a3, >>> Object a4, Object a5, Object a6, Object a7 >>> ) { >>> int i = pos; >>> a[i++] = a0; >>> a[i++] = a1; >>> a[i++] = a2; >>> a[i++] = a3; >>> a[i++] = a4; >>> a[i++] = a5; >>> a[i++] = a6; >>> a[i++] = a7; >>> return a; >>> } >>> >>> @Benchmark >>> public Object[] fillArray() { >>> return fillArray(0, new Object[8], a0, a1, a2, a3, >>> a4, a5, a6, a7); >>> } >>> >>> @Benchmark >>> public Object[] fillArrayAlt() { >>> return fillArrayAlt(0, new Object[8], a0, a1, a2, >>> a3, a4, a5, a6, a7); >>> } >>> } >>> >>> >>> The results on my i7 with JMH arguments "-i 8 -wi 5 -f 1 -gc >>> true": >>> >>> Benchmark Mode Samples >>> Score Score error Units >>> j.t.FillArrayTest.fillArray thrpt 8 48601447.674 >>> 5414853.634 ops/s >>> j.t.FillArrayTest.fillArrayAlt thrpt 8 90044973.732 >>> 8713725 .735 ops/s >>> >>> >>> So fillArrayAlt is nearly twice as fast... >>> >>> Regards, Peter >>> >>> >>> >>> On 10/2/14, 7:52 PM, Vladimir Ivanov wrote: >>> >>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/ >>> >>> https://bugs.openjdk.java.net/browse/JDK-8058892 >>> >>> Core j.l.i classes are preloaded during VM startup >>> in order to avoid >>> possible deadlock when accessing JSR292-related >>> functionality from >>> multiple threads. After LF sharing-related changes, >>> FILL_ARRAYS and >>> ARRAYS are initialized too early. It affects startup >>> time & footprint of >>> applications that don't use JSR292. >>> >>> The fix is to move these fields into MHI.Lazy class, >>> thus delaying their >>> initialization to the first usage of JSR292 API. >>> >>> Testing: failing test, manual (measured HelloWorld >>> app startup time; >>> compared -XX:+PrintCompilation logs) >>> >>> Best regards, >>> Vladimir Ivanov >>> >>> _______________________________________________ >>> mlvm-dev mailing list >>> mlvm-dev at openjdk.java.net >>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >>> >>> >> > > From vitalyd at gmail.com Thu Oct 2 20:59:19 2014 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Thu, 2 Oct 2014 16:59:19 -0400 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542DB9F1.7040702@gmail.com> References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> <542D9A8B.1000009@gmail.com> <542D9F70.5040802@gmail.com> <542DA39C.5020402@gmail.com> <542DB9F1.7040702@gmail.com> Message-ID: Yes sorry, I meant jitter got so much worse. TieredCompilation could be a source -- I'd try turning it off to see what C2 peak is. I'm guessing your machine is otherwise quiet when you're running these benchmarks. On Thu, Oct 2, 2014 at 4:47 PM, Peter Levart wrote: > > On 10/02/2014 09:28 PM, Vitaly Davidovich wrote: > > Yes, this is the version I wanted to see (i.e. where the only diff is > varargs, and not any anything else like array iteration, etc). > > Why did fillCopyLoop() get some much worse than in your prior email > though? > > > 82050640.406 (+-4055652.247) vs. 82395900.795 (+-2794747.540) > > I don't see a noticeable difference (there's a lot of jitter - didn't turn > off tiered compilation). > > Regards, Peter > > > > > > On Thu, Oct 2, 2014 at 3:12 PM, Peter Levart > wrote: > >> Well, if I add the following variant to the mix: >> >> private static void fillWith8Arguments(Object[] a, int pos, Object... >> args) { >> a[pos] = args[0]; >> a[pos + 1] = args[1]; >> a[pos + 2] = args[2]; >> a[pos + 3] = args[3]; >> a[pos + 4] = args[4]; >> a[pos + 5] = args[5]; >> a[pos + 6] = args[6]; >> a[pos + 7] = args[7]; >> } >> >> private static Object[] fillArrayByHand( >> Integer pos, Object[] a, >> Object a0, Object a1, Object a2, Object a3, >> Object a4, Object a5, Object a6, Object a7 >> ) { >> fillWith8Arguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); >> return a; >> } >> >> @Benchmark >> public Object[] fillByHand() { >> return fillArrayByHand(0, target, a0, a1, a2, a3, a4, a5, a6, a7); >> } >> >> The results: >> >> Benchmark Mode Samples Score Score >> error Units >> j.t.FillArrayTest.fillArray thrpt 8 75994667.408 4169836.951 >> ops/s >> j.t.FillArrayTest.fillArrayAlt thrpt 8 142761145.565 >> 7127589.095 ops/s >> j.t.FillArrayTest.fillByHand thrpt 8 141206898.861 >> 6435932.932 ops/s >> j.t.FillArrayTest.fillCopyLoop thrpt 8 82395900.795 >> 2794747.540 ops/s >> >> >> ...show that with fillByHand, varargs array is indeed eliminated. But >> then the "helper" method is not of any help, since it's not reusable for >> different array lengths... >> >> >> Regards, Peter >> >> >> On 10/02/2014 08:54 PM, Peter Levart wrote: >> >> >> On 10/02/2014 08:42 PM, Vitaly Davidovich wrote: >> >> AFIK, varargs (up to something like 64 args) should be eliminated by EA. >> Peter, can you add another jmh test that uses varargs but doesn't call into >> System.arraycopy but uses the hand rolled version like your at method? I'm >> wondering if that makes EA not kick in. >> >> >> Hm, here is a modified benchmark (I also eliminated repeatable allocation >> of target array): >> >> >> @State(Scope.Benchmark) >> public class FillArrayTest { >> >> private Object >> a0 = new Object(), >> a1 = new Object(), >> a2 = new Object(), >> a3 = new Object(), >> a4 = new Object(), >> a5 = new Object(), >> a6 = new Object(), >> a7 = new Object(); >> >> >> private Object[] target = new Object[8]; >> >> private static void fillWithArguments(Object[] a, int pos, Object... >> args) { >> System.arraycopy(args, 0, a, pos, args.length); >> } >> >> private static Object[] fillArray( >> Integer pos, Object[] a, >> Object a0, Object a1, Object a2, Object a3, >> Object a4, Object a5, Object a6, Object a7 >> ) { >> fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); >> return a; >> } >> >> private static void fillWithArgumentsCopyLoop(Object[] a, int pos, >> Object... args) { >> for (int i = 0; i < args.length; i++) { >> a[i + pos] = args[i]; >> } >> } >> >> private static Object[] fillArrayCopyLoop( >> Integer pos, Object[] a, >> Object a0, Object a1, Object a2, Object a3, >> Object a4, Object a5, Object a6, Object a7 >> ) { >> fillWithArgumentsCopyLoop(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); >> return a; >> } >> >> private static Object[] fillArrayAlt( >> Integer pos, Object[] a, >> Object a0, Object a1, Object a2, Object a3, >> Object a4, Object a5, Object a6, Object a7 >> ) { >> int i = pos; >> a[i++] = a0; >> a[i++] = a1; >> a[i++] = a2; >> a[i++] = a3; >> a[i++] = a4; >> a[i++] = a5; >> a[i++] = a6; >> a[i++] = a7; >> return a; >> } >> >> @Benchmark >> public Object[] fillArray() { >> return fillArray(0, target, a0, a1, a2, a3, a4, a5, a6, a7); >> } >> >> @Benchmark >> public Object[] fillCopyLoop() { >> return fillArrayCopyLoop(0, target, a0, a1, a2, a3, a4, a5, a6, >> a7); >> } >> >> @Benchmark >> public Object[] fillArrayAlt() { >> return fillArrayAlt(0, target, a0, a1, a2, a3, a4, a5, a6, a7); >> } >> } >> >> >> >> The results: >> >> >> Benchmark Mode Samples Score Score >> error Units >> j.t.FillArrayTest.fillArray thrpt 8 76534019.978 3063590.310 >> ops/s >> j.t.FillArrayTest.fillArrayAlt thrpt 8 141640280.270 7815152.038 >> ops/s >> j.t.FillArrayTest.fillCopyLoop thrpt 8 82050640.406 4055652.247 >> ops/s >> >> >> The fillCopyLoop seems a little faster. I don't know if this is because >> of possible elimination of allocation. The fillArrayAlt is still almost 2x >> as fast. >> >> Peter >> >> Sent from my phone >> On Oct 2, 2014 2:34 PM, "Peter Levart" wrote: >> >>> >>> On 10/02/2014 06:55 PM, Vladimir Ivanov wrote: >>> >>>> Small update: >>>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/ >>>> >>>> Need to reorder initialization sequence in MHI.Lazy. Initialized >>>> FILL_ARRAYS and ARRAYS are required for later MH lookups. >>>> >>>> Additional testing: >>>> * jck (api/java_lang/invoke) >>>> * jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea -esa" and >>>> COMPILE_THRESHOLD={0,30} >>>> >>>> Best regards, >>>> Vladimir Ivanov >>>> >>> >>> Hi Vladimir, >>> >>> I have a comment that does not directly pertain to the code changes (the >>> initialization of arrays) but to the sub-optimal implementation of >>> "fillArray" methods I noticed by the way. While it is nice to use varargs >>> "makeArray" helper method with "array" methods to construct the array, the >>> same strategy used with "fillWithArguments" in "fillArray" methods makes a >>> redundant array that is then copied to target array and discarded. The >>> redundant copying has a price. Here's a benchmark (Aleksey, please bear >>> with me): >>> >>> @State(Scope.Benchmark) >>> public class FillArrayTest { >>> >>> private Object >>> a0 = new Object(), >>> a1 = new Object(), >>> a2 = new Object(), >>> a3 = new Object(), >>> a4 = new Object(), >>> a5 = new Object(), >>> a6 = new Object(), >>> a7 = new Object(); >>> >>> >>> private static void fillWithArguments(Object[] a, int pos, Object... >>> args) { >>> System.arraycopy(args, 0, a, pos, args.length); >>> } >>> >>> private static Object[] fillArray( >>> Integer pos, Object[] a, >>> Object a0, Object a1, Object a2, Object a3, >>> Object a4, Object a5, Object a6, Object a7 >>> ) { >>> fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); >>> return a; >>> } >>> >>> private static Object[] fillArrayAlt( >>> Integer pos, Object[] a, >>> Object a0, Object a1, Object a2, Object a3, >>> Object a4, Object a5, Object a6, Object a7 >>> ) { >>> int i = pos; >>> a[i++] = a0; >>> a[i++] = a1; >>> a[i++] = a2; >>> a[i++] = a3; >>> a[i++] = a4; >>> a[i++] = a5; >>> a[i++] = a6; >>> a[i++] = a7; >>> return a; >>> } >>> >>> @Benchmark >>> public Object[] fillArray() { >>> return fillArray(0, new Object[8], a0, a1, a2, a3, a4, a5, a6, >>> a7); >>> } >>> >>> @Benchmark >>> public Object[] fillArrayAlt() { >>> return fillArrayAlt(0, new Object[8], a0, a1, a2, a3, a4, a5, >>> a6, a7); >>> } >>> } >>> >>> >>> The results on my i7 with JMH arguments "-i 8 -wi 5 -f 1 -gc true": >>> >>> Benchmark Mode Samples Score Score >>> error Units >>> j.t.FillArrayTest.fillArray thrpt 8 48601447.674 >>> 5414853.634 ops/s >>> j.t.FillArrayTest.fillArrayAlt thrpt 8 90044973.732 8713725 >>> <732%208713725>.735 ops/s >>> >>> >>> So fillArrayAlt is nearly twice as fast... >>> >>> Regards, Peter >>> >>> >>> >>>> On 10/2/14, 7:52 PM, Vladimir Ivanov wrote: >>>> >>>>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/ >>>>> https://bugs.openjdk.java.net/browse/JDK-8058892 >>>>> >>>>> Core j.l.i classes are preloaded during VM startup in order to avoid >>>>> possible deadlock when accessing JSR292-related functionality from >>>>> multiple threads. After LF sharing-related changes, FILL_ARRAYS and >>>>> ARRAYS are initialized too early. It affects startup time & footprint >>>>> of >>>>> applications that don't use JSR292. >>>>> >>>>> The fix is to move these fields into MHI.Lazy class, thus delaying >>>>> their >>>>> initialization to the first usage of JSR292 API. >>>>> >>>>> Testing: failing test, manual (measured HelloWorld app startup time; >>>>> compared -XX:+PrintCompilation logs) >>>>> >>>>> Best regards, >>>>> Vladimir Ivanov >>>>> >>>> _______________________________________________ >>>> mlvm-dev mailing list >>>> mlvm-dev at openjdk.java.net >>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >>>> >>> >>> >> >> > > From vladimir.x.ivanov at oracle.com Fri Oct 3 14:12:04 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Fri, 03 Oct 2014 18:12:04 +0400 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542D9335.4050705@oracle.com> References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> <542D84BB.9070407@oracle.com> <542D8AC8.7030506@oracle.com> <542D9335.4050705@oracle.com> Message-ID: <542EAEB4.5010707@oracle.com> >> Updated version: >> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.02/ > > Looks good. Thanks, Aleksey. Any "capital-R" volunteers to review this change? :-) Best regards, Vladimir Ivanov From vladimir.x.ivanov at oracle.com Fri Oct 3 14:17:47 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Fri, 03 Oct 2014 18:17:47 +0400 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542D9A8B.1000009@gmail.com> References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> <542D9A8B.1000009@gmail.com> Message-ID: <542EB00B.7010902@oracle.com> Peter, That's an interesting observation. As Vitaly already pointed out, varargs array should be eliminated by EA, but it seems it's not for this particular code shape. I'll look into what's going on there and file a followup bug. Thanks for the feedback! Best regards, Vladimir Ivanov On 10/2/14, 10:33 PM, Peter Levart wrote: > > On 10/02/2014 06:55 PM, Vladimir Ivanov wrote: >> Small update: >> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/ >> >> Need to reorder initialization sequence in MHI.Lazy. Initialized >> FILL_ARRAYS and ARRAYS are required for later MH lookups. >> >> Additional testing: >> * jck (api/java_lang/invoke) >> * jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea -esa" and >> COMPILE_THRESHOLD={0,30} >> >> Best regards, >> Vladimir Ivanov > > Hi Vladimir, > > I have a comment that does not directly pertain to the code changes (the > initialization of arrays) but to the sub-optimal implementation of > "fillArray" methods I noticed by the way. While it is nice to use > varargs "makeArray" helper method with "array" methods to construct the > array, the same strategy used with "fillWithArguments" in "fillArray" > methods makes a redundant array that is then copied to target array and > discarded. The redundant copying has a price. Here's a benchmark > (Aleksey, please bear with me): > > @State(Scope.Benchmark) > public class FillArrayTest { > > private Object > a0 = new Object(), > a1 = new Object(), > a2 = new Object(), > a3 = new Object(), > a4 = new Object(), > a5 = new Object(), > a6 = new Object(), > a7 = new Object(); > > > private static void fillWithArguments(Object[] a, int pos, > Object... args) { > System.arraycopy(args, 0, a, pos, args.length); > } > > private static Object[] fillArray( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); > return a; > } > > private static Object[] fillArrayAlt( > Integer pos, Object[] a, > Object a0, Object a1, Object a2, Object a3, > Object a4, Object a5, Object a6, Object a7 > ) { > int i = pos; > a[i++] = a0; > a[i++] = a1; > a[i++] = a2; > a[i++] = a3; > a[i++] = a4; > a[i++] = a5; > a[i++] = a6; > a[i++] = a7; > return a; > } > > @Benchmark > public Object[] fillArray() { > return fillArray(0, new Object[8], a0, a1, a2, a3, a4, a5, a6, a7); > } > > @Benchmark > public Object[] fillArrayAlt() { > return fillArrayAlt(0, new Object[8], a0, a1, a2, a3, a4, a5, > a6, a7); > } > } > > > The results on my i7 with JMH arguments "-i 8 -wi 5 -f 1 -gc true": > > Benchmark Mode Samples Score Score > error Units > j.t.FillArrayTest.fillArray thrpt 8 48601447.674 > 5414853.634 ops/s > j.t.FillArrayTest.fillArrayAlt thrpt 8 90044973.732 > 8713725.735 ops/s > > > So fillArrayAlt is nearly twice as fast... > > Regards, Peter > > >> >> On 10/2/14, 7:52 PM, Vladimir Ivanov wrote: >>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/ >>> https://bugs.openjdk.java.net/browse/JDK-8058892 >>> >>> Core j.l.i classes are preloaded during VM startup in order to avoid >>> possible deadlock when accessing JSR292-related functionality from >>> multiple threads. After LF sharing-related changes, FILL_ARRAYS and >>> ARRAYS are initialized too early. It affects startup time & footprint of >>> applications that don't use JSR292. >>> >>> The fix is to move these fields into MHI.Lazy class, thus delaying their >>> initialization to the first usage of JSR292 API. >>> >>> Testing: failing test, manual (measured HelloWorld app startup time; >>> compared -XX:+PrintCompilation logs) >>> >>> Best regards, >>> Vladimir Ivanov >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > > > > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From Alan.Bateman at oracle.com Fri Oct 3 15:19:43 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 03 Oct 2014 08:19:43 -0700 Subject: RFR(L): JDK-8057777 Cleanup of old and unused VM interfaces In-Reply-To: <542AC0E8.9040409@oracle.com> References: <542AC0E8.9040409@oracle.com> Message-ID: <542EBE8F.5090800@oracle.com> On 30/09/2014 07:40, Frederic Parain wrote: > Hi all, > > Please review changes for bug JDK-8057777 "Cleanup of old > and unused VM interfaces" > > CR: > https://bugs.openjdk.java.net/browse/JDK-8057777 > > This is basically a big cleanup of VM interfaces that are > not used anymore by the JDK but have been kept in our code > base for historical reasons (HotSpot Express for instance). > These changesets remove these interfaces from both the > JDK and the HotSpot side, and also perform some cleanup > on code that directly referenced the removed interfaces. > > These changes do not modify the behavior of the Java > classes impacted by the cleanup. > > VM interfaces removal has been approved by CCC and > a Release Note has been prepared that explicitly list > all the removed interfaces. > > Testing: JPRT hotspot + core, vm.quick.testlist, jdk_core > > Webrevs: > http://cr.openjdk.java.net/~fparain/8057777/ cc'ing core-libs-dev as part of this is clean-up in the library code too. I think we should deprecate java.lang.Compiler and the Runtime.traceXXX methods. They've been non-functional for a long time and having them in the API is a bit mis-leading to anyone reading the javadoc. I realize you are focused on the removing the old JVM_* functions so we can follow-up on that via other issues of course. Can ClassLoader#resolveClass0 can be removed completely? The null check can be done in ClassLoader#resolveClass. In the mapfile for libjava then the comment at line 281 says "ZipFile.c needs this one". As getLastErrorString is now exported for use by libzip then the comment should probably be updated. Otherwise this clean-up looks good to me and the jdk_core group of tests is the right group to exercise this area. -Alan From frederic.parain at oracle.com Fri Oct 3 16:02:54 2014 From: frederic.parain at oracle.com (Frederic Parain) Date: Fri, 03 Oct 2014 18:02:54 +0200 Subject: RFR(L): JDK-8057777 Cleanup of old and unused VM interfaces In-Reply-To: <542EBE8F.5090800@oracle.com> References: <542AC0E8.9040409@oracle.com> <542EBE8F.5090800@oracle.com> Message-ID: <542EC8AE.90808@oracle.com> Alan, Thank you for your feedback, see my comments below. On 03/10/2014 17:19, Alan Bateman wrote: > On 30/09/2014 07:40, Frederic Parain wrote: >> Hi all, >> >> Please review changes for bug JDK-8057777 "Cleanup of old >> and unused VM interfaces" >> >> CR: >> https://bugs.openjdk.java.net/browse/JDK-8057777 >> >> This is basically a big cleanup of VM interfaces that are >> not used anymore by the JDK but have been kept in our code >> base for historical reasons (HotSpot Express for instance). >> These changesets remove these interfaces from both the >> JDK and the HotSpot side, and also perform some cleanup >> on code that directly referenced the removed interfaces. >> >> These changes do not modify the behavior of the Java >> classes impacted by the cleanup. >> >> VM interfaces removal has been approved by CCC and >> a Release Note has been prepared that explicitly list >> all the removed interfaces. >> >> Testing: JPRT hotspot + core, vm.quick.testlist, jdk_core >> >> Webrevs: >> http://cr.openjdk.java.net/~fparain/8057777/ > cc'ing core-libs-dev as part of this is clean-up in the library code too. > > I think we should deprecate java.lang.Compiler and the Runtime.traceXXX > methods. They've been non-functional for a long time and having them in > the API is a bit mis-leading to anyone reading the javadoc. I realize > you are focused on the removing the old JVM_* functions so we can > follow-up on that via other issues of course. Deprecating class and methods would require another CCC approval, so I'd prefer to post-pone this change to another changeset. > Can ClassLoader#resolveClass0 can be removed completely? The null check > can be done in ClassLoader#resolveClass. Done. > In the mapfile for libjava then the comment at line 281 says "ZipFile.c > needs this one". As getLastErrorString is now exported for use by libzip > then the comment should probably be updated. Done. > Otherwise this clean-up looks good to me and the jdk_core group of tests > is the right group to exercise this area. Thank you, the new jdk webrev is here: http://cr.openjdk.java.net/~fparain/8057777/jdk_v02/ Regards, Fred -- Frederic Parain - Oracle Grenoble Engineering Center - France Phone: +33 4 76 18 81 17 Email: Frederic.Parain at oracle.com From xueming.shen at oracle.com Fri Oct 3 16:07:16 2014 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 03 Oct 2014 09:07:16 -0700 Subject: RFR(L): JDK-8057777 Cleanup of old and unused VM interfaces In-Reply-To: <542EBE8F.5090800@oracle.com> References: <542AC0E8.9040409@oracle.com> <542EBE8F.5090800@oracle.com> Message-ID: <542EC9B4.1050908@oracle.com> On 10/3/14 8:19 AM, Alan Bateman wrote: > On 30/09/2014 07:40, Hideric Parain wrote: >> Hi all, >> >> Please review changes for bug JDK-8057777 "Cleanup of old >> and unused VM interfaces" >> >> CR: >> https://bugs.openjdk.java.net/browse/JDK-8057777 >> >> This is basically a big cleanup of VM interfaces that are >> not used anymore by the JDK but have been kept in our code >> base for historical reasons (HotSpot Express for instance). >> These changesets remove these interfaces from both the >> JDK and the HotSpot side, and also perform some cleanup >> on code that directly referenced the removed interfaces. >> >> These changes do not modify the behavior of the Java >> classes impacted by the cleanup. >> >> VM interfaces removal has been approved by CCC and >> a Release Note has been prepared that explicitly list >> all the removed interfaces. >> >> Testing: JPRT hotspot + core, vm.quick.testlist, jdk_core >> >> Webrevs: >> http://cr.openjdk.java.net/~fparain/8057777/ > cc'ing core-libs-dev as part of this is clean-up in the library code too. > > I think we should deprecate java.lang.Compiler and the > Runtime.traceXXX methods. They've been non-functional for a long time > and having them in the API is a bit mis-leading to anyone reading the > javadoc. I realize you are focused on the removing the old JVM_* > functions so we can follow-up on that via other issues of course. > > Can ClassLoader#resolveClass0 can be removed completely? The null > check can be done in ClassLoader#resolveClass. > > In the mapfile for libjava then the comment at line 281 says > "ZipFile.c needs this one". As getLastErrorString is now exported for > use by libzip then the comment should probably be updated. > > Otherwise this clean-up looks good to me and the jdk_core group of > tests is the right group to exercise this area. > > -Alan > Hi, ZipFile.c expects the JVM_Open() to handle the JVM_O_DELETE, with explicit unlink on linux/solaris for example. I would assume the open from the c library does not handle it and we need to do it explicitly by ZipFile.c now? -Sherman From vladimir.kozlov at oracle.com Fri Oct 3 16:57:22 2014 From: vladimir.kozlov at oracle.com (Vladimir Kozlov) Date: Fri, 03 Oct 2014 09:57:22 -0700 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542EAEB4.5010707@oracle.com> References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> <542D84BB.9070407@oracle.com> <542D8AC8.7030506@oracle.com> <542D9335.4050705@oracle.com> <542EAEB4.5010707@oracle.com> Message-ID: <542ED572.2040400@oracle.com> Looks fine to me. Can you push it into our jdk9/hs-comp/jdk repo so we can see immediate results from it in our testing? Thanks, Vladimir On 10/3/14 7:12 AM, Vladimir Ivanov wrote: >>> Updated version: >>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.02/ >> >> Looks good. > Thanks, Aleksey. > > Any "capital-R" volunteers to review this change? :-) > > Best regards, > Vladimir Ivanov > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev From cnewland at chrisnewland.com Fri Oct 3 17:04:55 2014 From: cnewland at chrisnewland.com (Chris Newland) Date: Fri, 3 Oct 2014 18:04:55 +0100 Subject: Fwd: No for each loop comment? In-Reply-To: References: <9D348A16-A49D-4C38-81B0-6E66B86DCB07@gmail.com> <58EE9B4F-B192-493F-90DE-E2DD7C329CB5@dslextreme.com> <54297913.30706@redhat.com> Message-ID: Hi Paul, I've created a tool called JITWatch[1] which might be useful here. It parses the LogCompilation output, shows the source/bytecode/assembly and can highlight inlining failures due to exceeding the thresholds. If you could point me to the code you're having trouble with I'd be happy to run it through the tool and let you know the findings. Kind regards, Chris [1] https://github.com/AdoptOpenJDK/jitwatch On Mon, September 29, 2014 19:03, Vitaly Davidovich wrote: > Bytecode isn't that interesting when discussing peak performance of jit'd > code. Do you have assembly dumps? > > The only noteworthy aspect of the bytecode is that the enhanced for loop > version is slightly bigger, and combined with other code in some method, > may inhibit inlining. > > Speaking of which, have you tried running the jmh benchmarks with tiered > compilation disabled? If not, please do as it may introduce > variance/noise. > > Sent from my phone > On Sep 29, 2014 1:58 PM, "Paul Benedict" wrote: > > >> Bytecode output courtesy of Mikael St??ldal: >> >> >> With standard loop: >> >> >> private static boolean contains(org.apache.logging.log4j.Marker, >> org.apache.logging.log4j.Marker...); Code: >> 0: iconst_0 >> 1: istore_2 >> 2: aload_1 >> 3: arraylength >> 4: istore_3 >> 5: iload_2 >> 6: iload_3 >> 7: if_icmpge 29 >> 10: aload_1 >> 11: iload_2 >> 12: aaload >> 13: astore 4 >> 15: aload 4 >> 17: aload_0 >> 18: if_acmpne 23 >> 21: iconst_1 >> 22: ireturn >> 23: iinc 2, 1 >> 26: goto 5 >> 29: iconst_0 >> 30: ireturn >> >> >> >> With for-each: >> >> >> private static boolean contains(org.apache.logging.log4j.Marker, >> org.apache.logging.log4j.Marker...); Code: >> 0: aload_1 >> 1: astore_2 >> 2: aload_2 >> 3: arraylength >> 4: istore_3 >> 5: iconst_0 >> 6: istore 4 >> 8: iload 4 >> 10: iload_3 >> 11: if_icmpge 34 >> 14: aload_2 >> 15: iload 4 >> 17: aaload >> 18: astore 5 >> 20: aload 5 >> 22: aload_0 >> 23: if_acmpne 28 >> 26: iconst_1 >> 27: ireturn >> 28: iinc 4, 1 >> 31: goto 8 >> 34: iconst_0 >> 35: ireturn >> >> >> >> >> Cheers, >> Paul >> >> >> On Mon, Sep 29, 2014 at 11:31 AM, Vitaly Davidovich >> wrote: >> >> >>> I think Paul's email already has jmh output. >>> >>> >>> I looked at the generated asm on 7u60 x64 linux, and didn't see any >>> material difference. >>> >>> Paul, have you or anyone else looked at the machine code diffs >>> between the two? Looking at timing is useful, but it's possible to get >>> caught up in noise; the generated assembly should provide more >>> conclusive data on whether any real difference is there or not. >>> >>> On Mon, Sep 29, 2014 at 11:21 AM, Andrew Haley >>> wrote: >>> >>> >>>> On 09/29/2014 03:29 PM, Paul Benedict wrote: >>>> >>>>> Open JDKers, I am forwarding an email to get some clarification. >>>>> It's >>>>> >>>> been >>>>> a common understanding that foreach should perform no differently >>>>> than >>>> the >>>>> equivalent for-loop . However, some fellow developers claim there >>>>> is a noticable difference in their microbenchmarking. Can you help >>>>> explain >>>> what >>>>> is really going on? It's either the case there is a true >>>>> difference (a result that would surprise me) or the results are >>>>> within a margin of >>>> error >>>>> that make the results insignificant. Please advise. >>>> >>>> The actual code that such a forEach loop generates is this: >>>> >>>> >>>> private int forLoop(final int[] array) { int result = 0; int[] a = >>>> array; int len = a.length; for (int i = 0; i < len; i++) { int element >>>> = a[i]; >>>> result ^= element; } >>>> return result; } >>>> >>>> >>>> If you get different timings for this one, then the measurements >>>> are suspect. >>>> >>>> Java microbenchmarking is notoriously difficult. Please try to use >>>> jmh; you'll get better and easier to interpret results. >>>> >>>> Andrew. >>>> >>>> >>>> >>>> http://openjdk.java.net/projects/code-tools/jmh/ >>>> >>>> >>>> >>> >> > From huizhe.wang at oracle.com Fri Oct 3 17:21:01 2014 From: huizhe.wang at oracle.com (huizhe wang) Date: Fri, 03 Oct 2014 10:21:01 -0700 Subject: RFR (JAXP): 8036951: Xerces Update: XMLSchemaValidator.java and XMLSchemaLoader.java Message-ID: <542EDAFD.7030406@oracle.com> Hi, This patch contains updates to 52 classes, mostly completely updated to the trunk except a few. I replaced some obsolete usages (e.g. Vector), but not all of them in order to not expand the update into more classes. With this patch, the main validation section is updated to the current trunk. New tests were added. Previously added tests were updated. Fixed a few test failures caused by later revisions, or difference in the JDK implementation with regards to the default settings of FEATURE_SECURE_PROCESSING (JDK set the default to true, see FeaturePropagationTest.java). A full-test (JPRT, unit/funtional/TCK tests) passed. Please review: https://bugs.openjdk.java.net/browse/JDK-8036951 http://cr.openjdk.java.net/~joehw/jdk9/8036951/webrev/ Thanks, Joe From vladimir.x.ivanov at oracle.com Fri Oct 3 18:28:00 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Fri, 03 Oct 2014 22:28:00 +0400 Subject: [9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl In-Reply-To: <542ED572.2040400@oracle.com> References: <542D74A4.9050303@oracle.com> <542D8370.1030107@oracle.com> <542D84BB.9070407@oracle.com> <542D8AC8.7030506@oracle.com> <542D9335.4050705@oracle.com> <542EAEB4.5010707@oracle.com> <542ED572.2040400@oracle.com> Message-ID: <542EEAB0.20304@oracle.com> Vladimir, thanks! No problem, I'll integrate the fix through hs-comp repo. Best regards, Vladimir Ivanov On 10/3/14, 8:57 PM, Vladimir Kozlov wrote: > Looks fine to me. > Can you push it into our jdk9/hs-comp/jdk repo so we can see immediate > results from it in our testing? > > Thanks, > Vladimir > > On 10/3/14 7:12 AM, Vladimir Ivanov wrote: >>>> Updated version: >>>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.02/ >>> >>> Looks good. >> Thanks, Aleksey. >> >> Any "capital-R" volunteers to review this change? :-) >> >> Best regards, >> Vladimir Ivanov >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev From ecki at zusammenkunft.net Sat Oct 4 23:54:13 2014 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Sun, 5 Oct 2014 01:54:13 +0200 Subject: Windows executing bat/cmd Message-ID: <20141005015413.0000254f.ecki@zusammenkunft.net> Hello, I noticed that MSDN CreateProcess(W) talks about using "cmd /c" for executing .bat and .cmd files: "To run a batch file, you must start the command interpreter; set lpApplicationName to cmd.exe and set lpCommandLine to the following arguments: /c plus the name of the batch file." However the JDK implementation seems to accept an executable path pointing to a *.bat or *.cmd file. When I look through the windows specific code for ProcessImpl.java and ProcessImpl_md.c it looks like Java is expecting this (undocumented?) behaviour and even supporting it (as it parses cmd+bat commands stricter than exectables and looks for MZ signature etc). I don't see a comment discussing the not-documented behaviour of CreateProcessW and also there is no API Doc encouraging or deprecating the use of cmd[0]="bla.bat" in Process Builder (or I have missed it). Anybody can enlighten me? Gruss Bernd Sample code: it does allow bat/cmd: - http://stackoverflow.com/questions/21553379/createprocess-is-able-to-execute-batch-files-but-documentation-says-the-opposit JDK7u code: - http://hg.openjdk.java.net/jdk7u/jdk7u/jdk/file/1ed30c084e3d/src/windows/native/java/lang/ProcessImpl_md.c - http://hg.openjdk.java.net/jdk7u/jdk7u/jdk/file/1ed30c084e3d/src/windows/classes/java/lang/ProcessImpl.java MSDN CreateProcessW - http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx MSDN Sample usage: - http://msdn.microsoft.com/en-us/library/windows/desktop/ms682512%28v=vs.85%29.aspx From Alan.Bateman at oracle.com Sun Oct 5 01:21:58 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Sat, 04 Oct 2014 18:21:58 -0700 Subject: Windows executing bat/cmd In-Reply-To: <20141005015413.0000254f.ecki@zusammenkunft.net> References: <20141005015413.0000254f.ecki@zusammenkunft.net> Message-ID: <54309D36.3000802@oracle.com> On 04/10/2014 16:54, Bernd Eckenfels wrote: > Hello, > > I noticed that MSDN CreateProcess(W) talks about using "cmd /c" for > executing .bat and .cmd files: > > "To run a batch file, you must start the command interpreter; > set lpApplicationName to cmd.exe and set lpCommandLine to the > following arguments: /c plus the name of the batch file." > > However the JDK implementation seems to accept an executable path pointing > to a *.bat or *.cmd file. > > It's for compatibility reasons. There is a lot of code that calls Runtime.exec to run .cmd and .bat scripts. Early versions of the JDK didn't do much validation in this area and just passed the input to the win32 call. The checking has been tightened up a lot since and part had to deal with compatibility and keeping existing applications working. -Alan From ecki at zusammenkunft.net Sun Oct 5 02:12:31 2014 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Sun, 5 Oct 2014 04:12:31 +0200 Subject: Windows executing bat/cmd In-Reply-To: <54309D36.3000802@oracle.com> References: <20141005015413.0000254f.ecki@zusammenkunft.net> <54309D36.3000802@oracle.com> Message-ID: <20141005041231.00007def.ecki@zusammenkunft.net> Am Sat, 04 Oct 2014 18:21:58 -0700 schrieb Alan Bateman : > It's for compatibility reasons. There is a lot of code that calls > Runtime.exec to run .cmd and .bat scripts. Early versions of the JDK > didn't do much validation in this area and just passed the input to > the win32 call. The checking has been tightened up a lot since and > part had to deal with compatibility and keeping existing applications > working. This creates the interesting situation, that the JVM verifies stricter if you not use the (Microsoft recommended) "cmd /C". (In fact the implementation even documents this as a workaround if you want to avoid the validation.) Would it make sense to officially describe this in the exec(String[]), that you can specify the path to a bat/cmd file as the first argument and do not need to use the cmd /c? Gruss Bernd From Alan.Bateman at oracle.com Sun Oct 5 19:12:29 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Sun, 05 Oct 2014 12:12:29 -0700 Subject: Windows executing bat/cmd In-Reply-To: <20141005041231.00007def.ecki@zusammenkunft.net> References: <20141005015413.0000254f.ecki@zusammenkunft.net> <54309D36.3000802@oracle.com> <20141005041231.00007def.ecki@zusammenkunft.net> Message-ID: <5431981D.6070907@oracle.com> On 04/10/2014 19:12, Bernd Eckenfels wrote: > : > This creates the interesting situation, that the JVM verifies stricter > if you not use the (Microsoft recommended) "cmd /C". (In fact the > implementation even documents this as a workaround if you want to > avoid the validation.) > > Would it make sense to officially describe this in the exec(String[]), > that you can specify the path to a bat/cmd file as the first argument > and do not need to use the cmd /c? > Ideally all applications would quote correctly and avoid implicit execution of cmd.exe but there is a lot of existing code that doesn't. Some of the Oracle release notes and articles on this topic are here: http://www.oracle.com/technetwork/java/javase/7u25-relnotes-1955741.html#jruntime https://blogs.oracle.com/thejavatutorials/entry/changes_to_runtime_exec_problems The javadoc isn't really the place for this amount of highly Windows specific detail. There may be a case of referencing implementation specific documentation, we have several areas where such references could be useful to supplement the API docs. -Alan From ivan.gerasimov at oracle.com Mon Oct 6 10:41:53 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Mon, 06 Oct 2014 14:41:53 +0400 Subject: RFR 8023173: FileOutputStream(FileDescriptor) does not respect append flag on Windows Message-ID: <543271F1.8040505@oracle.com> Hello everybody! The append mode is emulated on Windows, therefore we have to keep a flag indicating that. With the current implementation, the FileDescriptor does not know if the file were opened with O_APPEND, and the flag is maintained at the upper level. This can cause inconsistency, when the FileDescriptor is reused to construct a new FileOutputStream, as there is no information available about the append/non-append mode. Even though the solution is quite straight-forward: moving the flag from FileOutputStream, FileDispatcherImpl and FileChannelImpl to the lower level of FileDescriptor, it touches 20 files across the source-code base. BUGURL: https://bugs.openjdk.java.net/browse/JDK-8023173 WEBREV: http://cr.openjdk.java.net/~igerasim/8023173/0/webrev/ With the fix, all the io/nio tests, including the new one, pass on all available platforms. Would you please help review this fix? Sincerely yours, Ivan From ivan.gerasimov at oracle.com Mon Oct 6 11:35:57 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Mon, 06 Oct 2014 15:35:57 +0400 Subject: RFR [8059563]: (proxy) sun.misc.ProxyGenerator.generateProxyClass should create intermediate directories Message-ID: <54327E9D.8060808@oracle.com> Hello! This is a 7u-only fix. Some users complain about the ProxyGenerator not creating the intermediate directories when asked to keep the generated files. It throws an IO exception instead The fix is essentially a part of JDK-8004260. That was a relatively big update, which required CCC, so it's not feasible to port it as a whole. Would you please help review it? BUGURL: https://bugs.openjdk.java.net/browse/JDK-8059563 WEBREV: http://cr.openjdk.java.net/~igerasim/8059563/0/webrev/ Sincerely yours, Ivan From daniel.fuchs at oracle.com Mon Oct 6 13:55:05 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Mon, 06 Oct 2014 15:55:05 +0200 Subject: java.util.logging.FileHandler integer overflow prevents file rotation In-Reply-To: References: Message-ID: <54329F39.8010101@oracle.com> Hi, On 19/08/14 16:00, Jason Mehrens wrote: > Stanimir, > > > Looks like the int overflow on the metered stream is an issue that hasn't been tracked. The other issues have been reported under https://bugs.openjdk.java.net/browse/JDK-6433253 > > and https://bugs.openjdk.java.net/browse/JDK-8028786 Apologies for not reacting sooner. Thanks for looking at the history Jason ;-) I have logged https://bugs.openjdk.java.net/browse/JDK-8059767, and will probably close the other two as duplicates. I usually prefer to keep different problems separate but in this case it's probably more efficient to fix these three in one go... best regards, -- daniel > > > Jason > > > > > ---------------------------------------- >> Date: Tue, 19 Aug 2014 11:06:27 +0300 >> Subject: java.util.logging.FileHandler integer overflow prevents file rotation >> From: stanimir at riflexo.com >> To: core-libs-dev at openjdk.java.net >> >> java.util.logging.FileHandler uses ints to track the written bytes >> that can cause negative value for >> java.util.logging.FileHandler.MeteredStream.written as there is no >> check in any of the write methods. >> The overflow prevents the check in FileHandler.publish(LogRecord) >> meter.written>= limit to ever trigger, esp. setting limit to >> Integer.MAX_VALUE that effectively always prevents file rotation. >> >> On a flip note, MeteredStream should be a static class. >> On another flip note, FileHandler should be using long as part of the >> API and internal implementation. ints are limited to 2GiB even when >> properly implemented that's a relatively low amount for certain types >> of logging files. So I propose adding overloaded c-tors >> FileHandler(String pattern, long limit, int count, boolean append) >> and FileHandler(String pattern, long limit, int count). LogManager >> should have a method "long getLongProperty(String name, long >> defaultValue)" to initialize limit. >> >> Thanks >> Stanimir From frederic.parain at oracle.com Mon Oct 6 14:32:08 2014 From: frederic.parain at oracle.com (Frederic Parain) Date: Mon, 06 Oct 2014 16:32:08 +0200 Subject: RFR(L): JDK-8057777 Cleanup of old and unused VM interfaces In-Reply-To: <542EC9B4.1050908@oracle.com> References: <542AC0E8.9040409@oracle.com> <542EBE8F.5090800@oracle.com> <542EC9B4.1050908@oracle.com> Message-ID: <5432A7E8.5070601@oracle.com> Thank you very much for catching the JVM_O_DELETE issue. I moved the O_DELETE support into the ZipFile.c file (code was the same for all non-Windows platforms) and cleaned up the original code in HotSpot. The new webrevs: http://cr.openjdk.java.net/~fparain/8057777/jdk_v03/ http://cr.openjdk.java.net/~fparain/8057777/hotspot_v03/ Regards, Fred On 10/03/2014 06:07 PM, Xueming Shen wrote: > On 10/3/14 8:19 AM, Alan Bateman wrote: >> On 30/09/2014 07:40, Hideric Parain wrote: >>> Hi all, >>> >>> Please review changes for bug JDK-8057777 "Cleanup of old >>> and unused VM interfaces" >>> >>> CR: >>> https://bugs.openjdk.java.net/browse/JDK-8057777 >>> >>> This is basically a big cleanup of VM interfaces that are >>> not used anymore by the JDK but have been kept in our code >>> base for historical reasons (HotSpot Express for instance). >>> These changesets remove these interfaces from both the >>> JDK and the HotSpot side, and also perform some cleanup >>> on code that directly referenced the removed interfaces. >>> >>> These changes do not modify the behavior of the Java >>> classes impacted by the cleanup. >>> >>> VM interfaces removal has been approved by CCC and >>> a Release Note has been prepared that explicitly list >>> all the removed interfaces. >>> >>> Testing: JPRT hotspot + core, vm.quick.testlist, jdk_core >>> >>> Webrevs: >>> http://cr.openjdk.java.net/~fparain/8057777/ >> cc'ing core-libs-dev as part of this is clean-up in the library code too. >> >> I think we should deprecate java.lang.Compiler and the >> Runtime.traceXXX methods. They've been non-functional for a long time >> and having them in the API is a bit mis-leading to anyone reading the >> javadoc. I realize you are focused on the removing the old JVM_* >> functions so we can follow-up on that via other issues of course. >> >> Can ClassLoader#resolveClass0 can be removed completely? The null >> check can be done in ClassLoader#resolveClass. >> >> In the mapfile for libjava then the comment at line 281 says >> "ZipFile.c needs this one". As getLastErrorString is now exported for >> use by libzip then the comment should probably be updated. >> >> Otherwise this clean-up looks good to me and the jdk_core group of >> tests is the right group to exercise this area. >> >> -Alan >> > > Hi, > > ZipFile.c expects the JVM_Open() to handle the JVM_O_DELETE, with > explicit unlink on linux/solaris for example. > I would assume the open from the c library does not handle it and we > need to do it explicitly by ZipFile.c now? > > -Sherman > > -- Frederic Parain - Oracle Grenoble Engineering Center - France Phone: +33 4 76 18 81 17 Email: Frederic.Parain at oracle.com From martinrb at google.com Mon Oct 6 17:22:15 2014 From: martinrb at google.com (Martin Buchholz) Date: Mon, 6 Oct 2014 10:22:15 -0700 Subject: RFR 8023173: FileOutputStream(FileDescriptor) does not respect append flag on Windows In-Reply-To: <543271F1.8040505@oracle.com> References: <543271F1.8040505@oracle.com> Message-ID: Thanks for tackling this difficult area! Alan is the most qualified to review, but I'll throw in some comments. The title of the bug in jira doesn't match the one in the webrev - they should be the same. I'm not sure, but it looks like getAppend is called even on non-Windows platforms, but there should be no need? On Mon, Oct 6, 2014 at 3:41 AM, Ivan Gerasimov wrote: > Hello everybody! > > The append mode is emulated on Windows, therefore we have to keep a flag > indicating that. > > With the current implementation, the FileDescriptor does not know if the > file were opened with O_APPEND, and the flag is maintained at the upper > level. > This can cause inconsistency, when the FileDescriptor is reused to > construct a new FileOutputStream, as there is no information available > about the append/non-append mode. > > Even though the solution is quite straight-forward: moving the flag from > FileOutputStream, FileDispatcherImpl and FileChannelImpl to the lower > level of FileDescriptor, it touches 20 files across the source-code base. > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8023173 > WEBREV: http://cr.openjdk.java.net/~igerasim/8023173/0/webrev/ > > With the fix, all the io/nio tests, including the new one, pass on all > available platforms. > > Would you please help review this fix? > > Sincerely yours, > Ivan > From mandy.chung at oracle.com Tue Oct 7 05:47:17 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Mon, 06 Oct 2014 22:47:17 -0700 Subject: RFR [8059563]: (proxy) sun.misc.ProxyGenerator.generateProxyClass should create intermediate directories In-Reply-To: <54327E9D.8060808@oracle.com> References: <54327E9D.8060808@oracle.com> Message-ID: <54337E65.2000700@oracle.com> On 10/6/2014 4:35 AM, Ivan Gerasimov wrote: > Hello! > > This is a 7u-only fix. > > Some users complain about the ProxyGenerator not creating the > intermediate directories when asked to keep the generated files. > It throws an IO exception instead > > The fix is essentially a part of JDK-8004260. > That was a relatively big update, which required CCC, so it's not > feasible to port it as a whole. > > Would you please help review it? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8059563 > WEBREV: http://cr.openjdk.java.net/~igerasim/8059563/0/webrev/ > The fix looks okay. Typo in the new test line 26: s/intermidiate/intermediate. It would be good to make sure the directory doesn't exist before generating the proxy class and also check if the expected file is created after it's generated. An alternative is to call Proxy.getProxyClass instead ProxyGenerator as your test is under java/lang/reflect/Proxy. Maybe the testname be renamed to "SaveProxyClassFileTest.java" Mandy From david.holmes at oracle.com Tue Oct 7 06:18:06 2014 From: david.holmes at oracle.com (David Holmes) Date: Tue, 07 Oct 2014 16:18:06 +1000 Subject: RFR(L): JDK-8057777 Cleanup of old and unused VM interfaces In-Reply-To: <5432A7E8.5070601@oracle.com> References: <542AC0E8.9040409@oracle.com> <542EBE8F.5090800@oracle.com> <542EC9B4.1050908@oracle.com> <5432A7E8.5070601@oracle.com> Message-ID: <5433859E.7070706@oracle.com> Hi Fred, Looks okay to me too. But I wouldn't be surprised if there is some test somewhere that checks for things when PrintJVMWarnings is set :) David On 7/10/2014 12:32 AM, Frederic Parain wrote: > Thank you very much for catching the JVM_O_DELETE issue. > I moved the O_DELETE support into the ZipFile.c file > (code was the same for all non-Windows platforms) and > cleaned up the original code in HotSpot. > > The new webrevs: > > http://cr.openjdk.java.net/~fparain/8057777/jdk_v03/ > http://cr.openjdk.java.net/~fparain/8057777/hotspot_v03/ > > Regards, > > Fred > > On 10/03/2014 06:07 PM, Xueming Shen wrote: >> On 10/3/14 8:19 AM, Alan Bateman wrote: >>> On 30/09/2014 07:40, Hideric Parain wrote: >>>> Hi all, >>>> >>>> Please review changes for bug JDK-8057777 "Cleanup of old >>>> and unused VM interfaces" >>>> >>>> CR: >>>> https://bugs.openjdk.java.net/browse/JDK-8057777 >>>> >>>> This is basically a big cleanup of VM interfaces that are >>>> not used anymore by the JDK but have been kept in our code >>>> base for historical reasons (HotSpot Express for instance). >>>> These changesets remove these interfaces from both the >>>> JDK and the HotSpot side, and also perform some cleanup >>>> on code that directly referenced the removed interfaces. >>>> >>>> These changes do not modify the behavior of the Java >>>> classes impacted by the cleanup. >>>> >>>> VM interfaces removal has been approved by CCC and >>>> a Release Note has been prepared that explicitly list >>>> all the removed interfaces. >>>> >>>> Testing: JPRT hotspot + core, vm.quick.testlist, jdk_core >>>> >>>> Webrevs: >>>> http://cr.openjdk.java.net/~fparain/8057777/ >>> cc'ing core-libs-dev as part of this is clean-up in the library code >>> too. >>> >>> I think we should deprecate java.lang.Compiler and the >>> Runtime.traceXXX methods. They've been non-functional for a long time >>> and having them in the API is a bit mis-leading to anyone reading the >>> javadoc. I realize you are focused on the removing the old JVM_* >>> functions so we can follow-up on that via other issues of course. >>> >>> Can ClassLoader#resolveClass0 can be removed completely? The null >>> check can be done in ClassLoader#resolveClass. >>> >>> In the mapfile for libjava then the comment at line 281 says >>> "ZipFile.c needs this one". As getLastErrorString is now exported for >>> use by libzip then the comment should probably be updated. >>> >>> Otherwise this clean-up looks good to me and the jdk_core group of >>> tests is the right group to exercise this area. >>> >>> -Alan >>> >> >> Hi, >> >> ZipFile.c expects the JVM_Open() to handle the JVM_O_DELETE, with >> explicit unlink on linux/solaris for example. >> I would assume the open from the c library does not handle it and we >> need to do it explicitly by ZipFile.c now? >> >> -Sherman >> >> > From ivan.gerasimov at oracle.com Tue Oct 7 08:08:20 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 07 Oct 2014 12:08:20 +0400 Subject: RFR 8023173: FileDescriptor should respect append flag In-Reply-To: References: <543271F1.8040505@oracle.com> Message-ID: <54339F74.6060200@oracle.com> Thanks Martin for the comments! On 06.10.2014 21:22, Martin Buchholz wrote: > Thanks for tackling this difficult area! > > Alan is the most qualified to review, but I'll throw in some comments. > > The title of the bug in jira doesn't match the one in the webrev - > they should be the same. > Do you mean the summary in the regression test? I'll update the Jira bug's title, the thread subject and the summary to be the same. > I'm not sure, but it looks like getAppend is called even on > non-Windows platforms, but there should be no need? > There is one place where we need it: in FileChannelImpl.position(), if in append mode, we should return the file size (see JDK-6526860). As the append flag was moved from FileChannelImpl down to FileDescriptor, we need a way to retrieve this information back, so getAppend() had to be introduced. This is applicable to both Windows and Unix. This code seems already to be covered by java/nio/channels/FileChannel/AtomicAppend.java, so I'm not introducing a new test for it. Sincerely yours, Ivan > On Mon, Oct 6, 2014 at 3:41 AM, Ivan Gerasimov > > wrote: > > Hello everybody! > > The append mode is emulated on Windows, therefore we have to keep > a flag indicating that. > > With the current implementation, the FileDescriptor does not know > if the file were opened with O_APPEND, and the flag is maintained > at the upper level. > This can cause inconsistency, when the FileDescriptor is reused to > construct a new FileOutputStream, as there is no information > available about the append/non-append mode. > > Even though the solution is quite straight-forward: moving the > flag from FileOutputStream, FileDispatcherImpl and > FileChannelImpl to the lower level of FileDescriptor, it touches > 20 files across the source-code base. > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8023173 > WEBREV: http://cr.openjdk.java.net/~igerasim/8023173/0/webrev/ > > > With the fix, all the io/nio tests, including the new one, pass on > all available platforms. > > Would you please help review this fix? > > Sincerely yours, > Ivan > > From ivan.gerasimov at oracle.com Tue Oct 7 08:47:36 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 07 Oct 2014 12:47:36 +0400 Subject: RFR [8059563]: (proxy) sun.misc.ProxyGenerator.generateProxyClass should create intermediate directories In-Reply-To: <54337E65.2000700@oracle.com> References: <54327E9D.8060808@oracle.com> <54337E65.2000700@oracle.com> Message-ID: <5433A8A8.7000704@oracle.com> Thank you Mandy! I've updated the webrev based on your suggestions. The test is moved to test/sun/misc/ProxyGenerator/ directory. Here's the updated webrev: http://cr.openjdk.java.net/~igerasim/8059563/1/webrev/ Sincerely yours, Ivan On 07.10.2014 9:47, Mandy Chung wrote: > > On 10/6/2014 4:35 AM, Ivan Gerasimov wrote: >> Hello! >> >> This is a 7u-only fix. >> >> Some users complain about the ProxyGenerator not creating the >> intermediate directories when asked to keep the generated files. >> It throws an IO exception instead >> >> The fix is essentially a part of JDK-8004260. >> That was a relatively big update, which required CCC, so it's not >> feasible to port it as a whole. >> >> Would you please help review it? >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8059563 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8059563/0/webrev/ >> > > The fix looks okay. > > Typo in the new test line 26: s/intermidiate/intermediate. It would > be good to make sure the directory doesn't exist before generating the > proxy class and also check if the expected file is created after it's > generated. An alternative is to call Proxy.getProxyClass instead > ProxyGenerator as your test is under java/lang/reflect/Proxy. Maybe > the testname be renamed to "SaveProxyClassFileTest.java" > > Mandy > > From daniel.fuchs at oracle.com Tue Oct 7 10:59:19 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Tue, 07 Oct 2014 12:59:19 +0200 Subject: RFR: 8028788: Logger.enterring uses String concatenation in a loop Message-ID: <5433C787.8030704@oracle.com> Hi, Please find below a trivial fix for 8028788: Logger.enterring uses String concatenation in a loop https://bugs.openjdk.java.net/browse/JDK-8028788 webrev: http://cr.openjdk.java.net/~dfuchs/webrev_8028788/webrev.00 best regards -- daniel From chris.hegarty at oracle.com Tue Oct 7 11:08:20 2014 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Tue, 7 Oct 2014 12:08:20 +0100 Subject: RFR: 8028788: Logger.enterring uses String concatenation in a loop In-Reply-To: <5433C787.8030704@oracle.com> References: <5433C787.8030704@oracle.com> Message-ID: <9FF2F502-2D16-42C5-A8CF-C105A9F8A93F@oracle.com> Looks ok to me Daniel. -Chris. On 7 Oct 2014, at 11:59, Daniel Fuchs wrote: > Hi, > > Please find below a trivial fix for > > 8028788: Logger.enterring uses String concatenation in a loop > https://bugs.openjdk.java.net/browse/JDK-8028788 > > webrev: > http://cr.openjdk.java.net/~dfuchs/webrev_8028788/webrev.00 > > best regards > > -- daniel From daniel.fuchs at oracle.com Tue Oct 7 11:24:32 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Tue, 07 Oct 2014 13:24:32 +0200 Subject: RFR: 8028788: Logger.enterring uses String concatenation in a loop In-Reply-To: <9A5B477E-3950-447F-B605-9E404D9F5D42@oracle.com> References: <5433C787.8030704@oracle.com> <9FF2F502-2D16-42C5-A8CF-C105A9F8A93F@oracle.com> <9A5B477E-3950-447F-B605-9E404D9F5D42@oracle.com> Message-ID: <5433CD70.40004@oracle.com> On 07/10/14 13:22, Lance Andersen wrote: > Hi Daniel, > > Couldn't you just do > > x.append(' ').append('{').append(i).append('}'); > > and avoid the String.valueOf() or do you find the performance the same? Hi Lance, I refreshed the webrev to remove the String.valueOf() best regards, -- daniel > > Best > Lance >> On 7 Oct 2014, at 11:59, Daniel Fuchs > > wrote: >> >>> Hi, >>> >>> Please find below a trivial fix for >>> >>> 8028788: Logger.enterring uses String concatenation in a loop >>> https://bugs.openjdk.java.net/browse/JDK-8028788 >>> >>> webrev: >>> http://cr.openjdk.java.net/~dfuchs/webrev_8028788/webrev.00 >>> >>> best regards >>> >>> -- daniel >> > > > > Lance Andersen| > Principal Member of Technical Staff | +1.781.442.2037 > Oracle Java Engineering > 1 Network Drive > Burlington, MA 01803 > Lance.Andersen at oracle.com > > > From Lance.Andersen at oracle.com Tue Oct 7 11:57:59 2014 From: Lance.Andersen at oracle.com (Lance Andersen) Date: Tue, 7 Oct 2014 07:57:59 -0400 Subject: RFR: 8028788: Logger.enterring uses String concatenation in a loop In-Reply-To: <5433CD70.40004@oracle.com> References: <5433C787.8030704@oracle.com> <9FF2F502-2D16-42C5-A8CF-C105A9F8A93F@oracle.com> <9A5B477E-3950-447F-B605-9E404D9F5D42@oracle.com> <5433CD70.40004@oracle.com> Message-ID: <846FEA05-B613-42EE-B04D-0F28ACAF5A75@oracle.com> Looks fine Daniel Best Lance -- Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com Sent from my iPhone > On Oct 7, 2014, at 7:24 AM, Daniel Fuchs wrote: > >> On 07/10/14 13:22, Lance Andersen wrote: >> Hi Daniel, >> >> Couldn't you just do >> >> x.append(' ').append('{').append(i).append('}'); >> >> and avoid the String.valueOf() or do you find the performance the same? > > Hi Lance, > > I refreshed the webrev to remove the String.valueOf() > > best regards, > > -- daniel > >> >> Best >> Lance >>> On 7 Oct 2014, at 11:59, Daniel Fuchs >> > wrote: >>> >>>> Hi, >>>> >>>> Please find below a trivial fix for >>>> >>>> 8028788: Logger.enterring uses String concatenation in a loop >>>> https://bugs.openjdk.java.net/browse/JDK-8028788 >>>> >>>> webrev: >>>> http://cr.openjdk.java.net/~dfuchs/webrev_8028788/webrev.00 >>>> >>>> best regards >>>> >>>> -- daniel >> >> >> >> Lance Andersen| >> Principal Member of Technical Staff | +1.781.442.2037 >> Oracle Java Engineering >> 1 Network Drive >> Burlington, MA 01803 >> Lance.Andersen at oracle.com > From Alan.Bateman at oracle.com Tue Oct 7 13:06:44 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 07 Oct 2014 06:06:44 -0700 Subject: RFR(L): JDK-8057777 Cleanup of old and unused VM interfaces In-Reply-To: <5432A7E8.5070601@oracle.com> References: <542AC0E8.9040409@oracle.com> <542EBE8F.5090800@oracle.com> <542EC9B4.1050908@oracle.com> <5432A7E8.5070601@oracle.com> Message-ID: <5433E564.8010402@oracle.com> On 06/10/2014 07:32, Frederic Parain wrote: > Thank you very much for catching the JVM_O_DELETE issue. > I moved the O_DELETE support into the ZipFile.c file > (code was the same for all non-Windows platforms) and > cleaned up the original code in HotSpot. > > The new webrevs: > > http://cr.openjdk.java.net/~fparain/8057777/jdk_v03/ > http://cr.openjdk.java.net/~fparain/8057777/hotspot_v03/ > Good spot by Sherman on the OPEN_DELETE issue, it makes me wonder what the test coverage is on this. The updated webrev addresses the points that I brought up and looks good (nice to see many of these functions going away). -Alan From daniel.fuchs at oracle.com Tue Oct 7 13:13:13 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Tue, 07 Oct 2014 15:13:13 +0200 Subject: RFR: 8059767: FileHandler should allow 'long' limits and handle overflow of MeteredStream.written. Message-ID: <5433E6E9.2080009@oracle.com> Hi, Please find below a patch for: 8059767: FileHandler should allow 'long' limits and handle overflow of MeteredStream.written. https://bugs.openjdk.java.net/browse/JDK-8059767 webrev: http://cr.openjdk.java.net/~dfuchs/webrev_8059767/webrev.00/ This follows an issue reported on this list: http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-August/028280.html The patch changes 'limit' from 'int' to 'long', fixes the handling of overflow, and adds a new constructor that allows to pass a long for 'limit'. It also makes it possible to specify a long value for 'limit' in the configuration. The test checks the handling of overflow by tweaking the internal of MeteredStream through reflection. Not ideal, but I couldn't find any other way. best regards, -- daniel From joe.darcy at oracle.com Tue Oct 7 16:25:37 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Tue, 07 Oct 2014 09:25:37 -0700 Subject: Urgent [9], 2nd round, RFR (S) : JDK-8039915 NumberFormat.format() does not consider required no. of fraction digits properly In-Reply-To: <542D7D6B.6000108@oracle.com> References: <542D7D6B.6000108@oracle.com> Message-ID: <54341401.4000109@oracle.com> Hi Olivier, Some rewording suggestions: 445 * @param alreadyRounded Boolean indicating if rounding up already happened. 446 * @param allDecimalDigits Boolean indicating if the digits provide an exact 447 * representation of the value. Including the type of the parameter is redundant with its declaration so I'd recommend something like 445 * @param alreadyRounded whether or not rounding up has already happened. Given the semantics of allDecimalDigits, I recommend renaming the parameter to something like "valueExactAsDecimal". For please restore the conventional formatting 532 } else if (digits[maximumDigits] == '5') { The code 543 if (roundingMode == RoundingMode.HALF_UP) { 544 // Strictly follow HALF_UP rule ==> round-up 545 return true; 546 } 547 else { 548 // Strictly follow HALF_DOWN rule ==> don't round-up 549 return false; 550 } can be replaced by 545 return roundingMode == RoundingMode.HALF_UP; with a suitable comment. Please make these adjustments and I'll do a careful review of the rounding logic. Thanks, -Joe On 10/2/2014 9:29 AM, olivier.lagneau at oracle.com wrote: > Please review this 2nd version of the fix taking into account your > feedback. > > Bug : https://bugs.openjdk.java.net/browse/JDK-8039915 > webrev : http://cr.openjdk.java.net/~olagneau/8039915/webrev.01 > > I have changed the code following your remarks > > Testing: lot of testing on jtreg, jck8, code coverage, jprt. > > Below are more details on the changes in this webrev. > > For the new work in question, it might be clearer to me if the HALF_UP > and HALF_DOWN cases >> were combined into a single block since they > share much of the logic. >> The unique logic for each mode would be easier to see if the >> differences were placed together. > I have merged HALF_UP and HALF_DOWN cases into a single switch case. > > I also tested a fully merged version where HALF_UP, HALF_DOWN, and > also HALF_EVEN are merge > into a single switch case. So merging the three is even possible. > If you want to have the three HALF_* cases we can quickly move to that. > >> My only suggestions are trivial: 1) enhance the method javadoc of >> shouldRoundUp(), e.g., there are no @param tags for the boolean >> parameters, > Fixed that. @param tags are available for shouldRoundUp method > >> 2) use braces around all the statements contained in if/else blocks >> (see below). Comment #2 is nit-picky. > Took care to follow this rule in this new version. > >> If the test is already printing out the information you showed above >> (?Error formatting ??) then I think it is enough but the verbiage >> should perhaps match the reminder, e.g., ?Failure: Error formatting >> double ?? > Changed test code to provide this consistent wording. > > Thanks, > Olivier. > > > > From wprice at pros.com Tue Oct 7 16:33:26 2014 From: wprice at pros.com (William Price) Date: Tue, 7 Oct 2014 16:33:26 +0000 Subject: Urgent [9], 2nd round, RFR (S) : JDK-8039915 NumberFormat.format() does not consider required no. of fraction digits properly In-Reply-To: <542D7D6B.6000108@oracle.com> References: <542D7D6B.6000108@oracle.com> Message-ID: <248346644B359C488489A7D3D971B3CC81D63F9B@PROS-EXMB02.prosrm.com> > Please review this 2nd version of the fix taking into account your feedback. I'm not recognized here as a reviewer, but the code looked OK to me and it passed my patch test suite. > I have merged HALF_UP and HALF_DOWN cases into a single switch case. Good to know. My current patch injects a method call to shim code immediately after the HALF_UP case label. I need to account for this or else the applied patch could potentially cause HALF_DOWN to behave the same as HALF_UP! Thankfully, this is easily detectable in the bytecode (not that the impact to my patch is of much concern to the core devs, but it dove-tails nicely). I'm looking forward to seeing this merged and the bug fixed/closed. For my company, the sooner this makes it into an 8u update, the better. Thanks, Olivier. -- William Price From jason_mehrens at hotmail.com Tue Oct 7 19:50:32 2014 From: jason_mehrens at hotmail.com (Jason Mehrens) Date: Tue, 7 Oct 2014 14:50:32 -0500 Subject: RFR: 8059767: FileHandler should allow 'long' limits and handle overflow of MeteredStream.written. In-Reply-To: <5433E6E9.2080009@oracle.com> References: <5433E6E9.2080009@oracle.com> Message-ID: Hi Daniel, The only thing I noticed is a missing @since tag on the FileHandler. Jason ---------------------------------------- > Date: Tue, 7 Oct 2014 15:13:13 +0200 > From: daniel.fuchs at oracle.com > To: core-libs-dev at openjdk.java.net > Subject: RFR: 8059767: FileHandler should allow 'long' limits and handle overflow of MeteredStream.written. > > Hi, > > Please find below a patch for: > > 8059767: FileHandler should allow 'long' limits and handle overflow > of MeteredStream.written. > https://bugs.openjdk.java.net/browse/JDK-8059767 > > webrev: > http://cr.openjdk.java.net/~dfuchs/webrev_8059767/webrev.00/ > > This follows an issue reported on this list: > http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-August/028280.html > > The patch changes 'limit' from 'int' to 'long', fixes the > handling of overflow, and adds a new constructor that allows > to pass a long for 'limit'. > It also makes it possible to specify a long value for 'limit' > in the configuration. > > The test checks the handling of overflow by tweaking the > internal of MeteredStream through reflection. Not ideal, but > I couldn't find any other way. > > best regards, > > -- daniel From mandy.chung at oracle.com Wed Oct 8 02:05:51 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 07 Oct 2014 19:05:51 -0700 Subject: Review for 8056909: test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java fails with OOME Message-ID: <54349BFF.70907@oracle.com> A simple patch to take out -mx flag from the test. The test should use the default setting instead of setting the max heap size. Thanks Mandy ---------------- diff --git a/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java b/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java --- a/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java +++ b/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java @@ -47,7 +47,7 @@ * @summary Verify if CallerSensitive methods are annotated with * sun.reflect.CallerSensitive annotation * @build CallerSensitiveFinder - * @run main/othervm/timeout=900 -mx600m CallerSensitiveFinder + * @run main/othervm/timeout=900 CallerSensitiveFinder */ public class CallerSensitiveFinder { private static int numThreads = 3; From joe.darcy at oracle.com Wed Oct 8 02:14:57 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Tue, 07 Oct 2014 19:14:57 -0700 Subject: Review for 8056909: test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java fails with OOME In-Reply-To: <54349BFF.70907@oracle.com> References: <54349BFF.70907@oracle.com> Message-ID: <54349E21.4090302@oracle.com> Looks good Mandy; cheers, -Joe On 10/07/2014 07:05 PM, Mandy Chung wrote: > A simple patch to take out -mx flag from the test. The test should > use the default setting instead of setting the max heap size. > > Thanks > Mandy > ---------------- > > diff --git > a/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java > b/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java > --- a/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java > +++ b/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java > @@ -47,7 +47,7 @@ > * @summary Verify if CallerSensitive methods are annotated with > * sun.reflect.CallerSensitive annotation > * @build CallerSensitiveFinder > - * @run main/othervm/timeout=900 -mx600m CallerSensitiveFinder > + * @run main/othervm/timeout=900 CallerSensitiveFinder > */ > public class CallerSensitiveFinder { > private static int numThreads = 3; > From ivan.gerasimov at oracle.com Wed Oct 8 06:26:36 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 08 Oct 2014 10:26:36 +0400 Subject: RFR: 8059767: FileHandler should allow 'long' limits and handle overflow of MeteredStream.written. In-Reply-To: <5433E6E9.2080009@oracle.com> References: <5433E6E9.2080009@oracle.com> Message-ID: <5434D91C.4040902@oracle.com> Hi Daniel! Would it make sense to make the old constructor FileHandler(String, *int*, int, boolean) call the new one, casting the limit to long? Sincerely yours, Ivan On 07.10.2014 17:13, Daniel Fuchs wrote: > Hi, > > Please find below a patch for: > > 8059767: FileHandler should allow 'long' limits and handle overflow > of MeteredStream.written. > https://bugs.openjdk.java.net/browse/JDK-8059767 > > webrev: > http://cr.openjdk.java.net/~dfuchs/webrev_8059767/webrev.00/ > > This follows an issue reported on this list: > http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-August/028280.html > > > The patch changes 'limit' from 'int' to 'long', fixes the > handling of overflow, and adds a new constructor that allows > to pass a long for 'limit'. > It also makes it possible to specify a long value for 'limit' > in the configuration. > > The test checks the handling of overflow by tweaking the > internal of MeteredStream through reflection. Not ideal, but > I couldn't find any other way. > > best regards, > > -- daniel > > From daniel.fuchs at oracle.com Wed Oct 8 08:49:41 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Wed, 08 Oct 2014 10:49:41 +0200 Subject: RFR: 8059767: FileHandler should allow 'long' limits and handle overflow of MeteredStream.written. In-Reply-To: References: <5433E6E9.2080009@oracle.com> Message-ID: <5434FAA5.10700@oracle.com> On 07/10/14 21:50, Jason Mehrens wrote: > Hi Daniel, > > > The only thing I noticed is a missing @since tag on the FileHandler. Oops, thanks for catching that Jason. -- daniel > > > Jason > > ---------------------------------------- >> Date: Tue, 7 Oct 2014 15:13:13 +0200 >> From: daniel.fuchs at oracle.com >> To: core-libs-dev at openjdk.java.net >> Subject: RFR: 8059767: FileHandler should allow 'long' limits and handle overflow of MeteredStream.written. >> >> Hi, >> >> Please find below a patch for: >> >> 8059767: FileHandler should allow 'long' limits and handle overflow >> of MeteredStream.written. >> https://bugs.openjdk.java.net/browse/JDK-8059767 >> >> webrev: >> http://cr.openjdk.java.net/~dfuchs/webrev_8059767/webrev.00/ >> >> This follows an issue reported on this list: >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-August/028280.html >> >> The patch changes 'limit' from 'int' to 'long', fixes the >> handling of overflow, and adds a new constructor that allows >> to pass a long for 'limit'. >> It also makes it possible to specify a long value for 'limit' >> in the configuration. >> >> The test checks the handling of overflow by tweaking the >> internal of MeteredStream through reflection. Not ideal, but >> I couldn't find any other way. >> >> best regards, >> >> -- daniel From aleksej.efimov at oracle.com Wed Oct 8 09:09:01 2014 From: aleksej.efimov at oracle.com (Aleksej Efimov) Date: Wed, 08 Oct 2014 13:09:01 +0400 Subject: RFR: 8046817: JDK 8 schemagen tool does not generate xsd files for enum types Message-ID: <5434FF2D.104@oracle.com> Hello, Please, review the fix [1] for the 8046817 [2]. Problem: schemagen tool doesn't generate schema file for the enum types [3]. SchemaGenerator class gets a list of annotated elements and filters out only the class variables, but annotation parser (AnnotationParser.java) filters out the Class and Enum. The proposed fix solves the problem: SchemaGenerator filters like AnnotationParser. Testing: JPRT build and test passes on platforms (with new regression test). JTREG tests: javax/xml - no failures. Thanks, Aleksej [1] Webrev: http://cr.openjdk.java.net/~aefimov/8046817/9/webrev.00/ [2] Bug: https://bugs.openjdk.java.net/browse/JDK-8046817 [3] Enum type: http://cr.openjdk.java.net/~aefimov/8046817/9/webrev.00/jdk/test/javax/xml/ws/8046817/TestEnumType.java.html From daniel.fuchs at oracle.com Wed Oct 8 09:46:26 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Wed, 08 Oct 2014 11:46:26 +0200 Subject: RFR: 8059767: FileHandler should allow 'long' limits and handle overflow of MeteredStream.written. In-Reply-To: <5434D91C.4040902@oracle.com> References: <5433E6E9.2080009@oracle.com> <5434D91C.4040902@oracle.com> Message-ID: <543507F2.2050804@oracle.com> On 08/10/14 08:26, Ivan Gerasimov wrote: > Hi Daniel! > > Would it make sense to make the old constructor FileHandler(String, > *int*, int, boolean) call the new one, casting the limit to long? Hi Ivan, I was about to reply 'no' out of consistency with the other constructors - which don't call each others - when I realized that it was not be possible to make the other constructors call each others anyway - as passing a parameter to a constructor means overriding the default value read from the configuration file. This however doesn't hold in our case as both constructors have exactly the same code - so there's no reason for not making FileHandler(String, *int*, int, boolean) call FileHandler(String, *long*, int, boolean). Which now makes me question whether I should add a second constructor FileHandler(String, *long*, int) to shadow FileHandler(String, *int*, int) - as Stanimir aleready suggested. My feeling is that the case where you would want to rely on the default value of 'append' configured in the logging.properties file instead of specifying one to the constructor should be sufficiently rare to not warrant the addition of a second constructor. And if you really wanted to rely on that default value you could go and fetch it before calling the constructor. Anyway - good remark - and here is a new webrev including yours and Jason's comments. http://cr.openjdk.java.net/~dfuchs/webrev_8059767/webrev.01 best regards, -- daniel > > Sincerely yours, > Ivan > > On 07.10.2014 17:13, Daniel Fuchs wrote: >> Hi, >> >> Please find below a patch for: >> >> 8059767: FileHandler should allow 'long' limits and handle overflow >> of MeteredStream.written. >> https://bugs.openjdk.java.net/browse/JDK-8059767 >> >> webrev: >> http://cr.openjdk.java.net/~dfuchs/webrev_8059767/webrev.00/ >> >> This follows an issue reported on this list: >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-August/028280.html >> >> >> The patch changes 'limit' from 'int' to 'long', fixes the >> handling of overflow, and adds a new constructor that allows >> to pass a long for 'limit'. >> It also makes it possible to specify a long value for 'limit' >> in the configuration. >> >> The test checks the handling of overflow by tweaking the >> internal of MeteredStream through reflection. Not ideal, but >> I couldn't find any other way. >> >> best regards, >> >> -- daniel >> >> > From konstantin.shefov at oracle.com Wed Oct 8 13:15:47 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Wed, 08 Oct 2014 17:15:47 +0400 Subject: [9] Review request : JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError Message-ID: <54353903.4000406@oracle.com> Hello, Please review the test bug fix https://bugs.openjdk.java.net/browse/JDK-8058733 Webrev is http://cr.openjdk.java.net/~kshefov/8058733/webrev.00/ Thanks -Konstantin From vladimir.x.ivanov at oracle.com Wed Oct 8 13:24:42 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Wed, 08 Oct 2014 17:24:42 +0400 Subject: [9] Review request : JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <54353903.4000406@oracle.com> References: <54353903.4000406@oracle.com> Message-ID: <54353B1A.2030903@oracle.com> Konstantin, What kind of testing have you done to verify the fix? Best regards, Vladimir Ivanov On 10/8/14, 5:15 PM, Konstantin Shefov wrote: > Hello, > > Please review the test bug fix > https://bugs.openjdk.java.net/browse/JDK-8058733 > Webrev is http://cr.openjdk.java.net/~kshefov/8058733/webrev.00/ > > Thanks > > -Konstantin From daniel.fuchs at oracle.com Wed Oct 8 13:25:02 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Wed, 08 Oct 2014 15:25:02 +0200 Subject: [9] Review request : JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <54353903.4000406@oracle.com> References: <54353903.4000406@oracle.com> Message-ID: <54353B2E.8000409@oracle.com> Hi Konstantin, I'm not qualified as a (R)eviewer for changes in this area, but I believe you can do: HotSpotDiagnosticMXBean mbean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); to get a handle on the MBean. You don't need to go through the MBeanServer and newPlatformMXBeanProxy stuff... best regards, -- daniel On 08/10/14 15:15, Konstantin Shefov wrote: > Hello, > > Please review the test bug fix > https://bugs.openjdk.java.net/browse/JDK-8058733 > Webrev is http://cr.openjdk.java.net/~kshefov/8058733/webrev.00/ > > Thanks > > -Konstantin From konstantin.shefov at oracle.com Wed Oct 8 13:32:41 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Wed, 08 Oct 2014 17:32:41 +0400 Subject: [9] Review request : JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <54353B1A.2030903@oracle.com> References: <54353903.4000406@oracle.com> <54353B1A.2030903@oracle.com> Message-ID: <54353CF9.2080509@oracle.com> I have run the test with the latest JDK 9 nightly build from Jenkins http://scaaa114.us.oracle.com:8080/job/jdk9-dev-test/ws/build/linux-x86_64-normal-server-release I have tried with different -XX:ReservedCodeCacheSize values. I have noticed that code cache consumption almost linearly depends on the number of iterations, so I take the number of iterations according to the code cache size. I take the number of iterations twice smaller than the limit (defined by the dependency) to ensure test's stability. I also can run the test on other OSs (Win, Mac). -Konstantin On 08.10.2014 17:24, Vladimir Ivanov wrote: > Konstantin, > > What kind of testing have you done to verify the fix? > > Best regards, > Vladimir Ivanov > > On 10/8/14, 5:15 PM, Konstantin Shefov wrote: >> Hello, >> >> Please review the test bug fix >> https://bugs.openjdk.java.net/browse/JDK-8058733 >> Webrev is http://cr.openjdk.java.net/~kshefov/8058733/webrev.00/ >> >> Thanks >> >> -Konstantin From konstantin.shefov at oracle.com Wed Oct 8 14:38:05 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Wed, 08 Oct 2014 18:38:05 +0400 Subject: [9] Review request : JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <54353B2E.8000409@oracle.com> References: <54353903.4000406@oracle.com> <54353B2E.8000409@oracle.com> Message-ID: <54354C4D.8020308@oracle.com> Daniel, Thanks for your comment Here is the updated webrev: http://cr.openjdk.java.net/~kshefov/8058733/webrev.01 -Konstantin On 08.10.2014 17:25, Daniel Fuchs wrote: > Hi Konstantin, > > I'm not qualified as a (R)eviewer for changes in this area, > but I believe you can do: > > HotSpotDiagnosticMXBean mbean = > ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); > > to get a handle on the MBean. You don't need to go through > the MBeanServer and newPlatformMXBeanProxy stuff... > > best regards, > > -- daniel > > On 08/10/14 15:15, Konstantin Shefov wrote: >> Hello, >> >> Please review the test bug fix >> https://bugs.openjdk.java.net/browse/JDK-8058733 >> Webrev is http://cr.openjdk.java.net/~kshefov/8058733/webrev.00/ >> >> Thanks >> >> -Konstantin > From olivier.lagneau at oracle.com Wed Oct 8 14:47:45 2014 From: olivier.lagneau at oracle.com (olivier.lagneau at oracle.com) Date: Wed, 08 Oct 2014 16:47:45 +0200 Subject: Urgent [9], 2nd round, RFR (S) : JDK-8039915 NumberFormat.format() does not consider required no. of fraction digits properly In-Reply-To: <248346644B359C488489A7D3D971B3CC81D63F9B@PROS-EXMB02.prosrm.com> References: <542D7D6B.6000108@oracle.com> <248346644B359C488489A7D3D971B3CC81D63F9B@PROS-EXMB02.prosrm.com> Message-ID: <54354E91.3000903@oracle.com> Hi William, On 07/10/2014 18:33, William Price wrote: >> Please review this 2nd version of the fix taking into account your feedback. > I'm not recognized here as a reviewer, but the code looked OK to me and > it passed my patch test suite. Thanks for letting me know. That provides additional confidence in the code ! > >> I have merged HALF_UP and HALF_DOWN cases into a single switch case. > Good to know. My current patch injects a method call to shim code > immediately after the HALF_UP case label. I need to account for this or > else the applied patch could potentially cause HALF_DOWN to behave the > same as HALF_UP! Thankfully, this is easily detectable in the bytecode > (not that the impact to my patch is of much concern to the core devs, > but it dove-tails nicely). > > I'm looking forward to seeing this merged and the bug fixed/closed. For my > company, the sooner this makes it into an 8u update, the better. Sure. This kind of code is very sensitive and we need to be very careful on the changes and during reviews. That takes some time. We expect to provide it soon in 8u base ! Thanks, Olivier. From pooja.chopra at oracle.com Tue Oct 7 10:55:54 2014 From: pooja.chopra at oracle.com (pooja chopra) Date: Tue, 07 Oct 2014 16:25:54 +0530 Subject: [9] Review Request: 8059753 Fix for java/security/Security/ClassLoaderDeadlock/Deadlock2.sh fails with exit code 1 Message-ID: <5433C6BA.3000609@oracle.com> Hello, Please review a fix for the issue: 8059753 [TEST_BUG] Test java/security/Security/ClassLoaderDeadlock/Deadlock2.sh fails with exit code 1 Test bug fix. https://bugs.openjdk.java.net/browse/JDK-8059753 The webrev is: http://cr.openjdk.java.net/~kshefov/8059753/webrev.00/ Thanks Pooja From olivier.lagneau at oracle.com Wed Oct 8 15:42:50 2014 From: olivier.lagneau at oracle.com (olivier.lagneau at oracle.com) Date: Wed, 08 Oct 2014 17:42:50 +0200 Subject: Urgent [9], 2nd round, RFR (S) : JDK-8039915 NumberFormat.format() does not consider required no. of fraction digits properly In-Reply-To: <54341401.4000109@oracle.com> References: <542D7D6B.6000108@oracle.com> <54341401.4000109@oracle.com> Message-ID: <54355B7A.8060602@oracle.com> Hi Joe, Thanks for the relevant feedback. I am going to provide all these changes in a new webrev within a few hours. Thanks, Olivier. On 07/10/2014 18:25, Joe Darcy wrote: > Hi Olivier, > > Some rewording suggestions: > > 445 * @param alreadyRounded Boolean indicating if rounding up > already happened. > 446 * @param allDecimalDigits Boolean indicating if the digits > provide an exact > 447 * representation of the value. > > Including the type of the parameter is redundant with its declaration > so I'd recommend something like > > 445 * @param alreadyRounded whether or not rounding up has > already happened. > > Given the semantics of allDecimalDigits, I recommend renaming the > parameter to something like "valueExactAsDecimal". > > For > > please restore the conventional formatting > > 532 } else if (digits[maximumDigits] == '5') { > > The code > > 543 if (roundingMode == > RoundingMode.HALF_UP) { > 544 // Strictly follow HALF_UP rule > ==> round-up > 545 return true; > 546 } > 547 else { > 548 // Strictly follow HALF_DOWN rule > ==> don't round-up > 549 return false; > 550 } > > can be replaced by > > 545 return roundingMode == > RoundingMode.HALF_UP; > > with a suitable comment. > > Please make these adjustments and I'll do a careful review of the > rounding logic. > > Thanks, > > -Joe > > On 10/2/2014 9:29 AM, olivier.lagneau at oracle.com wrote: >> Please review this 2nd version of the fix taking into account your >> feedback. >> >> Bug : https://bugs.openjdk.java.net/browse/JDK-8039915 >> webrev : http://cr.openjdk.java.net/~olagneau/8039915/webrev.01 >> >> I have changed the code following your remarks >> >> Testing: lot of testing on jtreg, jck8, code coverage, jprt. >> >> Below are more details on the changes in this webrev. >> >> For the new work in question, it might be clearer to me if the >> HALF_UP and HALF_DOWN cases >>> were combined into a single block since they > share much of the logic. >>> The unique logic for each mode would be easier to see if the >>> differences were placed together. >> I have merged HALF_UP and HALF_DOWN cases into a single switch case. >> >> I also tested a fully merged version where HALF_UP, HALF_DOWN, and >> also HALF_EVEN are merge >> into a single switch case. So merging the three is even possible. >> If you want to have the three HALF_* cases we can quickly move to that. >> >>> My only suggestions are trivial: 1) enhance the method javadoc of >>> shouldRoundUp(), e.g., there are no @param tags for the boolean >>> parameters, >> Fixed that. @param tags are available for shouldRoundUp method >> >>> 2) use braces around all the statements contained in if/else blocks >>> (see below). Comment #2 is nit-picky. >> Took care to follow this rule in this new version. >> >>> If the test is already printing out the information you showed above >>> (?Error formatting ??) then I think it is enough but the verbiage >>> should perhaps match the reminder, e.g., ?Failure: Error formatting >>> double ?? >> Changed test code to provide this consistent wording. >> >> Thanks, >> Olivier. >> >> >> >> > From martinrb at google.com Wed Oct 8 16:47:42 2014 From: martinrb at google.com (Martin Buchholz) Date: Wed, 8 Oct 2014 09:47:42 -0700 Subject: RFR 8023173: FileDescriptor should respect append flag In-Reply-To: <54339F74.6060200@oracle.com> References: <543271F1.8040505@oracle.com> <54339F74.6060200@oracle.com> Message-ID: Seems OK to me, but I leave it to Alan. On Tue, Oct 7, 2014 at 1:08 AM, Ivan Gerasimov wrote: > Thanks Martin for the comments! > > On 06.10.2014 21:22, Martin Buchholz wrote: > > Thanks for tackling this difficult area! > > Alan is the most qualified to review, but I'll throw in some comments. > > The title of the bug in jira doesn't match the one in the webrev - they > should be the same. > > Do you mean the summary in the regression test? > I'll update the Jira bug's title, the thread subject and the summary to be > the same. > > I'm not sure, but it looks like getAppend is called even on non-Windows > platforms, but there should be no need? > > > There is one place where we need it: in FileChannelImpl.position(), if in > append mode, we should return the file size (see JDK-6526860). > As the append flag was moved from FileChannelImpl down to FileDescriptor, > we need a way to retrieve this information back, so getAppend() had to be > introduced. > This is applicable to both Windows and Unix. > > This code seems already to be covered by > java/nio/channels/FileChannel/AtomicAppend.java, so I'm not introducing a > new test for it. > > Sincerely yours, > Ivan > > On Mon, Oct 6, 2014 at 3:41 AM, Ivan Gerasimov > wrote: > >> Hello everybody! >> >> The append mode is emulated on Windows, therefore we have to keep a flag >> indicating that. >> >> With the current implementation, the FileDescriptor does not know if the >> file were opened with O_APPEND, and the flag is maintained at the upper >> level. >> This can cause inconsistency, when the FileDescriptor is reused to >> construct a new FileOutputStream, as there is no information available >> about the append/non-append mode. >> >> Even though the solution is quite straight-forward: moving the flag from >> FileOutputStream, FileDispatcherImpl and FileChannelImpl to the lower >> level of FileDescriptor, it touches 20 files across the source-code base. >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8023173 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8023173/0/webrev/ >> >> With the fix, all the io/nio tests, including the new one, pass on all >> available platforms. >> >> Would you please help review this fix? >> >> Sincerely yours, >> Ivan >> > > > From ivan.gerasimov at oracle.com Wed Oct 8 16:53:25 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 08 Oct 2014 20:53:25 +0400 Subject: RFR 8023173: FileDescriptor should respect append flag In-Reply-To: References: <543271F1.8040505@oracle.com> <54339F74.6060200@oracle.com> Message-ID: <54356C05.1090408@oracle.com> On 08.10.2014 20:47, Martin Buchholz wrote: > Seems OK to me, but I leave it to Alan. > Thank you Martin! From joe.darcy at oracle.com Wed Oct 8 17:25:25 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Wed, 08 Oct 2014 10:25:25 -0700 Subject: [9] Review request : JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <54354C4D.8020308@oracle.com> References: <54353903.4000406@oracle.com> <54353B2E.8000409@oracle.com> <54354C4D.8020308@oracle.com> Message-ID: <54357385.7060102@oracle.com> Hello, I approve this change going into jdk9/dev contingent on the failing tests passing as modified. Thanks, -Joe On 10/8/2014 7:38 AM, Konstantin Shefov wrote: > Daniel, > Thanks for your comment > > Here is the updated webrev: > http://cr.openjdk.java.net/~kshefov/8058733/webrev.01 > > -Konstantin > > On 08.10.2014 17:25, Daniel Fuchs wrote: >> Hi Konstantin, >> >> I'm not qualified as a (R)eviewer for changes in this area, >> but I believe you can do: >> >> HotSpotDiagnosticMXBean mbean = >> ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); >> >> to get a handle on the MBean. You don't need to go through >> the MBeanServer and newPlatformMXBeanProxy stuff... >> >> best regards, >> >> -- daniel >> >> On 08/10/14 15:15, Konstantin Shefov wrote: >>> Hello, >>> >>> Please review the test bug fix >>> https://bugs.openjdk.java.net/browse/JDK-8058733 >>> Webrev is http://cr.openjdk.java.net/~kshefov/8058733/webrev.00/ >>> >>> Thanks >>> >>> -Konstantin >> > From mandy.chung at oracle.com Wed Oct 8 19:22:45 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 08 Oct 2014 12:22:45 -0700 Subject: RFR [8059563]: (proxy) sun.misc.ProxyGenerator.generateProxyClass should create intermediate directories In-Reply-To: <5433A8A8.7000704@oracle.com> References: <54327E9D.8060808@oracle.com> <54337E65.2000700@oracle.com> <5433A8A8.7000704@oracle.com> Message-ID: <54358F05.1000002@oracle.com> On 10/7/2014 1:47 AM, Ivan Gerasimov wrote: > Thank you Mandy! > > I've updated the webrev based on your suggestions. > The test is moved to test/sun/misc/ProxyGenerator/ directory. > > Here's the updated webrev: > http://cr.openjdk.java.net/~igerasim/8059563/1/webrev/ > Thanks for updating the test. Nit: I suggest to remove the directory "a" at the beginning rather than throwing a RuntimeException so that you can run the test multiple times manually. Mandy > Sincerely yours, > Ivan > > On 07.10.2014 9:47, Mandy Chung wrote: >> >> On 10/6/2014 4:35 AM, Ivan Gerasimov wrote: >>> Hello! >>> >>> This is a 7u-only fix. >>> >>> Some users complain about the ProxyGenerator not creating the >>> intermediate directories when asked to keep the generated files. >>> It throws an IO exception instead >>> >>> The fix is essentially a part of JDK-8004260. >>> That was a relatively big update, which required CCC, so it's not >>> feasible to port it as a whole. >>> >>> Would you please help review it? >>> >>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8059563 >>> WEBREV: http://cr.openjdk.java.net/~igerasim/8059563/0/webrev/ >>> >> >> The fix looks okay. >> >> Typo in the new test line 26: s/intermidiate/intermediate. It would >> be good to make sure the directory doesn't exist before generating >> the proxy class and also check if the expected file is created after >> it's generated. An alternative is to call Proxy.getProxyClass >> instead ProxyGenerator as your test is under >> java/lang/reflect/Proxy. Maybe the testname be renamed to >> "SaveProxyClassFileTest.java" >> >> Mandy >> >> > From ivan.gerasimov at oracle.com Wed Oct 8 21:51:09 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Thu, 09 Oct 2014 01:51:09 +0400 Subject: RFR [8059563]: (proxy) sun.misc.ProxyGenerator.generateProxyClass should create intermediate directories In-Reply-To: <54358F05.1000002@oracle.com> References: <54327E9D.8060808@oracle.com> <54337E65.2000700@oracle.com> <5433A8A8.7000704@oracle.com> <54358F05.1000002@oracle.com> Message-ID: <5435B1CD.3010905@oracle.com> Thanks Mandy! > Nit: I suggest to remove the directory "a" at the beginning rather > than throwing a RuntimeException so that you can run the test multiple > times manually. > Yes, makes sense. Here's the updated webrev: http://cr.openjdk.java.net/~igerasim/8059563/2/webrev/ Sincerely yours, Ivan From amy.lu at oracle.com Thu Oct 9 05:15:41 2014 From: amy.lu at oracle.com (Amy Lu) Date: Thu, 09 Oct 2014 13:15:41 +0800 Subject: RFR 8058855: Update java.util.zip tests to work with modular image Message-ID: <543619FD.4040706@oracle.com> Two java/util/zip tests use JDK rt.jar in test, this fix is to remove this dependency from test because with a modular rt.jar and the other JAR files in the JDK go away. bug: https://bugs.openjdk.java.net/browse/JDK-8058855 webrev: http://cr.openjdk.java.net/~tyan/amylu/8058855/webrev.00/ Thanks, Amy From david.holmes at oracle.com Thu Oct 9 05:23:15 2014 From: david.holmes at oracle.com (David Holmes) Date: Thu, 09 Oct 2014 15:23:15 +1000 Subject: RFR 8058855: Update java.util.zip tests to work with modular image In-Reply-To: <543619FD.4040706@oracle.com> References: <543619FD.4040706@oracle.com> Message-ID: <54361BC3.9000408@oracle.com> Hi Amy, On 9/10/2014 3:15 PM, Amy Lu wrote: > Two java/util/zip tests use JDK rt.jar in test, this fix is to remove > this dependency from test because with a modular rt.jar and the other > JAR files in the JDK go away. > > bug: https://bugs.openjdk.java.net/browse/JDK-8058855 > webrev: http://cr.openjdk.java.net/~tyan/amylu/8058855/webrev.00/ test/java/util/zip/InterruptibleZip.java Where is input.jar coming from? test/java/util/zip/ZipFile/FinalizeZipFile.java The File variable "lib" is no longer suitably named. Cheers, David > Thanks, > Amy From amy.lu at oracle.com Thu Oct 9 05:50:11 2014 From: amy.lu at oracle.com (Amy Lu) Date: Thu, 09 Oct 2014 13:50:11 +0800 Subject: RFR 8058855: Update java.util.zip tests to work with modular image In-Reply-To: <54361BC3.9000408@oracle.com> References: <543619FD.4040706@oracle.com> <54361BC3.9000408@oracle.com> Message-ID: <54362213.6070600@oracle.com> On 10/9/14, 1:23 PM, David Holmes wrote: > Hi Amy, > > On 9/10/2014 3:15 PM, Amy Lu wrote: >> Two java/util/zip tests use JDK rt.jar in test, this fix is to remove >> this dependency from test because with a modular rt.jar and the other >> JAR files in the JDK go away. >> >> bug: https://bugs.openjdk.java.net/browse/JDK-8058855 >> webrev: http://cr.openjdk.java.net/~tyan/amylu/8058855/webrev.00/ > > test/java/util/zip/InterruptibleZip.java > > Where is input.jar coming from? It's an existing jar file in test dir. > > test/java/util/zip/ZipFile/FinalizeZipFile.java > > The File variable "lib" is no longer suitably named. Updated name "lib" to "testdir": http://cr.openjdk.java.net/~weijun/8058855/webrev.01/ Thanks, Amy > > Cheers, > David > >> Thanks, >> Amy From mandy.chung at oracle.com Thu Oct 9 05:56:03 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 08 Oct 2014 22:56:03 -0700 Subject: RFR [8059563]: (proxy) sun.misc.ProxyGenerator.generateProxyClass should create intermediate directories In-Reply-To: <5435B1CD.3010905@oracle.com> References: <54327E9D.8060808@oracle.com> <54337E65.2000700@oracle.com> <5433A8A8.7000704@oracle.com> <54358F05.1000002@oracle.com> <5435B1CD.3010905@oracle.com> Message-ID: <54362373.5060505@oracle.com> > http://cr.openjdk.java.net/~igerasim/8059563/3/webrev/ I reviewed v3 version. Looks good. Mandy From ivan.gerasimov at oracle.com Thu Oct 9 06:20:45 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Thu, 09 Oct 2014 10:20:45 +0400 Subject: RFR [8059563]: (proxy) sun.misc.ProxyGenerator.generateProxyClass should create intermediate directories In-Reply-To: <54362373.5060505@oracle.com> References: <54327E9D.8060808@oracle.com> <54337E65.2000700@oracle.com> <5433A8A8.7000704@oracle.com> <54358F05.1000002@oracle.com> <5435B1CD.3010905@oracle.com> <54362373.5060505@oracle.com> Message-ID: <5436293D.3020109@oracle.com> Thank you Mandy! Seems like I managed to skip the mailing lists when sending the 3rd version of the review. Sorry about that. Sincerely yours, Ivan On 09.10.2014 9:56, Mandy Chung wrote: >> http://cr.openjdk.java.net/~igerasim/8059563/3/webrev/ > > I reviewed v3 version. Looks good. > > Mandy > > From frederic.parain at oracle.com Thu Oct 9 07:19:04 2014 From: frederic.parain at oracle.com (Frederic Parain) Date: Thu, 09 Oct 2014 09:19:04 +0200 Subject: RFR(L): JDK-8057777 Cleanup of old and unused VM interfaces In-Reply-To: <5433E564.8010402@oracle.com> References: <542AC0E8.9040409@oracle.com> <542EBE8F.5090800@oracle.com> <542EC9B4.1050908@oracle.com> <5432A7E8.5070601@oracle.com> <5433E564.8010402@oracle.com> Message-ID: <543636E8.9080802@oracle.com> Thank you Coleen, Harold, Alan and Sherman for your reviews. Fred On 07/10/2014 15:06, Alan Bateman wrote: > On 06/10/2014 07:32, Frederic Parain wrote: >> Thank you very much for catching the JVM_O_DELETE issue. >> I moved the O_DELETE support into the ZipFile.c file >> (code was the same for all non-Windows platforms) and >> cleaned up the original code in HotSpot. >> >> The new webrevs: >> >> http://cr.openjdk.java.net/~fparain/8057777/jdk_v03/ >> http://cr.openjdk.java.net/~fparain/8057777/hotspot_v03/ >> > Good spot by Sherman on the OPEN_DELETE issue, it makes me wonder what > the test coverage is on this. > > The updated webrev addresses the points that I brought up and looks good > (nice to see many of these functions going away). > > -Alan -- Frederic Parain - Oracle Grenoble Engineering Center - France Phone: +33 4 76 18 81 17 Email: Frederic.Parain at oracle.com From konstantin.shefov at oracle.com Thu Oct 9 08:44:44 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Thu, 09 Oct 2014 12:44:44 +0400 Subject: [9] Review request : JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <54357385.7060102@oracle.com> References: <54353903.4000406@oracle.com> <54353B2E.8000409@oracle.com> <54354C4D.8020308@oracle.com> <54357385.7060102@oracle.com> Message-ID: <54364AFC.5040101@oracle.com> Hi, I have updated the webrev to take into account the JDK 9 new feature with segmented code cache. http://cr.openjdk.java.net/~kshefov/8058733/webrev.02 Please, review. -Konstantin On 08.10.2014 21:25, Joe Darcy wrote: > Hello, > > I approve this change going into jdk9/dev contingent on the failing > tests passing as modified. > > Thanks, > > -Joe > > On 10/8/2014 7:38 AM, Konstantin Shefov wrote: >> Daniel, >> Thanks for your comment >> >> Here is the updated webrev: >> http://cr.openjdk.java.net/~kshefov/8058733/webrev.01 >> >> -Konstantin >> >> On 08.10.2014 17:25, Daniel Fuchs wrote: >>> Hi Konstantin, >>> >>> I'm not qualified as a (R)eviewer for changes in this area, >>> but I believe you can do: >>> >>> HotSpotDiagnosticMXBean mbean = >>> ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); >>> >>> to get a handle on the MBean. You don't need to go through >>> the MBeanServer and newPlatformMXBeanProxy stuff... >>> >>> best regards, >>> >>> -- daniel >>> >>> On 08/10/14 15:15, Konstantin Shefov wrote: >>>> Hello, >>>> >>>> Please review the test bug fix >>>> https://bugs.openjdk.java.net/browse/JDK-8058733 >>>> Webrev is http://cr.openjdk.java.net/~kshefov/8058733/webrev.00/ >>>> >>>> Thanks >>>> >>>> -Konstantin >>> >> > From olivier.lagneau at oracle.com Thu Oct 9 10:27:25 2014 From: olivier.lagneau at oracle.com (olivier.lagneau at oracle.com) Date: Thu, 09 Oct 2014 12:27:25 +0200 Subject: Urgent [9], 3rd round, RFR (S) : JDK-8039915 NumberFormat.format() does not consider required no. of fraction digits properly In-Reply-To: <54341401.4000109@oracle.com> References: <542D7D6B.6000108@oracle.com> <54341401.4000109@oracle.com> Message-ID: <5436630D.4030107@oracle.com> Please review this 3rd version of the fix taking into account latest feedback from Joe. Bug : https://bugs.openjdk.java.net/browse/JDK-8039915 Webrev : http://cr.openjdk.java.net/~olagneau/8039915/webrev.02/ List of changes from previous webrev: - renamed "allDecimalDigits" to "valueExactAsDecimal" - changed related @param javadoc comments - restored conventional formatting on "else if" clause - changed rounding decision code when last digit at rounding position and valueExactAsDecimal true to synthetic return statement: "return roundingMode == RoundingMode.HALF_UP;" with adapted comment. testing: jtreg, jck8, jprt, code coverage. Thanks for reviewing, Olivier. On 07/10/2014 18:25, Joe Darcy wrote: > Hi Olivier, > > Some rewording suggestions: > > 445 * @param alreadyRounded Boolean indicating if rounding up > already happened. > 446 * @param allDecimalDigits Boolean indicating if the digits > provide an exact > 447 * representation of the value. > > Including the type of the parameter is redundant with its declaration > so I'd recommend something like > > 445 * @param alreadyRounded whether or not rounding up has > already happened. > > Given the semantics of allDecimalDigits, I recommend renaming the > parameter to something like "valueExactAsDecimal". > > For > > please restore the conventional formatting > > 532 } else if (digits[maximumDigits] == '5') { > > The code > > 543 if (roundingMode == > RoundingMode.HALF_UP) { > 544 // Strictly follow HALF_UP rule > ==> round-up > 545 return true; > 546 } > 547 else { > 548 // Strictly follow HALF_DOWN rule > ==> don't round-up > 549 return false; > 550 } > > can be replaced by > > 545 return roundingMode == > RoundingMode.HALF_UP; > > with a suitable comment. > > Please make these adjustments and I'll do a careful review of the > rounding logic. > > Thanks, > > -Joe > > On 10/2/2014 9:29 AM, olivier.lagneau at oracle.com wrote: >> Please review this 2nd version of the fix taking into account your >> feedback. >> >> Bug : https://bugs.openjdk.java.net/browse/JDK-8039915 >> webrev : http://cr.openjdk.java.net/~olagneau/8039915/webrev.01 >> >> I have changed the code following your remarks >> >> Testing: lot of testing on jtreg, jck8, code coverage, jprt. >> >> Below are more details on the changes in this webrev. >> >> For the new work in question, it might be clearer to me if the >> HALF_UP and HALF_DOWN cases >>> were combined into a single block since they > share much of the logic. >>> The unique logic for each mode would be easier to see if the >>> differences were placed together. >> I have merged HALF_UP and HALF_DOWN cases into a single switch case. >> >> I also tested a fully merged version where HALF_UP, HALF_DOWN, and >> also HALF_EVEN are merge >> into a single switch case. So merging the three is even possible. >> If you want to have the three HALF_* cases we can quickly move to that. >> >>> My only suggestions are trivial: 1) enhance the method javadoc of >>> shouldRoundUp(), e.g., there are no @param tags for the boolean >>> parameters, >> Fixed that. @param tags are available for shouldRoundUp method >> >>> 2) use braces around all the statements contained in if/else blocks >>> (see below). Comment #2 is nit-picky. >> Took care to follow this rule in this new version. >> >>> If the test is already printing out the information you showed above >>> (?Error formatting ??) then I think it is enough but the verbiage >>> should perhaps match the reminder, e.g., ?Failure: Error formatting >>> double ?? >> Changed test code to provide this consistent wording. >> >> Thanks, >> Olivier. >> >> >> >> > From daniel.fuchs at oracle.com Thu Oct 9 13:09:03 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Thu, 09 Oct 2014 15:09:03 +0200 Subject: RFR: 8042147: test sun/util/logging/SourceClassName.java failed: Unexpected source: java.util.Currency info Message-ID: <543688EF.7050802@oracle.com> Hi, Please find below a fix for: 8042147: test sun/util/logging/SourceClassName.java failed: Unexpected source: java.util.Currency info https://bugs.openjdk.java.net/browse/JDK-8042147 webrev: http://cr.openjdk.java.net/~dfuchs/webrev_8042147/webrev.00/ It seems that something on some test systems can prompt java.util.Currency to log an INFO message (either at startup or triggered by the loading of some classes). The code of this test checks all the log messages that are printed and fails because it finds the unexpected message. The fix changes the test code to allow for the possibility that something else than the test code itself might be using java.util.logging. best regards, -- daniel From lance.andersen at oracle.com Thu Oct 9 13:39:10 2014 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 9 Oct 2014 09:39:10 -0400 Subject: RFR: 8042147: test sun/util/logging/SourceClassName.java failed: Unexpected source: java.util.Currency info In-Reply-To: <543688EF.7050802@oracle.com> References: <543688EF.7050802@oracle.com> Message-ID: Looks OK Daniel Best Lance On Oct 9, 2014, at 9:09 AM, Daniel Fuchs wrote: > Hi, > > Please find below a fix for: > > 8042147: test sun/util/logging/SourceClassName.java failed: > Unexpected source: java.util.Currency info > > https://bugs.openjdk.java.net/browse/JDK-8042147 > > webrev: http://cr.openjdk.java.net/~dfuchs/webrev_8042147/webrev.00/ > > > It seems that something on some test systems can prompt > java.util.Currency to log an INFO message (either at startup or > triggered by the loading of some classes). > The code of this test checks all the log messages that are printed and fails because it finds the unexpected message. > > The fix changes the test code to allow for the possibility that something else than the test code itself might be using > java.util.logging. > > best regards, > > -- daniel Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From kumar.x.srinivasan at oracle.com Thu Oct 9 14:34:42 2014 From: kumar.x.srinivasan at oracle.com (Kumar Srinivasan) Date: Thu, 09 Oct 2014 07:34:42 -0700 Subject: RFR: 8059973: Broken link in Class Pack200 Message-ID: <54369D02.1060209@oracle.com> Hello, Please review simple fix to remove the URL reference to Java Deployment Guide, these tend to move, causing broken link. Thanks Kumar diff --git a/src/java.base/share/classes/java/util/jar/Pack200.java b/src/java.base/share/classes/java/util/jar/Pack200.java --- a/src/java.base/share/classes/java/util/jar/Pack200.java +++ b/src/java.base/share/classes/java/util/jar/Pack200.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,8 +93,7 @@ * The deployment applications can use "Accept-Encoding=pack200-gzip". This * indicates to the server that the client application desires a version of * the file encoded with Pack200 and further compressed with gzip. Please - * refer to Java Deployment Guide for more details and - * techniques. + * refer to the Java Deployment Guide for techniques and details. *

* Unless otherwise noted, passing a null argument to a constructor or * method in this class will cause a {@link NullPointerException} to be thrown. From joe.darcy at oracle.com Thu Oct 9 15:56:38 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Thu, 09 Oct 2014 08:56:38 -0700 Subject: [9] Review request : JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <54364AFC.5040101@oracle.com> References: <54353903.4000406@oracle.com> <54353B2E.8000409@oracle.com> <54354C4D.8020308@oracle.com> <54357385.7060102@oracle.com> <54364AFC.5040101@oracle.com> Message-ID: <5436B036.6030905@oracle.com> Looks fine Konstantin. (These tests have been failing very often since they were pushed. If your fix isn't pushed today, I'd argue for the tests being excluded.) Thanks, -Joe On 10/9/2014 1:44 AM, Konstantin Shefov wrote: > Hi, > > I have updated the webrev to take into account the JDK 9 new feature > with segmented code cache. > http://cr.openjdk.java.net/~kshefov/8058733/webrev.02 > > Please, review. > > -Konstantin > > On 08.10.2014 21:25, Joe Darcy wrote: >> Hello, >> >> I approve this change going into jdk9/dev contingent on the failing >> tests passing as modified. >> >> Thanks, >> >> -Joe >> >> On 10/8/2014 7:38 AM, Konstantin Shefov wrote: >>> Daniel, >>> Thanks for your comment >>> >>> Here is the updated webrev: >>> http://cr.openjdk.java.net/~kshefov/8058733/webrev.01 >>> >>> -Konstantin >>> >>> On 08.10.2014 17:25, Daniel Fuchs wrote: >>>> Hi Konstantin, >>>> >>>> I'm not qualified as a (R)eviewer for changes in this area, >>>> but I believe you can do: >>>> >>>> HotSpotDiagnosticMXBean mbean = >>>> ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); >>>> >>>> to get a handle on the MBean. You don't need to go through >>>> the MBeanServer and newPlatformMXBeanProxy stuff... >>>> >>>> best regards, >>>> >>>> -- daniel >>>> >>>> On 08/10/14 15:15, Konstantin Shefov wrote: >>>>> Hello, >>>>> >>>>> Please review the test bug fix >>>>> https://bugs.openjdk.java.net/browse/JDK-8058733 >>>>> Webrev is http://cr.openjdk.java.net/~kshefov/8058733/webrev.00/ >>>>> >>>>> Thanks >>>>> >>>>> -Konstantin >>>> >>> >> > From xueming.shen at oracle.com Thu Oct 9 16:56:00 2014 From: xueming.shen at oracle.com (Xueming Shen) Date: Thu, 09 Oct 2014 09:56:00 -0700 Subject: RFR 8058855: Update java.util.zip tests to work with modular image In-Reply-To: <54362213.6070600@oracle.com> References: <543619FD.4040706@oracle.com> <54361BC3.9000408@oracle.com> <54362213.6070600@oracle.com> Message-ID: <5436BE20.4020000@oracle.com> On 10/08/2014 10:50 PM, Amy Lu wrote: > On 10/9/14, 1:23 PM, David Holmes wrote: >> Hi Amy, >> >> On 9/10/2014 3:15 PM, Amy Lu wrote: >>> Two java/util/zip tests use JDK rt.jar in test, this fix is to remove >>> this dependency from test because with a modular rt.jar and the other >>> JAR files in the JDK go away. >>> >>> bug: https://bugs.openjdk.java.net/browse/JDK-8058855 >>> webrev: http://cr.openjdk.java.net/~tyan/amylu/8058855/webrev.00/ >> >> test/java/util/zip/InterruptibleZip.java >> >> Where is input.jar coming from? > > It's an existing jar file in test dir. >> >> test/java/util/zip/ZipFile/FinalizeZipFile.java >> >> The File variable "lib" is no longer suitably named. > > Updated name "lib" to "testdir": > http://cr.openjdk.java.net/~weijun/8058855/webrev.01/ > > Thanks, > Amy looks fine. From joe.darcy at oracle.com Thu Oct 9 17:16:37 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Thu, 09 Oct 2014 10:16:37 -0700 Subject: Urgent [9], 3rd round, RFR (S) : JDK-8039915 NumberFormat.format() does not consider required no. of fraction digits properly In-Reply-To: <5436630D.4030107@oracle.com> References: <542D7D6B.6000108@oracle.com> <54341401.4000109@oracle.com> <5436630D.4030107@oracle.com> Message-ID: <5436C2F5.4050506@oracle.com> Hi Olivier, Please change the formatting any if-else statements like 537 } 538 else { 545 } 546 else { 552 } 553 else { to be 537 } else { More substantively, these lines 547 // Not an exact binary representation. 548 if (alreadyRounded) { 549 // Digit sequence rounded-up. Was below tie. 550 // Don't round-up twice ! 551 return false; 552 } 553 else { 554 // Digit sequence truncated. Was above tie. 555 // must round-up ! 556 return true; 557 } Can be replaced by return !alreadyRounded; with appropriate commenting. Please make these changes; as long as the tests still pass, no re-review is needed. Thanks, -Joe On 10/9/2014 3:27 AM, olivier.lagneau at oracle.com wrote: > Please review this 3rd version of the fix taking into account latest > feedback from Joe. > > Bug : https://bugs.openjdk.java.net/browse/JDK-8039915 > Webrev : http://cr.openjdk.java.net/~olagneau/8039915/webrev.02/ > > > List of changes from previous webrev: > - renamed "allDecimalDigits" to "valueExactAsDecimal" > - changed related @param javadoc comments > - restored conventional formatting on "else if" clause > - changed rounding decision code when last digit at rounding position > and valueExactAsDecimal true to synthetic return statement: > "return roundingMode == RoundingMode.HALF_UP;" with adapted comment. > > testing: jtreg, jck8, jprt, code coverage. > > Thanks for reviewing, > Olivier. > > > > On 07/10/2014 18:25, Joe Darcy wrote: >> Hi Olivier, >> >> Some rewording suggestions: >> >> 445 * @param alreadyRounded Boolean indicating if rounding up >> already happened. >> 446 * @param allDecimalDigits Boolean indicating if the digits >> provide an exact >> 447 * representation of the value. >> >> Including the type of the parameter is redundant with its declaration >> so I'd recommend something like >> >> 445 * @param alreadyRounded whether or not rounding up has >> already happened. >> >> Given the semantics of allDecimalDigits, I recommend renaming the >> parameter to something like "valueExactAsDecimal". >> >> For >> >> please restore the conventional formatting >> >> 532 } else if (digits[maximumDigits] == '5') { >> >> The code >> >> 543 if (roundingMode == >> RoundingMode.HALF_UP) { >> 544 // Strictly follow HALF_UP rule >> ==> round-up >> 545 return true; >> 546 } >> 547 else { >> 548 // Strictly follow HALF_DOWN >> rule ==> don't round-up >> 549 return false; >> 550 } >> >> can be replaced by >> >> 545 return roundingMode == >> RoundingMode.HALF_UP; >> >> with a suitable comment. >> >> Please make these adjustments and I'll do a careful review of the >> rounding logic. >> >> Thanks, >> >> -Joe >> >> On 10/2/2014 9:29 AM, olivier.lagneau at oracle.com wrote: >>> Please review this 2nd version of the fix taking into account your >>> feedback. >>> >>> Bug : https://bugs.openjdk.java.net/browse/JDK-8039915 >>> webrev : http://cr.openjdk.java.net/~olagneau/8039915/webrev.01 >>> >>> I have changed the code following your remarks >>> >>> Testing: lot of testing on jtreg, jck8, code coverage, jprt. >>> >>> Below are more details on the changes in this webrev. >>> >>> For the new work in question, it might be clearer to me if the >>> HALF_UP and HALF_DOWN cases >>>> were combined into a single block since they > share much of the >>>> logic. >>>> The unique logic for each mode would be easier to see if the >>>> differences were placed together. >>> I have merged HALF_UP and HALF_DOWN cases into a single switch case. >>> >>> I also tested a fully merged version where HALF_UP, HALF_DOWN, and >>> also HALF_EVEN are merge >>> into a single switch case. So merging the three is even possible. >>> If you want to have the three HALF_* cases we can quickly move to that. >>> >>>> My only suggestions are trivial: 1) enhance the method javadoc of >>>> shouldRoundUp(), e.g., there are no @param tags for the boolean >>>> parameters, >>> Fixed that. @param tags are available for shouldRoundUp method >>> >>>> 2) use braces around all the statements contained in if/else blocks >>>> (see below). Comment #2 is nit-picky. >>> Took care to follow this rule in this new version. >>> >>>> If the test is already printing out the information you showed >>>> above (?Error formatting ??) then I think it is enough but the >>>> verbiage should perhaps match the reminder, e.g., ?Failure: Error >>>> formatting double ?? >>> Changed test code to provide this consistent wording. >>> >>> Thanks, >>> Olivier. >>> >>> >>> >>> >> > From lance.andersen at oracle.com Thu Oct 9 19:33:30 2014 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 9 Oct 2014 15:33:30 -0400 Subject: RFR 8059997: Fix broken link in WebRowSet javadoc Message-ID: <1467A0E7-A949-4B29-B6EE-9C09F2A532DD@oracle.com> Hi all need a reviewer for the following change to address a broken link in the WebRowSet javadoc: hg diff src/java.sql.rowset/share/classes/javax/sql/rowset/WebRowSet.java diff -r f71379c4864f src/java.sql.rowset/share/classes/javax/sql/rowset/WebRowSet.java --- a/src/java.sql.rowset/share/classes/javax/sql/rowset/WebRowSet.java Wed Oct 08 11:51:36 2014 -0400 +++ b/src/java.sql.rowset/share/classes/javax/sql/rowset/WebRowSet.java Thu Oct 09 15:28:25 2014 -0400 @@ -56,7 +56,7 @@ * organization. The SQL/XML definition is available at the following URI: *

* The schema definition describes the internal data of a {@code RowSet} object ljanders-mac:jdk ljanders$ Best, Lance Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From roger.riggs at oracle.com Thu Oct 9 19:48:30 2014 From: roger.riggs at oracle.com (roger riggs) Date: Thu, 09 Oct 2014 15:48:30 -0400 Subject: RFR 8059997: Fix broken link in WebRowSet javadoc In-Reply-To: <1467A0E7-A949-4B29-B6EE-9C09F2A532DD@oracle.com> References: <1467A0E7-A949-4B29-B6EE-9C09F2A532DD@oracle.com> Message-ID: <5436E68E.20100@oracle.com> Hi Lance, Looks fine. Roger On 10/9/2014 3:33 PM, Lance Andersen wrote: > Hi all > > need a reviewer for the following change to address a broken link in the WebRowSet javadoc: > > hg diff src/java.sql.rowset/share/classes/javax/sql/rowset/WebRowSet.java > diff -r f71379c4864f src/java.sql.rowset/share/classes/javax/sql/rowset/WebRowSet.java > --- a/src/java.sql.rowset/share/classes/javax/sql/rowset/WebRowSet.java Wed Oct 08 11:51:36 2014 -0400 > +++ b/src/java.sql.rowset/share/classes/javax/sql/rowset/WebRowSet.java Thu Oct 09 15:28:25 2014 -0400 > @@ -56,7 +56,7 @@ > * organization. The SQL/XML definition is available at the following URI: > * > * The schema definition describes the internal data of a {@code RowSet} object > ljanders-mac:jdk ljanders$ > > > Best, > Lance > > > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 > Oracle Java Engineering > 1 Network Drive > Burlington, MA 01803 > Lance.Andersen at oracle.com > > > From jason_mehrens at hotmail.com Thu Oct 9 19:56:47 2014 From: jason_mehrens at hotmail.com (Jason Mehrens) Date: Thu, 9 Oct 2014 14:56:47 -0500 Subject: JDK-6774110 lock file is not deleted when child logger is used Message-ID: Daniel, The evaluation on this bug is not quite correct. What is going on here is the child logger is garbage collected which makes the FileHandler unreachable from the LogManager$Cleaner which would have closed the attached FileHandler. In the example, there is no hard reference that escapes the 'execute' method. Prior to fixing JDK-6274920: JDK logger holds strong reference to java.util.logging.Logger instances, the LogManager$Cleaner would have deleted the lock file on shutdown. Now that the loggers are GC'able, one possible fix would be change the FileHandler.locks static field to Map where the key is the file name and the value is the FileHandler that is open. Then in the LogManager$Cleaner could close any entries in that map after LogManager.reset() is executed. Jason From mandy.chung at oracle.com Thu Oct 9 20:08:48 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Thu, 09 Oct 2014 13:08:48 -0700 Subject: RFR: 8059973: Broken link in Class Pack200 In-Reply-To: <54369D02.1060209@oracle.com> References: <54369D02.1060209@oracle.com> Message-ID: <5436EB50.5000604@oracle.com> Thumbs up. Mandy On 10/9/14 7:34 AM, Kumar Srinivasan wrote: > Hello, > > Please review simple fix to remove the URL reference to Java > Deployment Guide, > these tend to move, causing broken link. > > Thanks > Kumar > > diff --git a/src/java.base/share/classes/java/util/jar/Pack200.java > b/src/java.base/share/classes/java/util/jar/Pack200.java > --- a/src/java.base/share/classes/java/util/jar/Pack200.java > +++ b/src/java.base/share/classes/java/util/jar/Pack200.java > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights > reserved. > + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights > reserved. > * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. > * > * This code is free software; you can redistribute it and/or modify it > @@ -93,8 +93,7 @@ > * The deployment applications can use > "Accept-Encoding=pack200-gzip". This > * indicates to the server that the client application desires a > version of > * the file encoded with Pack200 and further compressed with gzip. > Please > - * refer to href="{@docRoot}/../technotes/guides/deployment/deployment-guide/pack200.html">Java > Deployment Guide for more details and > - * techniques. > + * refer to the Java Deployment Guide for techniques and details. > *

> * Unless otherwise noted, passing a null argument to a > constructor or > * method in this class will cause a {@link NullPointerException} to > be thrown. From daniel.fuchs at oracle.com Thu Oct 9 20:59:43 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Thu, 09 Oct 2014 22:59:43 +0200 Subject: JDK-6774110 lock file is not deleted when child logger is used In-Reply-To: References: Message-ID: <5436F73F.5050102@oracle.com> Thanks Jason. I wonder if that may be another issue. Interesting. I'll see if I can work out a test case for that tomorrow. With the test case provided in the bug - tested on 7, 8, and 9, the only file that remained at the end was 'log' (which is as it should be - and I ran the test case several times with each JDK) - which lets me think that maybe the issue was different. Now what you describe looks indeed like a bug that should still be present in the code base. I didn't think about that scenario, thanks for pointing it out! If i can write a reproducer (which should not be too difficult), it will be a good incentive to attempt a fix :-) Thanks again, -- daniel On 10/9/14 9:56 PM, Jason Mehrens wrote: > Daniel, > > > The evaluation on this bug is not quite correct. What is going on here is the child logger is garbage collected which makes the FileHandler unreachable from the LogManager$Cleaner which would have closed the attached FileHandler. In the example, there is no hard reference that escapes the 'execute' method. Prior to fixing JDK-6274920: JDK logger holds strong reference to java.util.logging.Logger instances, the LogManager$Cleaner would have deleted the lock file on shutdown. Now that the loggers are GC'able, one possible fix would be change the FileHandler.locks static field to Map where the key is the file name and the value is the FileHandler that is open. Then in the LogManager$Cleaner could close any entries in that map after LogManager.reset() is executed. > > > Jason From jason_mehrens at hotmail.com Fri Oct 10 01:11:07 2014 From: jason_mehrens at hotmail.com (Jason Mehrens) Date: Thu, 9 Oct 2014 20:11:07 -0500 Subject: JDK-6774110 lock file is not deleted when child logger is used In-Reply-To: <5436F73F.5050102@oracle.com> References: , <5436F73F.5050102@oracle.com> Message-ID: Here is a test case. public class GcOfLogger { private static final String CLASS_NAME = GcOfLogger.class.getName(); public static void main(String[] args) throws Exception { File log = new File(CLASS_NAME.concat(".xml")); install(log.getCanonicalPath()); LogManager manager = LogManager.getLogManager(); boolean cleared = false; for (int i = 0; i < 10; i++) { if (manager.getLogger(CLASS_NAME) != null) { System.runFinalization(); System.gc(); System.runFinalization(); Thread.sleep(200L); } else { cleared = true; break; } } if (!cleared) { throw new IllegalStateException(); } File lock = new File(log.getCanonicalPath().concat(".lck")); System.out.println(log.delete()); System.out.println(lock.delete()); } private static void install(String log) throws Exception { String path = new File(log).getCanonicalPath(); Logger logger = Logger.getLogger(CLASS_NAME); //No strong reference. logger.addHandler(new FileHandler(path)); } } ---------------------------------------- > Date: Thu, 9 Oct 2014 22:59:43 +0200 > From: daniel.fuchs at oracle.com > To: jason_mehrens at hotmail.com > CC: core-libs-dev at openjdk.java.net > Subject: Re: JDK-6774110 lock file is not deleted when child logger is used > > Thanks Jason. > > I wonder if that may be another issue. Interesting. I'll see if I can > work out a test case > for that tomorrow. With the test case provided in the bug - tested on 7, > 8, and 9, > the only file that remained at the end was 'log' (which is as it should > be - and I ran > the test case several times with each JDK) - which lets me think that > maybe the > issue was different. > > Now what you describe looks indeed like a bug that should still be present > in the code base. I didn't think about that scenario, thanks for > pointing it out! > If i can write a reproducer (which should not be too difficult), it will > be a good > incentive to attempt a fix :-) > > Thanks again, > > -- daniel > > On 10/9/14 9:56 PM, Jason Mehrens wrote: >> Daniel, >> >> >> The evaluation on this bug is not quite correct. What is going on here is the child logger is garbage collected which makes the FileHandler unreachable from the LogManager$Cleaner which would have closed the attached FileHandler. In the example, there is no hard reference that escapes the 'execute' method. Prior to fixing JDK-6274920: JDK logger holds strong reference to java.util.logging.Logger instances, the LogManager$Cleaner would have deleted the lock file on shutdown. Now that the loggers are GC'able, one possible fix would be change the FileHandler.locks static field to Map where the key is the file name and the value is the FileHandler that is open. Then in the LogManager$Cleaner could close any entries in that map after LogManager.reset() is executed. >> >> >> Jason > From stanimir at riflexo.com Fri Oct 10 08:02:34 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Fri, 10 Oct 2014 04:02:34 -0400 Subject: JDK-6774110 lock file is not deleted when child logger is used In-Reply-To: <5436F73F.5050102@oracle.com> References: <5436F73F.5050102@oracle.com> Message-ID: Hi, LogManager.reset() should invoke a package private method to delete all lock files. However, that would require holding the FileHandler.locks monitor during the resetting of FileHandlers, not just the deletion process. Something like that, plus new PrivilegedAction(). static void deleteAllLocks(){ synchronized(locks){ for (String file : locks) new File(file).delete(); locks.clear(); } } Alternatively the deletion could just be part of the Cleaner shutdownhook with another sun.misc.Cleaner per FileHandler that deletes the file. (Handlers can be shared amongst loggers, so they cannot be closed explicitly). There is a certain risk as file.delete() can be a very slow operation, though (ext3 [concurrently] deleting large files for example). Stanimir On Thu, Oct 9, 2014 at 4:59 PM, Daniel Fuchs wrote: > Thanks Jason. > > I wonder if that may be another issue. Interesting. I'll see if I can work > out a test case > for that tomorrow. With the test case provided in the bug - tested on 7, > 8, and 9, > the only file that remained at the end was 'log' (which is as it should > be - and I ran > the test case several times with each JDK) - which lets me think that > maybe the > issue was different. > > Now what you describe looks indeed like a bug that should still be present > in the code base. I didn't think about that scenario, thanks for pointing > it out! > If i can write a reproducer (which should not be too difficult), it will > be a good > incentive to attempt a fix :-) > > Thanks again, > > -- daniel > > > On 10/9/14 9:56 PM, Jason Mehrens wrote: > >> Daniel, >> >> >> The evaluation on this bug is not quite correct. What is going on here >> is the child logger is garbage collected which makes the FileHandler >> unreachable from the LogManager$Cleaner which would have closed the >> attached FileHandler. In the example, there is no hard reference that >> escapes the 'execute' method. Prior to fixing JDK-6274920: JDK logger >> holds strong reference to java.util.logging.Logger instances, the >> LogManager$Cleaner would have deleted the lock file on shutdown. Now that >> the loggers are GC'able, one possible fix would be change the >> FileHandler.locks static field to Map where the key is >> the file name and the value is the FileHandler that is open. Then in the >> LogManager$Cleaner could close any entries in that map after >> LogManager.reset() is executed. >> >> >> Jason >> > > From konstantin.shefov at oracle.com Fri Oct 10 08:39:16 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Fri, 10 Oct 2014 12:39:16 +0400 Subject: [9] Review request : JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <5436B036.6030905@oracle.com> References: <54353903.4000406@oracle.com> <54353B2E.8000409@oracle.com> <54354C4D.8020308@oracle.com> <54357385.7060102@oracle.com> <54364AFC.5040101@oracle.com> <5436B036.6030905@oracle.com> Message-ID: <54379B34.1010501@oracle.com> Gently reminder On 09.10.2014 19:56, Joe Darcy wrote: > Looks fine Konstantin. > > (These tests have been failing very often since they were pushed. If > your fix isn't pushed today, I'd argue for the tests being excluded.) Please, review > > Thanks, > > -Joe > > On 10/9/2014 1:44 AM, Konstantin Shefov wrote: >> Hi, >> >> I have updated the webrev to take into account the JDK 9 new feature >> with segmented code cache. >> http://cr.openjdk.java.net/~kshefov/8058733/webrev.02 >> >> Please, review. >> >> -Konstantin >> >> On 08.10.2014 21:25, Joe Darcy wrote: >>> Hello, >>> >>> I approve this change going into jdk9/dev contingent on the failing >>> tests passing as modified. >>> >>> Thanks, >>> >>> -Joe >>> >>> On 10/8/2014 7:38 AM, Konstantin Shefov wrote: >>>> Daniel, >>>> Thanks for your comment >>>> >>>> Here is the updated webrev: >>>> http://cr.openjdk.java.net/~kshefov/8058733/webrev.01 >>>> >>>> -Konstantin >>>> >>>> On 08.10.2014 17:25, Daniel Fuchs wrote: >>>>> Hi Konstantin, >>>>> >>>>> I'm not qualified as a (R)eviewer for changes in this area, >>>>> but I believe you can do: >>>>> >>>>> HotSpotDiagnosticMXBean mbean = >>>>> ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); >>>>> >>>>> to get a handle on the MBean. You don't need to go through >>>>> the MBeanServer and newPlatformMXBeanProxy stuff... >>>>> >>>>> best regards, >>>>> >>>>> -- daniel >>>>> >>>>> On 08/10/14 15:15, Konstantin Shefov wrote: >>>>>> Hello, >>>>>> >>>>>> Please review the test bug fix >>>>>> https://bugs.openjdk.java.net/browse/JDK-8058733 >>>>>> Webrev is http://cr.openjdk.java.net/~kshefov/8058733/webrev.00/ >>>>>> >>>>>> Thanks >>>>>> >>>>>> -Konstantin >>>>> >>>> >>> >> > From konstantin.shefov at oracle.com Fri Oct 10 09:06:29 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Fri, 10 Oct 2014 13:06:29 +0400 Subject: [8u40] Request for approval and review : 8058695: [TESTBUG] Reinvokers with arity >253 can't be cached Message-ID: <5437A195.6050200@oracle.com> Hello, Please review and approve the backport of the test bug fix to 8u40 The bug: https://bugs.openjdk.java.net/browse/JDK-8058695 The webrev: http://cr.openjdk.java.net/~kshefov/8058695/8u-dev/webrev.00 Thanks -Konstantin From olivier.lagneau at oracle.com Fri Oct 10 09:14:54 2014 From: olivier.lagneau at oracle.com (olivier.lagneau at oracle.com) Date: Fri, 10 Oct 2014 11:14:54 +0200 Subject: Urgent [9], 3rd round, RFR (S) : JDK-8039915 NumberFormat.format() does not consider required no. of fraction digits properly In-Reply-To: <5436C2F5.4050506@oracle.com> References: <542D7D6B.6000108@oracle.com> <54341401.4000109@oracle.com> <5436630D.4030107@oracle.com> <5436C2F5.4050506@oracle.com> Message-ID: <5437A38E.1030407@oracle.com> Thanks Joe, Will modify and check the tests accordingly. Brian, I guess you are still ok with these code changes ? Thanks a lot both of you for the reviewing. Thanks a lot William for checking with your own tests. That is very much appreciated ! ;-) Olivier. On 09/10/2014 19:16, Joe Darcy wrote: > Hi Olivier, > > Please change the formatting any if-else statements like > > 537 } > 538 else { > > 545 } > 546 else { > > 552 } > 553 else { > > to be > > 537 } else { > > More substantively, these lines > > 547 // Not an exact binary representation. > 548 if (alreadyRounded) { > 549 // Digit sequence rounded-up. Was > below tie. > 550 // Don't round-up twice ! > 551 return false; > 552 } > 553 else { > 554 // Digit sequence truncated. Was > above tie. > 555 // must round-up ! > 556 return true; > 557 } > > Can be replaced by > > return !alreadyRounded; > > with appropriate commenting. > > Please make these changes; as long as the tests still pass, no > re-review is needed. > > Thanks, > > -Joe > > On 10/9/2014 3:27 AM, olivier.lagneau at oracle.com wrote: >> Please review this 3rd version of the fix taking into account latest >> feedback from Joe. >> >> Bug : https://bugs.openjdk.java.net/browse/JDK-8039915 >> Webrev : http://cr.openjdk.java.net/~olagneau/8039915/webrev.02/ >> >> >> List of changes from previous webrev: >> - renamed "allDecimalDigits" to "valueExactAsDecimal" >> - changed related @param javadoc comments >> - restored conventional formatting on "else if" clause >> - changed rounding decision code when last digit at rounding position >> and valueExactAsDecimal true to synthetic return statement: >> "return roundingMode == RoundingMode.HALF_UP;" with adapted comment. >> >> testing: jtreg, jck8, jprt, code coverage. >> >> Thanks for reviewing, >> Olivier. >> >> >> >> On 07/10/2014 18:25, Joe Darcy wrote: >>> Hi Olivier, >>> >>> Some rewording suggestions: >>> >>> 445 * @param alreadyRounded Boolean indicating if rounding up >>> already happened. >>> 446 * @param allDecimalDigits Boolean indicating if the digits >>> provide an exact >>> 447 * representation of the value. >>> >>> Including the type of the parameter is redundant with its >>> declaration so I'd recommend something like >>> >>> 445 * @param alreadyRounded whether or not rounding up has >>> already happened. >>> >>> Given the semantics of allDecimalDigits, I recommend renaming the >>> parameter to something like "valueExactAsDecimal". >>> >>> For >>> >>> please restore the conventional formatting >>> >>> 532 } else if (digits[maximumDigits] == '5') { >>> >>> The code >>> >>> 543 if (roundingMode == >>> RoundingMode.HALF_UP) { >>> 544 // Strictly follow HALF_UP rule >>> ==> round-up >>> 545 return true; >>> 546 } >>> 547 else { >>> 548 // Strictly follow HALF_DOWN >>> rule ==> don't round-up >>> 549 return false; >>> 550 } >>> >>> can be replaced by >>> >>> 545 return roundingMode == >>> RoundingMode.HALF_UP; >>> >>> with a suitable comment. >>> >>> Please make these adjustments and I'll do a careful review of the >>> rounding logic. >>> >>> Thanks, >>> >>> -Joe >>> >>> On 10/2/2014 9:29 AM, olivier.lagneau at oracle.com wrote: >>>> Please review this 2nd version of the fix taking into account your >>>> feedback. >>>> >>>> Bug : https://bugs.openjdk.java.net/browse/JDK-8039915 >>>> webrev : http://cr.openjdk.java.net/~olagneau/8039915/webrev.01 >>>> >>>> I have changed the code following your remarks >>>> >>>> Testing: lot of testing on jtreg, jck8, code coverage, jprt. >>>> >>>> Below are more details on the changes in this webrev. >>>> >>>> For the new work in question, it might be clearer to me if the >>>> HALF_UP and HALF_DOWN cases >>>>> were combined into a single block since they > share much of the >>>>> logic. >>>>> The unique logic for each mode would be easier to see if the >>>>> differences were placed together. >>>> I have merged HALF_UP and HALF_DOWN cases into a single switch case. >>>> >>>> I also tested a fully merged version where HALF_UP, HALF_DOWN, and >>>> also HALF_EVEN are merge >>>> into a single switch case. So merging the three is even possible. >>>> If you want to have the three HALF_* cases we can quickly move to that. >>>> >>>>> My only suggestions are trivial: 1) enhance the method javadoc of >>>>> shouldRoundUp(), e.g., there are no @param tags for the boolean >>>>> parameters, >>>> Fixed that. @param tags are available for shouldRoundUp method >>>> >>>>> 2) use braces around all the statements contained in if/else >>>>> blocks (see below). Comment #2 is nit-picky. >>>> Took care to follow this rule in this new version. >>>> >>>>> If the test is already printing out the information you showed >>>>> above (?Error formatting ??) then I think it is enough but the >>>>> verbiage should perhaps match the reminder, e.g., ?Failure: Error >>>>> formatting double ?? >>>> Changed test code to provide this consistent wording. >>>> >>>> Thanks, >>>> Olivier. >>>> >>>> >>>> >>>> >>> >> > From daniel.fuchs at oracle.com Fri Oct 10 09:39:41 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 10 Oct 2014 11:39:41 +0200 Subject: JDK-6774110 lock file is not deleted when child logger is used In-Reply-To: References: <5436F73F.5050102@oracle.com> Message-ID: <5437A95D.4050806@oracle.com> Hi Stanimir, Jason, On 10/10/14 10:02, Stanimir Simeonoff wrote: > Hi, > > LogManager.reset() should invoke a package private method to delete all > lock files. However, that would require holding the FileHandler.locks > monitor during the resetting of FileHandlers, not just the deletion > process. Something like that, plus new PrivilegedAction(). > static void deleteAllLocks(){ > synchronized(locks){ > for (String file : locks) new File(file).delete(); > locks.clear(); > } > } There's more than the deletion of the lock file unfortunately. I believe the handlers should be properly closed. A handler with an XMLFormatter for instance needs to write the tail of the file. > Alternatively the deletion could just be part of the Cleaner > shutdownhook with another sun.misc.Cleaner per FileHandler that deletes > the file. (Handlers can be shared amongst loggers, so they cannot be > closed explicitly). There is a certain risk as file.delete() can be a > very slow operation, though (ext3 [concurrently] deleting large files > for example). That's a solution I envisaged and rejected because of the constraints we have when running in the ReferenceHandler thread. I don't think it would be appropriate to close a Handler in that thread. I'm leaning towards suggesting that the LogManager should hold a strong reference on the loggers for which a Handler is explicitly configured in the configuration file. It would ensure that these loggers are still around when reset() is called. best regards, -- daniel > > Stanimir > > > > On Thu, Oct 9, 2014 at 4:59 PM, Daniel Fuchs > wrote: > > Thanks Jason. > > I wonder if that may be another issue. Interesting. I'll see if I > can work out a test case > for that tomorrow. With the test case provided in the bug - tested > on 7, 8, and 9, > the only file that remained at the end was 'log' (which is as it > should be - and I ran > the test case several times with each JDK) - which lets me think > that maybe the > issue was different. > > Now what you describe looks indeed like a bug that should still be > present > in the code base. I didn't think about that scenario, thanks for > pointing it out! > If i can write a reproducer (which should not be too difficult), it > will be a good > incentive to attempt a fix :-) > > Thanks again, > > -- daniel > > > On 10/9/14 9:56 PM, Jason Mehrens wrote: > > Daniel, > > > The evaluation on this bug is not quite correct. What is going > on here is the child logger is garbage collected which makes the > FileHandler unreachable from the LogManager$Cleaner which would > have closed the attached FileHandler. In the example, there is > no hard reference that escapes the 'execute' method. Prior to > fixing JDK-6274920: JDK logger holds strong reference to > java.util.logging.Logger instances, the LogManager$Cleaner would > have deleted the lock file on shutdown. Now that the loggers > are GC'able, one possible fix would be change the > FileHandler.locks static field to Map where > the key is the file name and the value is the FileHandler that > is open. Then in the LogManager$Cleaner could close any entries > in that map after LogManager.reset() is executed. > > > Jason > > > From jason_mehrens at hotmail.com Fri Oct 10 14:13:01 2014 From: jason_mehrens at hotmail.com (Jason Mehrens) Date: Fri, 10 Oct 2014 09:13:01 -0500 Subject: JDK-6774110 lock file is not deleted when child logger is used In-Reply-To: <5437A95D.4050806@oracle.com> References: <5436F73F.5050102@oracle.com> , <5437A95D.4050806@oracle.com> Message-ID: Hi Daniel, Stanimir, Closing the Handler is the main goal which takes care of the lock files. As far as a strong reference to the logger you don't need that. What you need to do is store a reference to the Logger.handlers List in the LogManager$LoggerWeakRef and reap the handlers inside of dispose. Now the only other issue is if one handler has been added to multiple loggers which could close a handler early. That is so uncommon I don't think it is worth the effort to correct. The caller can just fix the code to use a strong reference. Jason ---------------------------------------- > Date: Fri, 10 Oct 2014 11:39:41 +0200 > From: daniel.fuchs at oracle.com > To: stanimir at riflexo.com > CC: jason_mehrens at hotmail.com; core-libs-dev at openjdk.java.net > Subject: Re: JDK-6774110 lock file is not deleted when child logger is used > > Hi Stanimir, Jason, > > On 10/10/14 10:02, Stanimir Simeonoff wrote: >> Hi, >> >> LogManager.reset() should invoke a package private method to delete all >> lock files. However, that would require holding the FileHandler.locks >> monitor during the resetting of FileHandlers, not just the deletion >> process. Something like that, plus new PrivilegedAction(). >> static void deleteAllLocks(){ >> synchronized(locks){ >> for (String file : locks) new File(file).delete(); >> locks.clear(); >> } >> } > > There's more than the deletion of the lock file unfortunately. I believe > the handlers should be properly closed. A handler with an XMLFormatter > for instance needs to write the tail of the file. > > >> Alternatively the deletion could just be part of the Cleaner >> shutdownhook with another sun.misc.Cleaner per FileHandler that deletes >> the file. (Handlers can be shared amongst loggers, so they cannot be >> closed explicitly). There is a certain risk as file.delete() can be a >> very slow operation, though (ext3 [concurrently] deleting large files >> for example). > > That's a solution I envisaged and rejected because of the constraints > we have when running in the ReferenceHandler thread. I don't think it > would be appropriate to close a Handler in that thread. > > I'm leaning towards suggesting that the LogManager should hold a strong > reference on the loggers for which a Handler is explicitly > configured in the configuration file. It would ensure that > these loggers are still around when reset() is called. > > best regards, > > -- daniel > >> >> Stanimir >> >> >> >> On Thu, Oct 9, 2014 at 4:59 PM, Daniel Fuchs > > wrote: >> >> Thanks Jason. >> >> I wonder if that may be another issue. Interesting. I'll see if I >> can work out a test case >> for that tomorrow. With the test case provided in the bug - tested >> on 7, 8, and 9, >> the only file that remained at the end was 'log' (which is as it >> should be - and I ran >> the test case several times with each JDK) - which lets me think >> that maybe the >> issue was different. >> >> Now what you describe looks indeed like a bug that should still be >> present >> in the code base. I didn't think about that scenario, thanks for >> pointing it out! >> If i can write a reproducer (which should not be too difficult), it >> will be a good >> incentive to attempt a fix :-) >> >> Thanks again, >> >> -- daniel >> >> >> On 10/9/14 9:56 PM, Jason Mehrens wrote: >> >> Daniel, >> >> >> The evaluation on this bug is not quite correct. What is going >> on here is the child logger is garbage collected which makes the >> FileHandler unreachable from the LogManager$Cleaner which would >> have closed the attached FileHandler. In the example, there is >> no hard reference that escapes the 'execute' method. Prior to >> fixing JDK-6274920: JDK logger holds strong reference to >> java.util.logging.Logger instances, the LogManager$Cleaner would >> have deleted the lock file on shutdown. Now that the loggers >> are GC'able, one possible fix would be change the >> FileHandler.locks static field to Map where >> the key is the file name and the value is the FileHandler that >> is open. Then in the LogManager$Cleaner could close any entries >> in that map after LogManager.reset() is executed. >> >> >> Jason >> >> >> > From daniel.fuchs at oracle.com Fri Oct 10 14:17:43 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 10 Oct 2014 16:17:43 +0200 Subject: JDK-6774110 lock file is not deleted when child logger is used In-Reply-To: References: <5436F73F.5050102@oracle.com> Message-ID: <5437EA87.4050209@oracle.com> Hi, I have logged https://bugs.openjdk.java.net/browse/JDK-8060132. I will start a new thread for discussing this issue. best regards, -- daniel On 10/10/14 10:02, Stanimir Simeonoff wrote: > Hi, > > LogManager.reset() should invoke a package private method to delete all > lock files. However, that would require holding the FileHandler.locks > monitor during the resetting of FileHandlers, not just the deletion > process. Something like that, plus new PrivilegedAction(). > static void deleteAllLocks(){ > synchronized(locks){ > for (String file : locks) new File(file).delete(); > locks.clear(); > } > } > Alternatively the deletion could just be part of the Cleaner > shutdownhook with another sun.misc.Cleaner per FileHandler that deletes > the file. (Handlers can be shared amongst loggers, so they cannot be > closed explicitly). There is a certain risk as file.delete() can be a > very slow operation, though (ext3 [concurrently] deleting large files > for example). > > Stanimir > > > > On Thu, Oct 9, 2014 at 4:59 PM, Daniel Fuchs > wrote: > > Thanks Jason. > > I wonder if that may be another issue. Interesting. I'll see if I > can work out a test case > for that tomorrow. With the test case provided in the bug - tested > on 7, 8, and 9, > the only file that remained at the end was 'log' (which is as it > should be - and I ran > the test case several times with each JDK) - which lets me think > that maybe the > issue was different. > > Now what you describe looks indeed like a bug that should still be > present > in the code base. I didn't think about that scenario, thanks for > pointing it out! > If i can write a reproducer (which should not be too difficult), it > will be a good > incentive to attempt a fix :-) > > Thanks again, > > -- daniel > > > On 10/9/14 9:56 PM, Jason Mehrens wrote: > > Daniel, > > > The evaluation on this bug is not quite correct. What is going > on here is the child logger is garbage collected which makes the > FileHandler unreachable from the LogManager$Cleaner which would > have closed the attached FileHandler. In the example, there is > no hard reference that escapes the 'execute' method. Prior to > fixing JDK-6274920: JDK logger holds strong reference to > java.util.logging.Logger instances, the LogManager$Cleaner would > have deleted the lock file on shutdown. Now that the loggers > are GC'able, one possible fix would be change the > FileHandler.locks static field to Map where > the key is the file name and the value is the FileHandler that > is open. Then in the LogManager$Cleaner could close any entries > in that map after LogManager.reset() is executed. > > > Jason > > > From daniel.fuchs at oracle.com Fri Oct 10 14:36:21 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 10 Oct 2014 16:36:21 +0200 Subject: JDK-6774110 lock file is not deleted when child logger is used In-Reply-To: References: <5436F73F.5050102@oracle.com> , <5437A95D.4050806@oracle.com> Message-ID: <5437EEE5.7070206@oracle.com> On 10/10/14 16:13, Jason Mehrens wrote: > Hi Daniel, Stanimir, > > > Closing the Handler is the main goal which takes care of the lock files. As far as a strong reference to the logger you don't need that. What you need to do is store a reference to the Logger.handlers List in the LogManager$LoggerWeakRef and reap the handlers inside of dispose. Hi Jason, I discounted the idea because the same handler could be added to different loggers (though not from the configuration). Oh - that's what you're saying just below :-) > Now the only other issue is if one handler has been added to multiple loggers which could close a handler early. That is so uncommon I don't think it is worth the effort to correct. The caller can just fix the code to use a strong reference. I believe that keeping a reference on the loggers for which a handler is created from the configuration file might be less risky. After all - that's how it works for the root logger. Hmmm... That's probably going to force me to evaluate and fix (at least partly) https://bugs.openjdk.java.net/browse/JDK-8033661 as well... best regards -- daniel > > > Jason > > > ---------------------------------------- >> Date: Fri, 10 Oct 2014 11:39:41 +0200 >> From: daniel.fuchs at oracle.com >> To: stanimir at riflexo.com >> CC: jason_mehrens at hotmail.com; core-libs-dev at openjdk.java.net >> Subject: Re: JDK-6774110 lock file is not deleted when child logger is used >> >> Hi Stanimir, Jason, >> >> On 10/10/14 10:02, Stanimir Simeonoff wrote: >>> Hi, >>> >>> LogManager.reset() should invoke a package private method to delete all >>> lock files. However, that would require holding the FileHandler.locks >>> monitor during the resetting of FileHandlers, not just the deletion >>> process. Something like that, plus new PrivilegedAction(). >>> static void deleteAllLocks(){ >>> synchronized(locks){ >>> for (String file : locks) new File(file).delete(); >>> locks.clear(); >>> } >>> } >> >> There's more than the deletion of the lock file unfortunately. I believe >> the handlers should be properly closed. A handler with an XMLFormatter >> for instance needs to write the tail of the file. >> >> >>> Alternatively the deletion could just be part of the Cleaner >>> shutdownhook with another sun.misc.Cleaner per FileHandler that deletes >>> the file. (Handlers can be shared amongst loggers, so they cannot be >>> closed explicitly). There is a certain risk as file.delete() can be a >>> very slow operation, though (ext3 [concurrently] deleting large files >>> for example). >> >> That's a solution I envisaged and rejected because of the constraints >> we have when running in the ReferenceHandler thread. I don't think it >> would be appropriate to close a Handler in that thread. >> >> I'm leaning towards suggesting that the LogManager should hold a strong >> reference on the loggers for which a Handler is explicitly >> configured in the configuration file. It would ensure that >> these loggers are still around when reset() is called. >> >> best regards, >> >> -- daniel >> >>> >>> Stanimir >>> >>> >>> >>> On Thu, Oct 9, 2014 at 4:59 PM, Daniel Fuchs >> > wrote: >>> >>> Thanks Jason. >>> >>> I wonder if that may be another issue. Interesting. I'll see if I >>> can work out a test case >>> for that tomorrow. With the test case provided in the bug - tested >>> on 7, 8, and 9, >>> the only file that remained at the end was 'log' (which is as it >>> should be - and I ran >>> the test case several times with each JDK) - which lets me think >>> that maybe the >>> issue was different. >>> >>> Now what you describe looks indeed like a bug that should still be >>> present >>> in the code base. I didn't think about that scenario, thanks for >>> pointing it out! >>> If i can write a reproducer (which should not be too difficult), it >>> will be a good >>> incentive to attempt a fix :-) >>> >>> Thanks again, >>> >>> -- daniel >>> >>> >>> On 10/9/14 9:56 PM, Jason Mehrens wrote: >>> >>> Daniel, >>> >>> >>> The evaluation on this bug is not quite correct. What is going >>> on here is the child logger is garbage collected which makes the >>> FileHandler unreachable from the LogManager$Cleaner which would >>> have closed the attached FileHandler. In the example, there is >>> no hard reference that escapes the 'execute' method. Prior to >>> fixing JDK-6274920: JDK logger holds strong reference to >>> java.util.logging.Logger instances, the LogManager$Cleaner would >>> have deleted the lock file on shutdown. Now that the loggers >>> are GC'able, one possible fix would be change the >>> FileHandler.locks static field to Map where >>> the key is the file name and the value is the FileHandler that >>> is open. Then in the LogManager$Cleaner could close any entries >>> in that map after LogManager.reset() is executed. >>> >>> >>> Jason >>> >>> >>> >> From stanimir at riflexo.com Fri Oct 10 14:36:54 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Fri, 10 Oct 2014 17:36:54 +0300 Subject: JDK-6774110 lock file is not deleted when child logger is used In-Reply-To: References: <5436F73F.5050102@oracle.com> <5437A95D.4050806@oracle.com> Message-ID: On Fri, Oct 10, 2014 at 5:13 PM, Jason Mehrens wrote: > Hi Daniel, Stanimir, > > > Closing the Handler is the main goal which takes care of the lock files. > As far as a strong reference to the logger you don't need that. What you > need to do is store a reference to the Logger.handlers List in the > LogManager$LoggerWeakRef and reap the handlers inside of dispose. > > > Now the only other issue is if one handler has been added to multiple > loggers which could close a handler early. That is so uncommon I don't > think it is worth the effort to correct. The caller can just fix the code > to use a strong reference. > > > Actually we have framework that uses shared handlers quite liberally (like writing lots of stuff in a common file) but it also keeps strong references to any logger configured. The framework doesn't use the properties file but a custom xml-based config. My point is that: shared handlers may not be that uncommon and the change may break existing code as any shared handler could be prematurely closed. The Handler automatic closure remains problematic as they don't have a defined lifecycle. close() should be invoked after there are no references and it requires calling a potentially overridden method. It can be carried by PhantomReference+WeakRefence combo, though. > > ---------------------------------------- > > Date: Fri, 10 Oct 2014 11:39:41 +0200 > > From: daniel.fuchs at oracle.com > > To: stanimir at riflexo.com > > CC: jason_mehrens at hotmail.com; core-libs-dev at openjdk.java.net > > Subject: Re: JDK-6774110 lock file is not deleted when child logger is > used > > > > Hi Stanimir, Jason, > > > > On 10/10/14 10:02, Stanimir Simeonoff wrote: > >> Hi, > >> > >> LogManager.reset() should invoke a package private method to delete all > >> lock files. However, that would require holding the FileHandler.locks > >> monitor during the resetting of FileHandlers, not just the deletion > >> process. Something like that, plus new PrivilegedAction(). > >> static void deleteAllLocks(){ > >> synchronized(locks){ > >> for (String file : locks) new File(file).delete(); > >> locks.clear(); > >> } > >> } > > > > There's more than the deletion of the lock file unfortunately. I believe > > the handlers should be properly closed. A handler with an XMLFormatter > > for instance needs to write the tail of the file. > > > > > >> Alternatively the deletion could just be part of the Cleaner > >> shutdownhook with another sun.misc.Cleaner per FileHandler that deletes > >> the file. (Handlers can be shared amongst loggers, so they cannot be > >> closed explicitly). There is a certain risk as file.delete() can be a > >> very slow operation, though (ext3 [concurrently] deleting large files > >> for example). > > > > That's a solution I envisaged and rejected because of the constraints > > we have when running in the ReferenceHandler thread. I don't think it > > would be appropriate to close a Handler in that thread. > > > > I'm leaning towards suggesting that the LogManager should hold a strong > > reference on the loggers for which a Handler is explicitly > > configured in the configuration file. It would ensure that > > these loggers are still around when reset() is called. > > > > best regards, > > > > -- daniel > > > >> > >> Stanimir > >> > >> > >> > >> On Thu, Oct 9, 2014 at 4:59 PM, Daniel Fuchs >> > wrote: > >> > >> Thanks Jason. > >> > >> I wonder if that may be another issue. Interesting. I'll see if I > >> can work out a test case > >> for that tomorrow. With the test case provided in the bug - tested > >> on 7, 8, and 9, > >> the only file that remained at the end was 'log' (which is as it > >> should be - and I ran > >> the test case several times with each JDK) - which lets me think > >> that maybe the > >> issue was different. > >> > >> Now what you describe looks indeed like a bug that should still be > >> present > >> in the code base. I didn't think about that scenario, thanks for > >> pointing it out! > >> If i can write a reproducer (which should not be too difficult), it > >> will be a good > >> incentive to attempt a fix :-) > >> > >> Thanks again, > >> > >> -- daniel > >> > >> > >> On 10/9/14 9:56 PM, Jason Mehrens wrote: > >> > >> Daniel, > >> > >> > >> The evaluation on this bug is not quite correct. What is going > >> on here is the child logger is garbage collected which makes the > >> FileHandler unreachable from the LogManager$Cleaner which would > >> have closed the attached FileHandler. In the example, there is > >> no hard reference that escapes the 'execute' method. Prior to > >> fixing JDK-6274920: JDK logger holds strong reference to > >> java.util.logging.Logger instances, the LogManager$Cleaner would > >> have deleted the lock file on shutdown. Now that the loggers > >> are GC'able, one possible fix would be change the > >> FileHandler.locks static field to Map where > >> the key is the file name and the value is the FileHandler that > >> is open. Then in the LogManager$Cleaner could close any entries > >> in that map after LogManager.reset() is executed. > >> > >> > >> Jason > >> > >> > >> > > > From daniel.fuchs at oracle.com Fri Oct 10 14:44:19 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 10 Oct 2014 16:44:19 +0200 Subject: JDK-6774110 lock file is not deleted when child logger is used In-Reply-To: References: <5436F73F.5050102@oracle.com> <5437A95D.4050806@oracle.com> Message-ID: <5437F0C3.9070905@oracle.com> On 10/10/14 16:36, Stanimir Simeonoff wrote: > The Handler automatic closure remains problematic as they don't have a > defined lifecycle. close() should be invoked after there are no > references and it requires calling a potentially overridden method. It > can be carried by PhantomReference+WeakRefence combo, though. I agree. However we can't use sun.misc.Cleaner for that, and it's not clear were we could/should poll() the reference queue in order to close handler. Somehow I feel that closing handlers *created by the configuration* *in the configuration reset* might be the safest route. best regards, -- daniel From daniel.fuchs at oracle.com Fri Oct 10 14:51:20 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 10 Oct 2014 16:51:20 +0200 Subject: RFR: 8060132: Handlers configured on abstract nodes in logging.properties are not always properly closed Message-ID: <5437F268.9020600@oracle.com> Hi, Please find below a possible fix for: 8060132: Handlers configured on abstract nodes in logging.properties are not always properly closed https://bugs.openjdk.java.net/browse/JDK-8060132 webrev: http://cr.openjdk.java.net/~dfuchs/webrev_8060132/webrev.00/ Other options have been discussed in this other email thread: Subject: JDK-6774110 lock file is not deleted when child logger is used http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029038.html best regards, -- daniel From vladimir.x.ivanov at oracle.com Fri Oct 10 15:06:12 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Fri, 10 Oct 2014 19:06:12 +0400 Subject: [9] Review request : JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <54364AFC.5040101@oracle.com> References: <54353903.4000406@oracle.com> <54353B2E.8000409@oracle.com> <54354C4D.8020308@oracle.com> <54357385.7060102@oracle.com> <54364AFC.5040101@oracle.com> Message-ID: <5437F5E4.3080606@oracle.com> Looks good. Best regards, Vladimir Ivanov On 10/9/14, 12:44 PM, Konstantin Shefov wrote: > Hi, > > I have updated the webrev to take into account the JDK 9 new feature > with segmented code cache. > http://cr.openjdk.java.net/~kshefov/8058733/webrev.02 > > Please, review. > > -Konstantin > > On 08.10.2014 21:25, Joe Darcy wrote: >> Hello, >> >> I approve this change going into jdk9/dev contingent on the failing >> tests passing as modified. >> >> Thanks, >> >> -Joe >> >> On 10/8/2014 7:38 AM, Konstantin Shefov wrote: >>> Daniel, >>> Thanks for your comment >>> >>> Here is the updated webrev: >>> http://cr.openjdk.java.net/~kshefov/8058733/webrev.01 >>> >>> -Konstantin >>> >>> On 08.10.2014 17:25, Daniel Fuchs wrote: >>>> Hi Konstantin, >>>> >>>> I'm not qualified as a (R)eviewer for changes in this area, >>>> but I believe you can do: >>>> >>>> HotSpotDiagnosticMXBean mbean = >>>> ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); >>>> >>>> to get a handle on the MBean. You don't need to go through >>>> the MBeanServer and newPlatformMXBeanProxy stuff... >>>> >>>> best regards, >>>> >>>> -- daniel >>>> >>>> On 08/10/14 15:15, Konstantin Shefov wrote: >>>>> Hello, >>>>> >>>>> Please review the test bug fix >>>>> https://bugs.openjdk.java.net/browse/JDK-8058733 >>>>> Webrev is http://cr.openjdk.java.net/~kshefov/8058733/webrev.00/ >>>>> >>>>> Thanks >>>>> >>>>> -Konstantin >>>> >>> >> > From stanimir at riflexo.com Fri Oct 10 15:10:11 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Fri, 10 Oct 2014 18:10:11 +0300 Subject: RFR: 8060132: Handlers configured on abstract nodes in logging.properties are not always properly closed In-Reply-To: <5437F268.9020600@oracle.com> References: <5437F268.9020600@oracle.com> Message-ID: persistentLoggers should be cleared on reset(), imo. Also using "count" and then "for in" to loop over an array looks a bit ugly, should be just "for (int i=0; i wrote: > Hi, > > Please find below a possible fix for: > > 8060132: Handlers configured on abstract nodes in logging.properties are > not always properly closed > https://bugs.openjdk.java.net/browse/JDK-8060132 > > webrev: http://cr.openjdk.java.net/~dfuchs/webrev_8060132/webrev.00/ > > Other options have been discussed in this other email thread: > > Subject: JDK-6774110 lock file is not deleted when child logger is used > http://mail.openjdk.java.net/pipermail/core-libs-dev/2014- > October/029038.html > > best regards, > > -- daniel > From claes.redestad at oracle.com Fri Oct 10 15:10:35 2014 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 10 Oct 2014 17:10:35 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package Message-ID: <5437F6EB.4080506@oracle.com> Hi all, please review this patch which attempts to clean up synchronization and improve scalability when defining and getting java.lang.Package objects. webrev: http://cr.openjdk.java.net/~redestad/8060130/webrev.02/ bug: https://bugs.openjdk.java.net/browse/JDK-8060130 Testing: jtreg, UTE vm.parallel_class_loading.testlist, various benchmarks Torturing the retrieval code with a simple microbenchmark[1] shows that the existing code could cause bottlenecks, but also that the proposed patch works slightly faster even in uncontended cases: Benchmark Mode Samples Score Score error Units baseline, 1 thread: o.s.SimpleBench.getClassPackage thrpt 10 11.621 0.618 ops/us o.s.SimpleBench.getPackage thrpt 10 41.754 3.381 ops/us o.s.SimpleBench.getPackages thrpt 10 0.009 0.000 ops/us baseline, 2 threads: o.s.SimpleBench.getClassPackage thrpt 10 7.884 1.977 ops/us o.s.SimpleBench.getPackage thrpt 10 17.013 8.079 ops/us o.s.SimpleBench.getPackages thrpt 10 0.004 0.001 ops/us patch applied, 1 thread: o.s.SimpleBench.getClassPackage thrpt 10 13.519 0.170 ops/us o.s.SimpleBench.getPackage thrpt 10 59.999 0.988 ops/us o.s.SimpleBench.getPackages thrpt 10 0.019 0.001 ops/us patch applied, 2 threads: o.s.SimpleBench.getClassPackage thrpt 10 19.181 3.688 ops/us o.s.SimpleBench.getPackage thrpt 10 79.708 31.220 ops/us o.s.SimpleBench.getPackages thrpt 10 0.025 0.006 ops/us /Claes [1] package org.sample; import org.openjdk.jmh.annotations.*; @State(Scope.Thread) public class SimpleBench { @Benchmark public Package[] getPackages() { return Package.getPackages(); } @Benchmark public Package getClassPackage() { return this.getClass().getPackage(); } @Benchmark public Package getPackage() { return Package.getPackage("java.util.zip"); } } From stanimir at riflexo.com Fri Oct 10 15:12:07 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Fri, 10 Oct 2014 18:12:07 +0300 Subject: RFR: 8060132: Handlers configured on abstract nodes in logging.properties are not always properly closed In-Reply-To: References: <5437F268.9020600@oracle.com> Message-ID: Please disregard the remark about "count", as any exception would make the use of the index variable incorrect. Stanimir On Fri, Oct 10, 2014 at 6:10 PM, Stanimir Simeonoff wrote: > persistentLoggers should be cleared on reset(), imo. > > Also using "count" and then "for in" to loop over an array looks a bit > ugly, should be just "for (int i=0; i className = names[i];..} > Calling the class name 'word' is weird as well. (I do understand that's > not new but it's a good time to get it straight). > > Cheers > Stanimir > > > On Fri, Oct 10, 2014 at 5:51 PM, Daniel Fuchs > wrote: > >> Hi, >> >> Please find below a possible fix for: >> >> 8060132: Handlers configured on abstract nodes in logging.properties are >> not always properly closed >> https://bugs.openjdk.java.net/browse/JDK-8060132 >> >> webrev: http://cr.openjdk.java.net/~dfuchs/webrev_8060132/webrev.00/ >> >> Other options have been discussed in this other email thread: >> >> Subject: JDK-6774110 lock file is not deleted when child logger is used >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2014- >> October/029038.html >> >> best regards, >> >> -- daniel >> > > From sean.coffey at oracle.com Fri Oct 10 15:14:45 2014 From: sean.coffey at oracle.com (=?UTF-8?B?U2XDoW4gQ29mZmV5?=) Date: Fri, 10 Oct 2014 16:14:45 +0100 Subject: [8u40] Request for approval and review : 8058695: [TESTBUG] Reinvokers with arity >253 can't be cached In-Reply-To: <5437A195.6050200@oracle.com> References: <5437A195.6050200@oracle.com> Message-ID: <5437F7E5.2010900@oracle.com> This was already approved Konstantin : http://mail.openjdk.java.net/pipermail/jdk8u-dev/2014-October/002118.html If it's a clean import (patch wise) then - there's no need for a separate review. If there was changes to the 8u patch (apart from modular path name changes) then please get a review also. regards, Sean. On 10/10/14 10:06, Konstantin Shefov wrote: > Hello, > > Please review and approve the backport of the test bug fix to 8u40 > > The bug: https://bugs.openjdk.java.net/browse/JDK-8058695 > The webrev: http://cr.openjdk.java.net/~kshefov/8058695/8u-dev/webrev.00 > > Thanks > > -Konstantin From david.holmes at oracle.com Fri Oct 10 15:22:15 2014 From: david.holmes at oracle.com (David Holmes) Date: Sat, 11 Oct 2014 01:22:15 +1000 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <5437F6EB.4080506@oracle.com> References: <5437F6EB.4080506@oracle.com> Message-ID: <5437F9A7.1020503@oracle.com> Hi Claes, On 11/10/2014 1:10 AM, Claes Redestad wrote: > Hi all, > > please review this patch which attempts to clean up synchronization and > improve scalability when defining and getting java.lang.Package objects. Is this a real problem or a theoretical one? I've not previously heard of getting Package objects as being critical. ConcurrentHashMap improves the contended case but if we aren't normally contended then it will degrade performance. How does this perform on real code? I'm also wondering how this impacts the initialization order of the VM as we need a lot more classes to be loaded and initialized when the first Package is created. Thanks, David > webrev: http://cr.openjdk.java.net/~redestad/8060130/webrev.02/ > bug: https://bugs.openjdk.java.net/browse/JDK-8060130 > > Testing: jtreg, UTE vm.parallel_class_loading.testlist, various benchmarks > > Torturing the retrieval code with a simple microbenchmark[1] shows that > the existing code > could cause bottlenecks, but also that the proposed patch works slightly > faster even in > uncontended cases: > > Benchmark Mode Samples Score Score error Units > baseline, 1 thread: > o.s.SimpleBench.getClassPackage thrpt 10 11.621 0.618 > ops/us > o.s.SimpleBench.getPackage thrpt 10 41.754 3.381 > ops/us > o.s.SimpleBench.getPackages thrpt 10 0.009 0.000 > ops/us > > baseline, 2 threads: > o.s.SimpleBench.getClassPackage thrpt 10 7.884 1.977 > ops/us > o.s.SimpleBench.getPackage thrpt 10 17.013 8.079 > ops/us > o.s.SimpleBench.getPackages thrpt 10 0.004 0.001 > ops/us > > patch applied, 1 thread: > o.s.SimpleBench.getClassPackage thrpt 10 13.519 0.170 > ops/us > o.s.SimpleBench.getPackage thrpt 10 59.999 0.988 > ops/us > o.s.SimpleBench.getPackages thrpt 10 0.019 0.001 > ops/us > > patch applied, 2 threads: > o.s.SimpleBench.getClassPackage thrpt 10 19.181 3.688 > ops/us > o.s.SimpleBench.getPackage thrpt 10 79.708 31.220 > ops/us > o.s.SimpleBench.getPackages thrpt 10 0.025 0.006 > ops/us > > /Claes > > [1] > package org.sample; > > import org.openjdk.jmh.annotations.*; > > @State(Scope.Thread) > public class SimpleBench { > > @Benchmark > public Package[] getPackages() { > return Package.getPackages(); > } > > @Benchmark > public Package getClassPackage() { > return this.getClass().getPackage(); > } > > @Benchmark > public Package getPackage() { > return Package.getPackage("java.util.zip"); > } > } > From chris.hegarty at oracle.com Fri Oct 10 15:29:58 2014 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Fri, 10 Oct 2014 16:29:58 +0100 Subject: RFR [9] - 8060052: FutureTask; fix underflow when timeout = Long.MIN_VALUE Message-ID: <5437FB76.3070709@oracle.com> This is a formal review request for pulling the latest FutureTask from the 166 CVS. Webrev: http://cr.openjdk.java.net/~chegar/8060052/webrev.00/webrev/ The most significant issue being addresses is that task.get(Long.MIN_VALUE, NANOSECONDS) does not timeout for a really really long time, when it should throw TimeoutException almost immediately. There is some other refactoring around consistent usage of Unsafe. I took the liberty of adding a trivial test to give addition coverage in OpenJDK, but there is a TCK test in the 166 CVS that exercises this, and in fact the sync'ing of that test into the JCK 9 ea is what promoted this RFR. -Chris. From daniel.fuchs at oracle.com Fri Oct 10 15:39:55 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 10 Oct 2014 17:39:55 +0200 Subject: RFR: 8060132: Handlers configured on abstract nodes in logging.properties are not always properly closed In-Reply-To: References: <5437F268.9020600@oracle.com> Message-ID: <5437FDCB.30803@oracle.com> On 10/10/14 17:10, Stanimir Simeonoff wrote: > persistentLoggers should be cleared on reset(), imo. Yes - I was wondering about that too, it's a bit tricky to get it right (WRT MT-safety) :-(. > Also using "count" and then "for in" to loop over an array looks a bit > ugly, should be just "for (int i=0; i className = names[i];..} I wanted to add the logger only if at least one handler was successfully created and added, so 'count' is not necessarily equals to 'i'. > Calling the class name 'word' is weird as well. (I do understand that's > not new but it's a good time to get it straight). Agreed. http://cr.openjdk.java.net/~dfuchs/webrev_8060132/webrev.01 best regards, and thanks for all the valuable inputs & comment from you and Jason - I really appreciate it :-) -- daniel > > Cheers > Stanimir > > > On Fri, Oct 10, 2014 at 5:51 PM, Daniel Fuchs > wrote: > > Hi, > > Please find below a possible fix for: > > 8060132: Handlers configured on abstract nodes in logging.properties > are not always properly closed > https://bugs.openjdk.java.net/__browse/JDK-8060132 > > > webrev: > http://cr.openjdk.java.net/~__dfuchs/webrev_8060132/webrev.__00/ > > > Other options have been discussed in this other email thread: > > Subject: JDK-6774110 lock file is not deleted when child logger is used > http://mail.openjdk.java.net/__pipermail/core-libs-dev/2014-__October/029038.html > > > best regards, > > -- daniel > > From claes.redestad at oracle.com Fri Oct 10 16:06:37 2014 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 10 Oct 2014 18:06:37 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <5437F9A7.1020503@oracle.com> References: <5437F6EB.4080506@oracle.com> <5437F9A7.1020503@oracle.com> Message-ID: <5438040D.5010000@oracle.com> Hi David! On 10/10/2014 05:22 PM, David Holmes wrote: > Hi Claes, > > On 11/10/2014 1:10 AM, Claes Redestad wrote: >> Hi all, >> >> please review this patch which attempts to clean up synchronization and >> improve scalability when defining and getting java.lang.Package objects. > > Is this a real problem or a theoretical one? Deadlocks in getPackage() have historically caused issues (https://bugs.openjdk.java.net/browse/JDK-7001933), so contention can happen. Still somewhat theoretical, though. > I've not previously heard of getting Package objects as being > critical. ConcurrentHashMap improves the contended case but if we > aren't normally contended then it will degrade performance. How does > this perform on real code? Experiments (like the trivial microbenchmark below) indicate this improves performance even in uncontended cases, which can probably be explained by the removal of explicit synchronization in favor of volatile reads inside CHM. I've run a number of larger benchmarks mostly to ensure there are no unexpected regressions, but not found a case where this patch has a significant impact. There's a small footprint win in effect by merging two maps in java.lang.Package and not saving ancestral entries in the ClassLoader packages map which shows up on some footprint measures and might have more impact when scaling up to larger apps. > > I'm also wondering how this impacts the initialization order of the VM > as we need a lot more classes to be loaded and initialized when the > first Package is created. Since this is a concern, I've ran a number of internal startup benchmarks but not found the changes to have any statistical significant startup impact in either direction. Since ConcurrentHashMap is already in use by any parallel capable java.lang.ClassLoader, java.lang.Thread etc, it would seem it'll already be loaded and initialized early. /Claes > > Thanks, > David > >> webrev: http://cr.openjdk.java.net/~redestad/8060130/webrev.02/ >> bug: https://bugs.openjdk.java.net/browse/JDK-8060130 >> >> Testing: jtreg, UTE vm.parallel_class_loading.testlist, various >> benchmarks >> >> Torturing the retrieval code with a simple microbenchmark[1] shows that >> the existing code >> could cause bottlenecks, but also that the proposed patch works slightly >> faster even in >> uncontended cases: >> >> Benchmark Mode Samples Score Score error >> Units >> baseline, 1 thread: >> o.s.SimpleBench.getClassPackage thrpt 10 11.621 0.618 >> ops/us >> o.s.SimpleBench.getPackage thrpt 10 41.754 3.381 >> ops/us >> o.s.SimpleBench.getPackages thrpt 10 0.009 0.000 >> ops/us >> >> baseline, 2 threads: >> o.s.SimpleBench.getClassPackage thrpt 10 7.884 1.977 >> ops/us >> o.s.SimpleBench.getPackage thrpt 10 17.013 8.079 >> ops/us >> o.s.SimpleBench.getPackages thrpt 10 0.004 0.001 >> ops/us >> >> patch applied, 1 thread: >> o.s.SimpleBench.getClassPackage thrpt 10 13.519 0.170 >> ops/us >> o.s.SimpleBench.getPackage thrpt 10 59.999 0.988 >> ops/us >> o.s.SimpleBench.getPackages thrpt 10 0.019 0.001 >> ops/us >> >> patch applied, 2 threads: >> o.s.SimpleBench.getClassPackage thrpt 10 19.181 3.688 >> ops/us >> o.s.SimpleBench.getPackage thrpt 10 79.708 31.220 >> ops/us >> o.s.SimpleBench.getPackages thrpt 10 0.025 0.006 >> ops/us >> >> /Claes >> >> [1] >> package org.sample; >> >> import org.openjdk.jmh.annotations.*; >> >> @State(Scope.Thread) >> public class SimpleBench { >> >> @Benchmark >> public Package[] getPackages() { >> return Package.getPackages(); >> } >> >> @Benchmark >> public Package getClassPackage() { >> return this.getClass().getPackage(); >> } >> >> @Benchmark >> public Package getPackage() { >> return Package.getPackage("java.util.zip"); >> } >> } >> From konstantin.shefov at oracle.com Fri Oct 10 17:31:02 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Fri, 10 Oct 2014 21:31:02 +0400 Subject: [9] Review request : JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <5437F5E4.3080606@oracle.com> References: <54353903.4000406@oracle.com> <54353B2E.8000409@oracle.com> <54354C4D.8020308@oracle.com> <54357385.7060102@oracle.com> <54364AFC.5040101@oracle.com> <5437F5E4.3080606@oracle.com> Message-ID: <543817D6.3060706@oracle.com> Thanks for reviewing! Pushed. -Konstantin 10.10.2014 19:06, Vladimir Ivanov ?????: > Looks good. > > Best regards, > Vladimir Ivanov > > On 10/9/14, 12:44 PM, Konstantin Shefov wrote: >> Hi, >> >> I have updated the webrev to take into account the JDK 9 new feature >> with segmented code cache. >> http://cr.openjdk.java.net/~kshefov/8058733/webrev.02 >> >> Please, review. >> >> -Konstantin >> >> On 08.10.2014 21:25, Joe Darcy wrote: >>> Hello, >>> >>> I approve this change going into jdk9/dev contingent on the failing >>> tests passing as modified. >>> >>> Thanks, >>> >>> -Joe >>> >>> On 10/8/2014 7:38 AM, Konstantin Shefov wrote: >>>> Daniel, >>>> Thanks for your comment >>>> >>>> Here is the updated webrev: >>>> http://cr.openjdk.java.net/~kshefov/8058733/webrev.01 >>>> >>>> -Konstantin >>>> >>>> On 08.10.2014 17:25, Daniel Fuchs wrote: >>>>> Hi Konstantin, >>>>> >>>>> I'm not qualified as a (R)eviewer for changes in this area, >>>>> but I believe you can do: >>>>> >>>>> HotSpotDiagnosticMXBean mbean = >>>>> ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); >>>>> >>>>> to get a handle on the MBean. You don't need to go through >>>>> the MBeanServer and newPlatformMXBeanProxy stuff... >>>>> >>>>> best regards, >>>>> >>>>> -- daniel >>>>> >>>>> On 08/10/14 15:15, Konstantin Shefov wrote: >>>>>> Hello, >>>>>> >>>>>> Please review the test bug fix >>>>>> https://bugs.openjdk.java.net/browse/JDK-8058733 >>>>>> Webrev is http://cr.openjdk.java.net/~kshefov/8058733/webrev.00/ >>>>>> >>>>>> Thanks >>>>>> >>>>>> -Konstantin >>>>> >>>> >>> >> From martinrb at google.com Fri Oct 10 17:40:11 2014 From: martinrb at google.com (Martin Buchholz) Date: Fri, 10 Oct 2014 10:40:11 -0700 Subject: RFR [9] - 8060052: FutureTask; fix underflow when timeout = Long.MIN_VALUE In-Reply-To: <5437FB76.3070709@oracle.com> References: <5437FB76.3070709@oracle.com> Message-ID: Thanks and approved! Seems suitable for a backport to 8u if you want to do that. Personally I would not add the openjdk test, but use noreg-jck, but up to you. Your test is certainly more focused on the bug fix than our jsr166 tck test. On Fri, Oct 10, 2014 at 8:29 AM, Chris Hegarty wrote: > This is a formal review request for pulling the latest FutureTask from the > 166 CVS. > > Webrev: > http://cr.openjdk.java.net/~chegar/8060052/webrev.00/webrev/ > > The most significant issue being addresses is that > task.get(Long.MIN_VALUE, NANOSECONDS) does not timeout for a really really > long time, when it should throw TimeoutException almost immediately. There > is some other refactoring around consistent usage of Unsafe. > > I took the liberty of adding a trivial test to give addition coverage in > OpenJDK, but there is a TCK test in the 166 CVS that exercises this, and in > fact the sync'ing of that test into the JCK 9 ea is what promoted this RFR. > > -Chris. > From jason_mehrens at hotmail.com Fri Oct 10 17:52:43 2014 From: jason_mehrens at hotmail.com (Jason Mehrens) Date: Fri, 10 Oct 2014 12:52:43 -0500 Subject: RFR: 8060132: Handlers configured on abstract nodes in logging.properties are not always properly closed In-Reply-To: <5437FDCB.30803@oracle.com> References: <5437F268.9020600@oracle.com>, , <5437FDCB.30803@oracle.com> Message-ID: Daniel, Looks good. As always, thanks for fixing this. Jason ---------------------------------------- > Date: Fri, 10 Oct 2014 17:39:55 +0200 > From: daniel.fuchs at oracle.com > To: stanimir at riflexo.com; core-libs-dev at openjdk.java.net > CC: jason_mehrens at hotmail.com > Subject: Re: RFR: 8060132: Handlers configured on abstract nodes in logging.properties are not always properly closed > > On 10/10/14 17:10, Stanimir Simeonoff wrote: >> persistentLoggers should be cleared on reset(), imo. > > Yes - I was wondering about that too, it's a bit tricky to > get it right (WRT MT-safety) :-(. > >> Also using "count" and then "for in" to loop over an array looks a bit >> ugly, should be just "for (int i=0; i> className = names[i];..} > > I wanted to add the logger only if at least one handler was > successfully created and added, so 'count' is not necessarily > equals to 'i'. > >> Calling the class name 'word' is weird as well. (I do understand that's >> not new but it's a good time to get it straight). > > Agreed. > > http://cr.openjdk.java.net/~dfuchs/webrev_8060132/webrev.01 > > best regards, and thanks for all the valuable inputs & comment from > you and Jason - I really appreciate it :-) > > -- daniel > >> >> Cheers >> Stanimir >> >> >> On Fri, Oct 10, 2014 at 5:51 PM, Daniel Fuchs > > wrote: >> >> Hi, >> >> Please find below a possible fix for: >> >> 8060132: Handlers configured on abstract nodes in logging.properties >> are not always properly closed >> https://bugs.openjdk.java.net/__browse/JDK-8060132 >> >> >> webrev: >> http://cr.openjdk.java.net/~__dfuchs/webrev_8060132/webrev.__00/ >> >> >> Other options have been discussed in this other email thread: >> >> Subject: JDK-6774110 lock file is not deleted when child logger is used >> http://mail.openjdk.java.net/__pipermail/core-libs-dev/2014-__October/029038.html >> >> >> best regards, >> >> -- daniel >> >> > From vladimir.x.ivanov at oracle.com Fri Oct 10 19:08:00 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Fri, 10 Oct 2014 23:08:00 +0400 Subject: [9] [8u40] RFR (M): 8059877: GWT branch frequencies pollution due to LF sharing Message-ID: <54382E90.7040105@oracle.com> http://cr.openjdk.java.net/~vlivanov/8059877/webrev.00/ https://bugs.openjdk.java.net/browse/JDK-8059877 LambdaForm sharing introduces profile pollution in compiled LambdaForms. The most serious consequence is inlining distortion, which severely degrade peak performance. The main victim is guardWithTest (GWT) combinator. Before LambdaForm sharing, inlining in GWT was affected by 2 aspects: - branch frequencies: never-taken branch is skipped; - target & fallback method handles (corresponding LFs: compiled vs interpreted): if method handle has been invoked < COMPILE_THRESHOLD times, LambdaForm.vmentry points to LF interpreter which is marked w/ @DontInline. LambdaForm sharing breaks both aspects: - sharing of GWT LambdaForm pollutes branch profile; - sharing of LambdaForms used in target & fallback pollutes invocation counters. I experimented w/ VM API to guide JIT-compiler using profiling information gathered on LambdaForm level [1], but decided to take safer route for now (8u40). JIT-compiler control approach looks promising, but I need more time to get rid of some performance artifacts it suffers from. The proposed fix is to mimic behavior of fully customized LambdaForms. When GWT is created, both target & fallback method handles are wrapped in a special reinoker, which blocks inlining (@DontInline on reinvoker's compiled LambdaForm). Once a wrapper is invoked more that DONT_INLINE_THRESHOLD times, it's LambdaForm is replaced with a regular reinvoker, which is fully transparent for the JIT and it inlines smoothly. The downside of the chosen approach is that LambdaForm.updateForm() doesn't guarantee that all places where stale LambaForm is used see the update. If it is already part of some nmethod, it won't be invalidated and recompiled, but will be kept as is. It shouldn't be a problem, since DONT_INLINE_THRESHOLD is expected to be pretty low (~30), so only very rarely executed branches are affected. The fix significantly improves peak performance w/ full LF sharing (USE_LF_EDITOR=true). Octane/nashorn results [2] for: (1) USE_LF_EDITOR=false DONT_INLINE_THRESHOLD=0 (default for 8u40&9) (2) USE_LF_EDITOR=true DONT_INLINE_THRESHOLD=0 (default for 8u40&9) (3) USE_LF_EDITOR=true DONT_INLINE_THRESHOLD=30 (fixed version) (1) & (2) correspond to default configurations (partial & full LF sharing respectively). (3) is the fixed version. The fix recovers peak performance for: * Crypto: ~255ms -> ~12ms; * DeltaBlue: ~40ms -> ~2ms; * Raytracer: ~62ms -> ~7ms; * EarleyBoyer: ~160ms -> ~22ms; * NavierStokes: ~17ms -> ~13ms; 2 subbenchmarks (Box2D & Gbemu) still has some regressions, but it's much better now: Box2D: ~48ms -> ~61ms (w/o the fix: ~155ms) Gbemu: ~88ms -> ~116ms (w/o the fix: ~160ms) Testing: tests: jck (api/java_lang/invoke), jdk/java/lang/invoke, jdk/java/util/streams, octane configurations: -ea -esa -Xverify:all + COMPILE_THRESHOLD={0,30} + USE_LF_EDITOR={false,true} + DONT_INLINE_THRESHOLD={0,30} Thanks! Best regards, Vladimir Ivanov [1] http://cr.openjdk.java.net/~vlivanov/profiling/ [2] http://cr.openjdk.java.net/~vlivanov/8059877/octane.txt From forax at univ-mlv.fr Fri Oct 10 20:28:20 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Fri, 10 Oct 2014 22:28:20 +0200 Subject: [9] [8u40] RFR (M): 8059877: GWT branch frequencies pollution due to LF sharing In-Reply-To: <54382E90.7040105@oracle.com> References: <54382E90.7040105@oracle.com> Message-ID: <54384164.60509@univ-mlv.fr> Hi Vladimir, Why do you need getHistoricInt ? Is it because Unsafe.getInt() doesn't do any constant folding ? BTW, why getHistoricInt is named getHistoricInt ? cheers, R?mi On 10/10/2014 09:08 PM, Vladimir Ivanov wrote: > http://cr.openjdk.java.net/~vlivanov/8059877/webrev.00/ > https://bugs.openjdk.java.net/browse/JDK-8059877 > > LambdaForm sharing introduces profile pollution in compiled > LambdaForms. The most serious consequence is inlining distortion, > which severely degrade peak performance. The main victim is > guardWithTest (GWT) combinator. > > Before LambdaForm sharing, inlining in GWT was affected by 2 aspects: > - branch frequencies: never-taken branch is skipped; > - target & fallback method handles (corresponding LFs: compiled vs > interpreted): if method handle has been invoked < COMPILE_THRESHOLD > times, LambdaForm.vmentry points to LF interpreter which is marked w/ > @DontInline. > > LambdaForm sharing breaks both aspects: > - sharing of GWT LambdaForm pollutes branch profile; > - sharing of LambdaForms used in target & fallback pollutes > invocation counters. > > I experimented w/ VM API to guide JIT-compiler using profiling > information gathered on LambdaForm level [1], but decided to take > safer route for now (8u40). JIT-compiler control approach looks > promising, but I need more time to get rid of some performance > artifacts it suffers from. > > The proposed fix is to mimic behavior of fully customized LambdaForms. > When GWT is created, both target & fallback method handles are wrapped > in a special reinoker, which blocks inlining (@DontInline on > reinvoker's compiled LambdaForm). Once a wrapper is invoked more that > DONT_INLINE_THRESHOLD times, it's LambdaForm is replaced with a > regular reinvoker, which is fully transparent for the JIT and it > inlines smoothly. > > The downside of the chosen approach is that LambdaForm.updateForm() > doesn't guarantee that all places where stale LambaForm is used see > the update. If it is already part of some nmethod, it won't be > invalidated and recompiled, but will be kept as is. It shouldn't be a > problem, since DONT_INLINE_THRESHOLD is expected to be pretty low > (~30), so only very rarely executed branches are affected. > > The fix significantly improves peak performance w/ full LF sharing > (USE_LF_EDITOR=true). > > Octane/nashorn results [2] for: > (1) USE_LF_EDITOR=false DONT_INLINE_THRESHOLD=0 (default for 8u40&9) > (2) USE_LF_EDITOR=true DONT_INLINE_THRESHOLD=0 (default for 8u40&9) > (3) USE_LF_EDITOR=true DONT_INLINE_THRESHOLD=30 (fixed version) > > (1) & (2) correspond to default configurations (partial & full LF > sharing respectively). (3) is the fixed version. > > The fix recovers peak performance for: > * Crypto: ~255ms -> ~12ms; > * DeltaBlue: ~40ms -> ~2ms; > * Raytracer: ~62ms -> ~7ms; > * EarleyBoyer: ~160ms -> ~22ms; > * NavierStokes: ~17ms -> ~13ms; > > 2 subbenchmarks (Box2D & Gbemu) still has some regressions, but it's > much better now: > Box2D: ~48ms -> ~61ms (w/o the fix: ~155ms) > Gbemu: ~88ms -> ~116ms (w/o the fix: ~160ms) > > Testing: > tests: jck (api/java_lang/invoke), jdk/java/lang/invoke, > jdk/java/util/streams, octane > configurations: -ea -esa -Xverify:all > + COMPILE_THRESHOLD={0,30} + USE_LF_EDITOR={false,true} + > DONT_INLINE_THRESHOLD={0,30} > > Thanks! > > Best regards, > Vladimir Ivanov > > [1] http://cr.openjdk.java.net/~vlivanov/profiling/ > [2] http://cr.openjdk.java.net/~vlivanov/8059877/octane.txt > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev From vladimir.x.ivanov at oracle.com Fri Oct 10 20:42:27 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Sat, 11 Oct 2014 00:42:27 +0400 Subject: [9] [8u40] RFR (M): 8059877: GWT branch frequencies pollution due to LF sharing In-Reply-To: <54384164.60509@univ-mlv.fr> References: <54382E90.7040105@oracle.com> <54384164.60509@univ-mlv.fr> Message-ID: <543844B3.8040807@oracle.com> Remi, > Why do you need getHistoricInt ? > Is it because Unsafe.getInt() doesn't do any constant folding ? Exactly. I need a compile-time constant to feed it to the compiler to guide compilation. > BTW, why getHistoricInt is named getHistoricInt ? From application perspective, the call returns current or some of the previous values a field has. Best regards, Vladimir Ivanov > > cheers, > R?mi > > On 10/10/2014 09:08 PM, Vladimir Ivanov wrote: >> http://cr.openjdk.java.net/~vlivanov/8059877/webrev.00/ >> https://bugs.openjdk.java.net/browse/JDK-8059877 >> >> LambdaForm sharing introduces profile pollution in compiled >> LambdaForms. The most serious consequence is inlining distortion, >> which severely degrade peak performance. The main victim is >> guardWithTest (GWT) combinator. >> >> Before LambdaForm sharing, inlining in GWT was affected by 2 aspects: >> - branch frequencies: never-taken branch is skipped; >> - target & fallback method handles (corresponding LFs: compiled vs >> interpreted): if method handle has been invoked < COMPILE_THRESHOLD >> times, LambdaForm.vmentry points to LF interpreter which is marked w/ >> @DontInline. >> >> LambdaForm sharing breaks both aspects: >> - sharing of GWT LambdaForm pollutes branch profile; >> - sharing of LambdaForms used in target & fallback pollutes >> invocation counters. >> >> I experimented w/ VM API to guide JIT-compiler using profiling >> information gathered on LambdaForm level [1], but decided to take >> safer route for now (8u40). JIT-compiler control approach looks >> promising, but I need more time to get rid of some performance >> artifacts it suffers from. >> >> The proposed fix is to mimic behavior of fully customized LambdaForms. >> When GWT is created, both target & fallback method handles are wrapped >> in a special reinoker, which blocks inlining (@DontInline on >> reinvoker's compiled LambdaForm). Once a wrapper is invoked more that >> DONT_INLINE_THRESHOLD times, it's LambdaForm is replaced with a >> regular reinvoker, which is fully transparent for the JIT and it >> inlines smoothly. >> >> The downside of the chosen approach is that LambdaForm.updateForm() >> doesn't guarantee that all places where stale LambaForm is used see >> the update. If it is already part of some nmethod, it won't be >> invalidated and recompiled, but will be kept as is. It shouldn't be a >> problem, since DONT_INLINE_THRESHOLD is expected to be pretty low >> (~30), so only very rarely executed branches are affected. >> >> The fix significantly improves peak performance w/ full LF sharing >> (USE_LF_EDITOR=true). >> >> Octane/nashorn results [2] for: >> (1) USE_LF_EDITOR=false DONT_INLINE_THRESHOLD=0 (default for 8u40&9) >> (2) USE_LF_EDITOR=true DONT_INLINE_THRESHOLD=0 (default for 8u40&9) >> (3) USE_LF_EDITOR=true DONT_INLINE_THRESHOLD=30 (fixed version) >> >> (1) & (2) correspond to default configurations (partial & full LF >> sharing respectively). (3) is the fixed version. >> >> The fix recovers peak performance for: >> * Crypto: ~255ms -> ~12ms; >> * DeltaBlue: ~40ms -> ~2ms; >> * Raytracer: ~62ms -> ~7ms; >> * EarleyBoyer: ~160ms -> ~22ms; >> * NavierStokes: ~17ms -> ~13ms; >> >> 2 subbenchmarks (Box2D & Gbemu) still has some regressions, but it's >> much better now: >> Box2D: ~48ms -> ~61ms (w/o the fix: ~155ms) >> Gbemu: ~88ms -> ~116ms (w/o the fix: ~160ms) >> >> Testing: >> tests: jck (api/java_lang/invoke), jdk/java/lang/invoke, >> jdk/java/util/streams, octane >> configurations: -ea -esa -Xverify:all >> + COMPILE_THRESHOLD={0,30} + USE_LF_EDITOR={false,true} + >> DONT_INLINE_THRESHOLD={0,30} >> >> Thanks! >> >> Best regards, >> Vladimir Ivanov >> >> [1] http://cr.openjdk.java.net/~vlivanov/profiling/ >> [2] http://cr.openjdk.java.net/~vlivanov/8059877/octane.txt >> _______________________________________________ >> mlvm-dev mailing list >> mlvm-dev at openjdk.java.net >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From forax at univ-mlv.fr Fri Oct 10 21:20:49 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Fri, 10 Oct 2014 23:20:49 +0200 Subject: [9] [8u40] RFR (M): 8059877: GWT branch frequencies pollution due to LF sharing In-Reply-To: <543844B3.8040807@oracle.com> References: <54382E90.7040105@oracle.com> <54384164.60509@univ-mlv.fr> <543844B3.8040807@oracle.com> Message-ID: <54384DB1.3080004@univ-mlv.fr> On 10/10/2014 10:42 PM, Vladimir Ivanov wrote: > Remi, > >> Why do you need getHistoricInt ? >> Is it because Unsafe.getInt() doesn't do any constant folding ? > Exactly. I need a compile-time constant to feed it to the compiler to > guide compilation. > >> BTW, why getHistoricInt is named getHistoricInt ? > From application perspective, the call returns current or some of the > previous values a field has. thanks for your answer, I have another question about inOptimizer(), thinkint a little about it, if there is a code like if (unsafe.inOptimizer()) { ... } this code will always trigger a recompilation, at least once, because in the interpreter, the branch will never be evaluated and in the JIT, because inOptimizer will be rue, the JIT will insert a deopt instruction because the branch was never evaluated before. I wonder if this recompilation can be avoided or not ? > > Best regards, > Vladimir Ivanov regards, R?mi >> >> cheers, >> R?mi >> >> On 10/10/2014 09:08 PM, Vladimir Ivanov wrote: >>> http://cr.openjdk.java.net/~vlivanov/8059877/webrev.00/ >>> https://bugs.openjdk.java.net/browse/JDK-8059877 >>> >>> LambdaForm sharing introduces profile pollution in compiled >>> LambdaForms. The most serious consequence is inlining distortion, >>> which severely degrade peak performance. The main victim is >>> guardWithTest (GWT) combinator. >>> >>> Before LambdaForm sharing, inlining in GWT was affected by 2 aspects: >>> - branch frequencies: never-taken branch is skipped; >>> - target & fallback method handles (corresponding LFs: compiled vs >>> interpreted): if method handle has been invoked < COMPILE_THRESHOLD >>> times, LambdaForm.vmentry points to LF interpreter which is marked w/ >>> @DontInline. >>> >>> LambdaForm sharing breaks both aspects: >>> - sharing of GWT LambdaForm pollutes branch profile; >>> - sharing of LambdaForms used in target & fallback pollutes >>> invocation counters. >>> >>> I experimented w/ VM API to guide JIT-compiler using profiling >>> information gathered on LambdaForm level [1], but decided to take >>> safer route for now (8u40). JIT-compiler control approach looks >>> promising, but I need more time to get rid of some performance >>> artifacts it suffers from. >>> >>> The proposed fix is to mimic behavior of fully customized LambdaForms. >>> When GWT is created, both target & fallback method handles are wrapped >>> in a special reinoker, which blocks inlining (@DontInline on >>> reinvoker's compiled LambdaForm). Once a wrapper is invoked more that >>> DONT_INLINE_THRESHOLD times, it's LambdaForm is replaced with a >>> regular reinvoker, which is fully transparent for the JIT and it >>> inlines smoothly. >>> >>> The downside of the chosen approach is that LambdaForm.updateForm() >>> doesn't guarantee that all places where stale LambaForm is used see >>> the update. If it is already part of some nmethod, it won't be >>> invalidated and recompiled, but will be kept as is. It shouldn't be a >>> problem, since DONT_INLINE_THRESHOLD is expected to be pretty low >>> (~30), so only very rarely executed branches are affected. >>> >>> The fix significantly improves peak performance w/ full LF sharing >>> (USE_LF_EDITOR=true). >>> >>> Octane/nashorn results [2] for: >>> (1) USE_LF_EDITOR=false DONT_INLINE_THRESHOLD=0 (default for 8u40&9) >>> (2) USE_LF_EDITOR=true DONT_INLINE_THRESHOLD=0 (default for 8u40&9) >>> (3) USE_LF_EDITOR=true DONT_INLINE_THRESHOLD=30 (fixed version) >>> >>> (1) & (2) correspond to default configurations (partial & full LF >>> sharing respectively). (3) is the fixed version. >>> >>> The fix recovers peak performance for: >>> * Crypto: ~255ms -> ~12ms; >>> * DeltaBlue: ~40ms -> ~2ms; >>> * Raytracer: ~62ms -> ~7ms; >>> * EarleyBoyer: ~160ms -> ~22ms; >>> * NavierStokes: ~17ms -> ~13ms; >>> >>> 2 subbenchmarks (Box2D & Gbemu) still has some regressions, but it's >>> much better now: >>> Box2D: ~48ms -> ~61ms (w/o the fix: ~155ms) >>> Gbemu: ~88ms -> ~116ms (w/o the fix: ~160ms) >>> >>> Testing: >>> tests: jck (api/java_lang/invoke), jdk/java/lang/invoke, >>> jdk/java/util/streams, octane >>> configurations: -ea -esa -Xverify:all >>> + COMPILE_THRESHOLD={0,30} + USE_LF_EDITOR={false,true} + >>> DONT_INLINE_THRESHOLD={0,30} >>> >>> Thanks! >>> >>> Best regards, >>> Vladimir Ivanov >>> >>> [1] http://cr.openjdk.java.net/~vlivanov/profiling/ >>> [2] http://cr.openjdk.java.net/~vlivanov/8059877/octane.txt >>> _______________________________________________ >>> mlvm-dev mailing list >>> mlvm-dev at openjdk.java.net >>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev >> From mandy.chung at oracle.com Sat Oct 11 00:31:41 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Fri, 10 Oct 2014 17:31:41 -0700 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <5437F6EB.4080506@oracle.com> References: <5437F6EB.4080506@oracle.com> Message-ID: <54387A6D.90402@oracle.com> On 10/10/2014 8:10 AM, Claes Redestad wrote: > Hi all, > > please review this patch which attempts to clean up synchronization > and improve scalability when > defining and getting java.lang.Package objects. I agree with David that getting Package objects are not performance critical. On the other hand, the code defining/getting Packages is old and deserves some cleanup especially the synchronization part. If you run helloworld program, how does that change the list of loaded classes besides the new CachedManifest class? > > webrev: http://cr.openjdk.java.net/~redestad/8060130/webrev.02/ ClassLoader.java line 272: can you change the declared type as Map. definePackage throws IAE if there exists an existing package either in this class loader or one of its ancestors. - this change would not catch if two definePackage calls to define a package of the same name but with different spec version, title, etc concurrently. You may not be able to avoid synchronizing on packages for this case. move line 1623 to 1630 so that the declaration of map is closer to the assignment. Package.java line 557 there is a possibility that new Package[pkgs.size()] is not big enough and a new array would be created. As this method is not popularly used, it's okay if another array is created. line 563 and 565 can be merged line 570-575: do you think you can modify the private Package(String name, Manifest man, URL url, ClassLoader loader) constructor to take null Manifest and null url so that these lines can be folded into pkg = new Package(name, cachedManifest.getManifest(), cachedManifest.getURL(), null); I think CachedManifest class and the createCachedManifest method need some work. Perhaps we can have the CachedManifest constructor to obtain the URL. Each invalid fn will have one instance instead of NO_MANIFEST singleton but that should not happen as fn is the filename where the classes loaded from the bootclasspath. CachedManifest.url can then become final. line 587-601 would not be needed. Can we avoid line 606 and write the createCachedManifest method this way: if (!manifests.containsKey(fn)) { manifests.putIfAbsent(fn, new CachedManifest(fn)); } return manifests.get(fn); You may be able to further simplify CachedManifest and remove the resolved field by storing an empty Manifest when loadManifest returns null. That may help the private Package constructor not require any change to merge line 570-575 as my comment noted above. You will need to check there is any test to verify Package created with and without manifest. Do you mind making this change and tests (I realize it might be out of scope of this performance improvement you initially anticipated)? Mandy From john.r.rose at oracle.com Sat Oct 11 07:40:10 2014 From: john.r.rose at oracle.com (John Rose) Date: Sat, 11 Oct 2014 00:40:10 -0700 Subject: [9] [8u40] RFR (M): 8059877: GWT branch frequencies pollution due to LF sharing In-Reply-To: <54384DB1.3080004@univ-mlv.fr> References: <54382E90.7040105@oracle.com> <54384164.60509@univ-mlv.fr> <543844B3.8040807@oracle.com> <54384DB1.3080004@univ-mlv.fr> Message-ID: <3897F7F9-FB26-46D8-9543-27F55612001F@oracle.com> On Oct 10, 2014, at 2:20 PM, Remi Forax wrote: > I have another question about inOptimizer(), > thinkint a little about it, if there is a code like > if (unsafe.inOptimizer()) { > ... > } > > this code will always trigger a recompilation, at least once, because in the interpreter, the branch will never be evaluated and in the JIT, > because inOptimizer will be rue, the JIT will insert a deopt instruction because the branch was never evaluated before. > > I wonder if this recompilation can be avoided or not ? I think so. Being "in the optimizer" is not necessarily the same as being in compiled code. If the JIT were going to deoptimize immediately after an inOptimizer=true condition, then it wasn't really in the optimizer at that point, or (to split hairs) it was at the very edge of partially-optimized code just about to fall out of it. That's the reason we named it "inOptimizer" instead of "inCompiler". The JIT is free to evaluate it to false, if the path is not well optimized. The overall expectation is that as the code warms up, inOptimizer will go from false to true, eventually. ? John From Alan.Bateman at oracle.com Sat Oct 11 12:43:20 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Sat, 11 Oct 2014 13:43:20 +0100 Subject: RFR 8058855: Update java.util.zip tests to work with modular image In-Reply-To: <54362213.6070600@oracle.com> References: <543619FD.4040706@oracle.com> <54361BC3.9000408@oracle.com> <54362213.6070600@oracle.com> Message-ID: <543925E8.3050907@oracle.com> On 09/10/2014 06:50, Amy Lu wrote: > > Updated name "lib" to "testdir": > http://cr.openjdk.java.net/~weijun/8058855/webrev.01/ Thanks for taking this one, the updated version looks good to me too. -Alan From chris.hegarty at oracle.com Sat Oct 11 13:39:31 2014 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Sat, 11 Oct 2014 14:39:31 +0100 Subject: RFR [9] - 8060052: FutureTask; fix underflow when timeout = Long.MIN_VALUE In-Reply-To: References: <5437FB76.3070709@oracle.com> Message-ID: Thanks for the review Martin. Since this change may be backported to 8u, then I?ll keep the test, as the JCK8(a) may not contain the new TCK test from the 166 CVS. -Chris. On 10 Oct 2014, at 18:40, Martin Buchholz wrote: > Thanks and approved! > > Seems suitable for a backport to 8u if you want to do that. > > Personally I would not add the openjdk test, but use noreg-jck, but up to you. Your test is certainly more focused on the bug fix than our jsr166 tck test. > > On Fri, Oct 10, 2014 at 8:29 AM, Chris Hegarty wrote: > This is a formal review request for pulling the latest FutureTask from the 166 CVS. > > Webrev: > http://cr.openjdk.java.net/~chegar/8060052/webrev.00/webrev/ > > The most significant issue being addresses is that task.get(Long.MIN_VALUE, NANOSECONDS) does not timeout for a really really long time, when it should throw TimeoutException almost immediately. There is some other refactoring around consistent usage of Unsafe. > > I took the liberty of adding a trivial test to give addition coverage in OpenJDK, but there is a TCK test in the 166 CVS that exercises this, and in fact the sync'ing of that test into the JCK 9 ea is what promoted this RFR. > > -Chris. > From forax at univ-mlv.fr Sat Oct 11 15:17:29 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 11 Oct 2014 17:17:29 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <54387A6D.90402@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> Message-ID: <54394A09.3060703@univ-mlv.fr> Hi Mandy, On 10/11/2014 02:31 AM, Mandy Chung wrote: [...] > >> >> webrev: http://cr.openjdk.java.net/~redestad/8060130/webrev.02/ > > ClassLoader.java > line 272: can you change the declared type as Map. I think it's a bad idea, the class doesn't work if you replace the ConcurrentHashMap by any Map so declaring the field 'packages' as a Map seems wrong to me. At least, it should be a ConcurrentMap, but even with a ConcurrentMap, I think that the guarantee that in definePackage the call to putIfAbstent is amortized O(1) and not something like O(ln n) is important. Note that using interfaces instead of implementations is important in the signature of public or protected method, for a local variable or a private field, which are hidden, there is no real reason to use an interface. I understand that pedagogically having only one rule is appealing but from my own experience, this rule hide one of the corner stone of the OOP, encapsulation, so IMO the rule 'use an interface everywhere you can' does more harm than good because it offers a discorded version of the OO world. cheers, R?mi From stanimir at riflexo.com Sat Oct 11 15:45:01 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Sat, 11 Oct 2014 18:45:01 +0300 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <5437F6EB.4080506@oracle.com> References: <5437F6EB.4080506@oracle.com> Message-ID: The commented annotation in ClassLoader.java must be removed (line 268) // @GuardedBy("itself") Stanimir On Fri, Oct 10, 2014 at 6:10 PM, Claes Redestad wrote: > Hi all, > > please review this patch which attempts to clean up synchronization and > improve scalability when > defining and getting java.lang.Package objects. > > webrev: http://cr.openjdk.java.net/~redestad/8060130/webrev.02/ > bug: https://bugs.openjdk.java.net/browse/JDK-8060130 > > Testing: jtreg, UTE vm.parallel_class_loading.testlist, various benchmarks > > Torturing the retrieval code with a simple microbenchmark[1] shows that > the existing code > could cause bottlenecks, but also that the proposed patch works slightly > faster even in > uncontended cases: > > Benchmark Mode Samples Score Score error > Units > baseline, 1 thread: > o.s.SimpleBench.getClassPackage thrpt 10 11.621 0.618 > ops/us > o.s.SimpleBench.getPackage thrpt 10 41.754 3.381 > ops/us > o.s.SimpleBench.getPackages thrpt 10 0.009 0.000 > ops/us > > baseline, 2 threads: > o.s.SimpleBench.getClassPackage thrpt 10 7.884 1.977 > ops/us > o.s.SimpleBench.getPackage thrpt 10 17.013 8.079 > ops/us > o.s.SimpleBench.getPackages thrpt 10 0.004 0.001 > ops/us > > patch applied, 1 thread: > o.s.SimpleBench.getClassPackage thrpt 10 13.519 0.170 > ops/us > o.s.SimpleBench.getPackage thrpt 10 59.999 0.988 > ops/us > o.s.SimpleBench.getPackages thrpt 10 0.019 0.001 > ops/us > > patch applied, 2 threads: > o.s.SimpleBench.getClassPackage thrpt 10 19.181 3.688 > ops/us > o.s.SimpleBench.getPackage thrpt 10 79.708 31.220 > ops/us > o.s.SimpleBench.getPackages thrpt 10 0.025 0.006 > ops/us > > /Claes > > [1] > package org.sample; > > import org.openjdk.jmh.annotations.*; > > @State(Scope.Thread) > public class SimpleBench { > > @Benchmark > public Package[] getPackages() { > return Package.getPackages(); > } > > @Benchmark > public Package getClassPackage() { > return this.getClass().getPackage(); > } > > @Benchmark > public Package getPackage() { > return Package.getPackage("java.util.zip"); > } > } > > From mandy.chung at oracle.com Sat Oct 11 20:29:31 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Sat, 11 Oct 2014 13:29:31 -0700 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <54394A09.3060703@univ-mlv.fr> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <54394A09.3060703@univ-mlv.fr> Message-ID: <5439932B.7090503@oracle.com> On 10/11/2014 8:17 AM, Remi Forax wrote: > Hi Mandy, > > On 10/11/2014 02:31 AM, Mandy Chung wrote: > > [...] > >> >>> >>> webrev: http://cr.openjdk.java.net/~redestad/8060130/webrev.02/ >> >> ClassLoader.java >> line 272: can you change the declared type as Map. > > I think it's a bad idea, the class doesn't work if you replace the > ConcurrentHashMap by any Map > so declaring the field 'packages' as a Map seems wrong to me. > At least, it should be a ConcurrentMap, but even with a ConcurrentMap, > I think that the guarantee > that in definePackage the call to putIfAbstent is amortized O(1) and > not something like O(ln n) is important. > > Note that using interfaces instead of implementations is important in > the signature of public or protected method, for a local variable or a > private field, which are hidden, there is no real reason to use an > interface. I understand that pedagogically having only one rule is > appealing but from my own experience, this rule hide one of the corner > stone of the OOP, encapsulation, so IMO the rule 'use an interface > everywhere you can' does more harm than good because it offers a > discorded version of the OO world. Remi - thanks for catching this. After I sent the comment, I was pondering my suggestion (this specific one) was a bad idea. Declaring it as Map loses the significance that the implementation depends on the packages map being concurrently accessed. Agree. Mandy From forax at univ-mlv.fr Sat Oct 11 22:11:01 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Sun, 12 Oct 2014 00:11:01 +0200 Subject: [9] [8u40] RFR (M): 8059877: GWT branch frequencies pollution due to LF sharing In-Reply-To: <3897F7F9-FB26-46D8-9543-27F55612001F@oracle.com> References: <54382E90.7040105@oracle.com> <54384164.60509@univ-mlv.fr> <543844B3.8040807@oracle.com> <54384DB1.3080004@univ-mlv.fr> <3897F7F9-FB26-46D8-9543-27F55612001F@oracle.com> Message-ID: <5439AAF5.8010207@univ-mlv.fr> On 10/11/2014 09:40 AM, John Rose wrote: > On Oct 10, 2014, at 2:20 PM, Remi Forax wrote: > >> I have another question about inOptimizer(), >> thinkint a little about it, if there is a code like >> if (unsafe.inOptimizer()) { >> ... >> } >> >> this code will always trigger a recompilation, at least once, because in the interpreter, the branch will never be evaluated and in the JIT, >> because inOptimizer will be rue, the JIT will insert a deopt instruction because the branch was never evaluated before. >> >> I wonder if this recompilation can be avoided or not ? > I think so. Being "in the optimizer" is not necessarily the same as being in compiled code. If the JIT were going to deoptimize immediately after an inOptimizer=true condition, then it wasn't really in the optimizer at that point, or (to split hairs) it was at the very edge of partially-optimized code just about to fall out of it. > > That's the reason we named it "inOptimizer" instead of "inCompiler". The JIT is free to evaluate it to false, if the path is not well optimized. The overall expectation is that as the code warms up, inOptimizer will go from false to true, eventually. thanks for the explanation, my mind was not able to see past the proposed implementation. > > ? John R?mi From jeffhain at rocketmail.com Sat Oct 11 23:56:42 2014 From: jeffhain at rocketmail.com (Jeff Hain) Date: Sun, 12 Oct 2014 00:56:42 +0100 Subject: RFR [9] - 8060052: FutureTask; fix underflow when timeout = Long.MIN_VALUE In-Reply-To: <5437FB76.3070709@oracle.com> References: <5437FB76.3070709@oracle.com> Message-ID: <1413071802.93800.YahooMailNeo@web172401.mail.ir2.yahoo.com> Chris wrote: >Webrev: > http://cr.openjdk.java.net/~chegar/8060052/webrev.00/webrev/ An aside remark: Every time some nanos timeout needs to be kept track of, and that remaining time does not need to be returned, one could consider the timeout to be infinite (timed = false) above, say, Long.MAX_VALUE/2 (not Long.MAX_VALUE, because some (actual) durations might be subtracted from the specified timeout by intermediate treatments), to get a small (in absolute) but relatively noticeable performance boost on configurations where System.nanoTime() is slow. In the curent case, if not wanting to have System.nanoTime() calls, there is the get() method, but generic code might use get(long,TimeUnit) even for huge timeouts. Or maybe we don't want users to dangerously tinker around this hidden and huge threshold... -Jeff From claes.redestad at oracle.com Sun Oct 12 02:09:30 2014 From: claes.redestad at oracle.com (Claes Redestad) Date: Sun, 12 Oct 2014 04:09:30 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <54387A6D.90402@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> Message-ID: <5439E2DA.1040309@oracle.com> On 2014-10-11 02:31, Mandy Chung wrote: > > On 10/10/2014 8:10 AM, Claes Redestad wrote: >> Hi all, >> >> please review this patch which attempts to clean up synchronization >> and improve scalability when >> defining and getting java.lang.Package objects. > > I agree with David that getting Package objects are not performance > critical. On the other hand, the code defining/getting Packages is > old and deserves some cleanup especially the synchronization part. > > If you run helloworld program, how does that change the list of loaded > classes besides the new CachedManifest class? > >> >> webrev: http://cr.openjdk.java.net/~redestad/8060130/webrev.02/ > > ClassLoader.java > line 272: can you change the declared type as Map. Map misses the atomicity requirement of putIfAbsent, ConcurrentMap is OK but leaves some related questions open (why we can't add a null value, specifically). I'm glad it was brought up and discussed and will use ConcurrentHashMap for private fields unless there's a strong preference otherwise. > > definePackage throws IAE if there exists an existing package either > in this class loader or one of its ancestors. > - this change would not catch if two definePackage calls to define > a package of the same name but with different spec version, title, etc > concurrently. > > You may not be able to avoid synchronizing on packages for this case. Right, I was I think synchronization can still be avoided by throwing IAE if putIfAbsent doesn't return null: if (packages.putIfAbsent(name, pkg) != null) { throw new IllegalArgumentException(name); } return pkg; > > move line 1623 to 1630 so that the declaration of map is closer to > the assignment. Ok > > Package.java > > line 557 there is a possibility that new Package[pkgs.size()] is not > big enough and a new array would be created. As this method is not > popularly used, it's okay if another array is created. Yes, an unlikely race. > > line 563 and 565 can be merged > > line 570-575: do you think you can modify the private > Package(String name, Manifest man, URL url, ClassLoader loader) > constructor > to take null Manifest and null url so that these lines can be folded into > > pkg = new Package(name, cachedManifest.getManifest(), > cachedManifest.getURL(), null); I think I'll take your suggestion below and ensure cachedManifest and it's getManifest() never evaluate to null, which makes for a cleaner patch. There is some code duplication here with URLClassLoader#definePackage. Future cleanup? It would seem the ClassLoader argument in this ctor is always called with null. Remove? > > I think CachedManifest class and the createCachedManifest method need > some work. Perhaps we can have the CachedManifest constructor to > obtain the URL. > > Each invalid fn will have one instance instead of NO_MANIFEST singleton > but that should not happen as fn is the filename where the classes > loaded from the bootclasspath. CachedManifest.url can then become final. > > line 587-601 would not be needed. Can we avoid line 606 and write > the createCachedManifest method this way: > if (!manifests.containsKey(fn)) { > manifests.putIfAbsent(fn, new CachedManifest(fn)); > } > return manifests.get(fn); Yes. Looked a bit dangerous, but it seems we still maintain the necessary guarantees. > > You may be able to further simplify CachedManifest and remove the > resolved > field by storing an empty Manifest when loadManifest returns null. > That may help the private Package constructor not require any change > to merge line 570-575 as my comment noted above. Sure! Taking in all these suggestions as well as realizing a race could cause different Package to return from subsequent calls to Package.defineSystemPackage brings me to this: http://cr.openjdk.java.net/~redestad/8060130/webrev.03/ Now... How about a slightly alternative approach: instead of caching Manifests we could create and cache a Package - call it a prototype - then add a private constructor taking the package name and the "prototype" Package. The Package objects should come with a smaller footprint and have the added benefit of being effectively immutable. Does that sound like an improvement? > > You will need to check there is any test to verify Package created with > and without manifest. Do you mind making this change and tests (I > realize > it might be out of scope of this performance improvement you initially > anticipated)? I'll take a look at the current test coverage and give it some thought. Thanks! /Claes > > Mandy > From fuyou001 at gmail.com Sun Oct 12 10:02:33 2014 From: fuyou001 at gmail.com (fuyou) Date: Sun, 12 Oct 2014 18:02:33 +0800 Subject: why epoll consum sys usage,is normal? Message-ID: when I profile java application,find the epoll consum lots of sys usage step one ? I use systemtap script find the which thread consum cpu usgae,every second display one ,find these thread comm tid %user %kernel (of 15133 ticks) java 27965 0.00% 7.11% java 27743 0.00% 4.15% java 28177 0.00% 3.35% java 27902 0.00% 3.33% java 27964 0.00% 3.23% java 27929 0.00% 2.96% java 28205 0.00% 2.95% java 28203 0.00% 2.94% java 27863 0.00% 2.93% java 27581 0.00% 1.38% java 27586 0.00% 1.24% java 27588 0.00% 0.88% java 27905 0.00% 0.77% java 27954 0.00% 0.74% java 27945 0.00% 0.73% java 27911 0.00% 0.72% java 27946 0.00% 0.72% java 27910 0.00% 0.71% java 27938 0.00% 0.70% java 27962 0.00% 0.70% comm tid %user %kernel (of 457 ticks) java 27758 0.00% 11.15% java 27742 0.00% 10.06% java 27749 0.00% 9.84% java 27756 0.00% 8.75% java 27747 0.00% 8.31% java 27752 0.00% 8.31% java 27740 0.00% 6.34% java 27734 0.00% 6.34% java 27537 0.00% 3.06% java 27965 0.00% 2.84% java 27538 0.00% 2.18% java 27743 0.00% 1.31% java 27929 0.00% 1.31% java 28203 0.00% 1.09% java 27586 0.00% 1.09% java 27902 0.00% 0.87% java 27964 0.00% 0.87% java 28177 0.00% 0.87% java 28205 0.00% 0.65% java 27868 0.00% 0.65% comm tid %user %kernel (of 193 ticks) java 27863 0.00% 8.80% java 27965 0.00% 7.77% java 27964 0.00% 6.21% java 28177 0.00% 6.21% java 28203 0.00% 5.18% java 27929 0.00% 5.18% java 28205 0.00% 4.14% java 27902 0.00% 2.59% java 27615 0.00% 2.59% java 27590 0.00% 2.59% java 27743 0.00% 1.55% java 27762 0.00% 1.55% java 27775 0.00% 1.55% java 27776 0.00% 1.55% java 27767 0.00% 1.55% java 27794 0.00% 1.55% java 27731 0.00% 1.55% java 18362 0.00% 1.03% java 27828 0.00% 1.03% java 27747 0.00% 1.03% step two ?use jstack -l PID go get java stack step three : change the thread id to hex and find stack in java stack file the thread: >>> print(hex(27965)) 0x6d3d >>> print(hex(27758)) 0x6c6e >>> print(hex(27863)) 0x6cd7 >>> print(hex(27965)) 0x6d3d the jstacks [~]$ cat jstack_27523_2.txt |grep --color -A10 --color 0x6c6e "task-8" prio=10 tid=0x00007f76d7314000 nid=0x6c6e runnable [0x00000000471a0000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x000000076c5e9980> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025) at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:424) at io.netty.util.concurrent.SingleThreadEventExecutor.takeTask(SingleThreadEventExecutor.java:235) at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:34) at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) at java.lang.Thread.run(Thread.java:662) [ ~]$ cat jstack_27523_2.txt |grep --color -A10 --color 0x6cd7 "NETTYSERVER-WORKER-14-thread-1" prio=10 tid=0x00007f76d0052000 nid=0x6cd7 runnable [0x000000004da08000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69) - locked <0x000000076c436e58> (a io.netty.channel.nio.SelectedSelectionKeySet) - locked <0x000000076c2f0990> (a java.util.Collections$UnmodifiableSet) - locked <0x000000076c417140> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80) at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:618) [~]$ cat jstack_27523_2.txt |grep --color -A10 --color 0x6d3d "NETTYSERVER-WORKER-14-thread-5" prio=10 tid=0x00007f76d05fa000 nid=0x6d3d runnable [0x000000005204e000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69) - locked <0x000000076c2f5a20> (a io.netty.channel.nio.SelectedSelectionKeySet) - locked <0x000000076c3c9688> (a java.util.Collections$UnmodifiableSet) - locked <0x000000076c035a60> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80) at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:618) I also use systemtap to monitor epoll call every seconds pid | poll select epoll itimer futex nanosle signal| process 27523 | 0 0 380 0 10543 0 0| java the os is Red Hat Enterprise Linux Server release 5.7 2.6.32-el5.x86_64 the java verison java version "1.6.0_32" every seonds ,the epoll only 380 ervery seconds ,why epoll method consume lots sys,is normal? or how to check it is normal consum sys cpu usgae? thanks! -- ============================================= fuyou001 Best Regards From peter.levart at gmail.com Sun Oct 12 10:40:53 2014 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 12 Oct 2014 12:40:53 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <5439E2DA.1040309@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> Message-ID: <543A5AB5.8060600@gmail.com> On 10/12/2014 04:09 AM, Claes Redestad wrote: > Taking in all these suggestions as well as realizing a race could > cause different Package > to return from subsequent calls to Package.defineSystemPackage brings > me to this: > > http://cr.openjdk.java.net/~redestad/8060130/webrev.03/ > Hi Claes, Just some nits... - I think you're still using Map as the type of 'pkgs' and 'manifests' static fields in Package although they are CHMs at runtime. - To avoid unnecessary (multiple) reads from a volatile field, the following code in CachedManifest: 631 public Manifest getManifest() { 632 resolveManifest(); 633 return manifest; 634 } 635 636 private void resolveManifest() { 637 if (manifest != null || url == null) { 638 return; 639 } 640 synchronized(this) { 641 if (manifest == null) { 642 manifest = AccessController.doPrivileged(new PrivilegedAction() { 643 public Manifest run() { 644 return loadManifest(fileName); 645 } 646 }); 647 } 648 } 649 } could be written as: public Manifest getManifest() { if (url == null) return null; Manifest m = manifest; if (m != null) return m; synchronized (this) { if ((m = manifest) != null) return m; manifest = m = AccessControler.doPrivileged(....); return m; } } - It would be better to move loadManifest() into the CachedManifest class since it's only used there as a helper method (to avoid creating access bridges or having to declare it package-private instead) - well no, this doesn't help, since it's called from an anonymous inner PrivilegedAction subclass. What about just inlining it into the PrivilegeAction's run() method? I also wonder if the lazy loading of Manifest in CachedManifest is necessary. If you look at the only usage of CachedManifest.getManifest() method (in Package.defineSystemPackage()): CachedManifest cachedManifest = createCachedManifest(fn); pkgs.putIfAbsent(name, new Package(name, cachedManifest.getManifest(), cachedManifest.getURL())); ...you can see that getManifest() is called immediately after obtaining the CacheManifest. So there's no need for lazy loading. Loading the Manifest in CachedManifest constructor would be just fine. > Now... How about a slightly alternative approach: instead of caching > Manifests we could create > and cache a Package - call it a prototype - then add a private > constructor taking the > package name and the "prototype" Package. The Package objects should > come with a > smaller footprint and have the added benefit of being effectively > immutable. Does that > sound like an improvement? Or, call the prototype a 'CachedManifest' and Package just delegate methods to it. Well... A noble goal, but this space optimization would only pertain to system packages if changed only in ClassLoader/Package. You would still have to have "fat" Packages because other ClassLoaders define their Packages with the other Package constructor that doesn't take the Manifest file name (which would be used as a key to obtain a prototype), but use their own Manifest parsing (see URLClassLoader.definePackage()) ... There are just a couple of system packages. So you would have to also change the API between individual ClassLoader(s) and ClassLoader/Package (see ClassLoader.definePackage()) to optimize other non-system packages which outnumber system packages. There are not so many packages after all (compared to Class(es)). Regards, Peter From peter.levart at gmail.com Sun Oct 12 10:52:00 2014 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 12 Oct 2014 12:52:00 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543A5AB5.8060600@gmail.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543A5AB5.8060600@gmail.com> Message-ID: <543A5D50.7040707@gmail.com> On 10/12/2014 12:40 PM, Peter Levart wrote: > I also wonder if the lazy loading of Manifest in CachedManifest is > necessary. If you look at the only usage of > CachedManifest.getManifest() method (in Package.defineSystemPackage()): > > CachedManifest cachedManifest = createCachedManifest(fn); > pkgs.putIfAbsent(name, new Package(name, > cachedManifest.getManifest(), > cachedManifest.getURL())); > > ...you can see that getManifest() is called immediately after > obtaining the CacheManifest. So there's no need for lazy loading. > Loading the Manifest in CachedManifest constructor would be just fine. ..Ah, you can do that, yes, but then you have to use synchronization in createCachedManifest in order to avoid redundant concurrent loading of Manifest. And that would be a good thing since then you avoid concurrent resolving of fileName -> URL too in one go. Peter From peter.levart at gmail.com Sun Oct 12 11:02:44 2014 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 12 Oct 2014 13:02:44 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543A5D50.7040707@gmail.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543A5AB5.8060600@gmail.com> <543A5D50.7040707@gmail.com> Message-ID: <543A5FD4.2050606@gmail.com> On 10/12/2014 12:52 PM, Peter Levart wrote: > > On 10/12/2014 12:40 PM, Peter Levart wrote: >> I also wonder if the lazy loading of Manifest in CachedManifest is >> necessary. If you look at the only usage of >> CachedManifest.getManifest() method (in Package.defineSystemPackage()): >> >> CachedManifest cachedManifest = createCachedManifest(fn); >> pkgs.putIfAbsent(name, new Package(name, >> cachedManifest.getManifest(), >> cachedManifest.getURL())); >> >> ...you can see that getManifest() is called immediately after >> obtaining the CacheManifest. So there's no need for lazy loading. >> Loading the Manifest in CachedManifest constructor would be just fine. > > > ..Ah, you can do that, yes, but then you have to use synchronization > in createCachedManifest in order to avoid redundant concurrent loading > of Manifest. And that would be a good thing since then you avoid > concurrent resolving of fileName -> URL too in one go. > > Peter > Scrap that. I see now what you wanted to achieve. You wanted to avoid synchronization on a single monitor when loading manifests while avoiding multiple concurrent loading of same manifest. Lazy loading is fine than. Regards, Peter From ecki at zusammenkunft.net Mon Oct 13 01:24:41 2014 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Mon, 13 Oct 2014 03:24:41 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <54387A6D.90402@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> Message-ID: <20141013032441.00005433.ecki@zusammenkunft.net> Am Fri, 10 Oct 2014 17:31:41 -0700 schrieb Mandy Chung : > I agree with David that getting Package objects are not performance > critical. On the other hand, the code defining/getting Packages is > old and deserves some cleanup especially the synchronization part. Hmm.. isnt the package logic part of the ClassLoader (defineClass) especially around sealing and security manager? So it would be at least performance critical for startup time? Bernd From david.holmes at oracle.com Mon Oct 13 01:29:12 2014 From: david.holmes at oracle.com (David Holmes) Date: Mon, 13 Oct 2014 11:29:12 +1000 Subject: RFR 8058855: Update java.util.zip tests to work with modular image In-Reply-To: <54362213.6070600@oracle.com> References: <543619FD.4040706@oracle.com> <54361BC3.9000408@oracle.com> <54362213.6070600@oracle.com> Message-ID: <543B2AE8.4080806@oracle.com> On 9/10/2014 3:50 PM, Amy Lu wrote: > On 10/9/14, 1:23 PM, David Holmes wrote: >> Hi Amy, >> >> On 9/10/2014 3:15 PM, Amy Lu wrote: >>> Two java/util/zip tests use JDK rt.jar in test, this fix is to remove >>> this dependency from test because with a modular rt.jar and the other >>> JAR files in the JDK go away. >>> >>> bug: https://bugs.openjdk.java.net/browse/JDK-8058855 >>> webrev: http://cr.openjdk.java.net/~tyan/amylu/8058855/webrev.00/ >> >> test/java/util/zip/InterruptibleZip.java >> >> Where is input.jar coming from? > > It's an existing jar file in test dir. Is it copied-there/created-by some other part of the test? >> >> test/java/util/zip/ZipFile/FinalizeZipFile.java >> >> The File variable "lib" is no longer suitably named. > > Updated name "lib" to "testdir": > http://cr.openjdk.java.net/~weijun/8058855/webrev.01/ Thanks, David > Thanks, > Amy > > >> >> Cheers, >> David >> >>> Thanks, >>> Amy > From david.holmes at oracle.com Mon Oct 13 02:18:29 2014 From: david.holmes at oracle.com (David Holmes) Date: Mon, 13 Oct 2014 12:18:29 +1000 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <5439E2DA.1040309@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> Message-ID: <543B3675.2000802@oracle.com> Hi Claes, Looking at version three ... You seemed to have changed the caching strategy for Packages in the classloader. Previously a Package defined by a parent or the system would be updated in the current loader's Package map; but now you leave them separate so future lookups will always have to traverse the hierarchy. This doesn't seem like a performance gain. Looking at definePackage it seems both old and new code have serious race conditions due to a lack of atomicity when checking the parent/system packages. A package of the same name could be defined in the parent/system after definePackage has called getPackage - and we then end up with two same named Packages in different loaders. No comment on the manifest caching aspect - I'm not familiar enough with the existing code. On 12/10/2014 12:09 PM, Claes Redestad wrote: > On 2014-10-11 02:31, Mandy Chung wrote: >> >> On 10/10/2014 8:10 AM, Claes Redestad wrote: >>> Hi all, >>> >>> please review this patch which attempts to clean up synchronization >>> and improve scalability when >>> defining and getting java.lang.Package objects. >> >> I agree with David that getting Package objects are not performance >> critical. On the other hand, the code defining/getting Packages is >> old and deserves some cleanup especially the synchronization part. >> >> If you run helloworld program, how does that change the list of loaded >> classes besides the new CachedManifest class? >> >>> >>> webrev: http://cr.openjdk.java.net/~redestad/8060130/webrev.02/ >> >> ClassLoader.java >> line 272: can you change the declared type as Map. > > Map misses the atomicity requirement of putIfAbsent, ConcurrentMap is OK > but leaves some > related questions open (why we can't add a null value, specifically). > I'm glad it was brought up > and discussed and will use ConcurrentHashMap for private fields unless > there's a strong > preference otherwise. > >> >> definePackage throws IAE if there exists an existing package either >> in this class loader or one of its ancestors. >> - this change would not catch if two definePackage calls to define >> a package of the same name but with different spec version, title, etc >> concurrently. >> >> You may not be able to avoid synchronizing on packages for this case. > > Right, I was I think synchronization can still be avoided by throwing > IAE if > putIfAbsent doesn't return null: > > if (packages.putIfAbsent(name, pkg) != null) { > throw new IllegalArgumentException(name); > } > return pkg; > >> >> move line 1623 to 1630 so that the declaration of map is closer to >> the assignment. > > Ok > >> >> Package.java >> >> line 557 there is a possibility that new Package[pkgs.size()] is not >> big enough and a new array would be created. As this method is not >> popularly used, it's okay if another array is created. > > Yes, an unlikely race. > >> >> line 563 and 565 can be merged >> >> line 570-575: do you think you can modify the private >> Package(String name, Manifest man, URL url, ClassLoader loader) >> constructor >> to take null Manifest and null url so that these lines can be folded into >> >> pkg = new Package(name, cachedManifest.getManifest(), >> cachedManifest.getURL(), null); > > I think I'll take your suggestion below and ensure cachedManifest and > it's getManifest() > never evaluate to null, which makes for a cleaner patch. There is some > code duplication > here with URLClassLoader#definePackage. Future cleanup? > > It would seem the ClassLoader argument in this ctor is always called > with null. Remove? > >> >> I think CachedManifest class and the createCachedManifest method need >> some work. Perhaps we can have the CachedManifest constructor to >> obtain the URL. >> >> Each invalid fn will have one instance instead of NO_MANIFEST singleton >> but that should not happen as fn is the filename where the classes >> loaded from the bootclasspath. CachedManifest.url can then become final. >> >> line 587-601 would not be needed. Can we avoid line 606 and write >> the createCachedManifest method this way: >> if (!manifests.containsKey(fn)) { >> manifests.putIfAbsent(fn, new CachedManifest(fn)); >> } >> return manifests.get(fn); > > Yes. Looked a bit dangerous, but it seems we still maintain the > necessary guarantees. > >> >> You may be able to further simplify CachedManifest and remove the >> resolved >> field by storing an empty Manifest when loadManifest returns null. >> That may help the private Package constructor not require any change >> to merge line 570-575 as my comment noted above. > > Sure! Taking in all these suggestions as well as realizing a race could > cause different Package > to return from subsequent calls to Package.defineSystemPackage brings me > to this: > > http://cr.openjdk.java.net/~redestad/8060130/webrev.03/ > > Now... How about a slightly alternative approach: instead of caching > Manifests we could create > and cache a Package - call it a prototype - then add a private > constructor taking the > package name and the "prototype" Package. The Package objects should > come with a > smaller footprint and have the added benefit of being effectively > immutable. Does that > sound like an improvement? > >> >> You will need to check there is any test to verify Package created with >> and without manifest. Do you mind making this change and tests (I >> realize >> it might be out of scope of this performance improvement you initially >> anticipated)? > > I'll take a look at the current test coverage and give it some thought. > > Thanks! > > /Claes > >> >> Mandy >> > From amy.lu at oracle.com Mon Oct 13 03:08:02 2014 From: amy.lu at oracle.com (Amy Lu) Date: Mon, 13 Oct 2014 11:08:02 +0800 Subject: RFR 8058855: Update java.util.zip tests to work with modular image In-Reply-To: <543B2AE8.4080806@oracle.com> References: <543619FD.4040706@oracle.com> <54361BC3.9000408@oracle.com> <54362213.6070600@oracle.com> <543B2AE8.4080806@oracle.com> Message-ID: <543B4212.3030006@oracle.com> On 10/13/14, 9:29 AM, David Holmes wrote: > On 9/10/2014 3:50 PM, Amy Lu wrote: >> On 10/9/14, 1:23 PM, David Holmes wrote: >>> Hi Amy, >>> >>> On 9/10/2014 3:15 PM, Amy Lu wrote: >>>> Two java/util/zip tests use JDK rt.jar in test, this fix is to remove >>>> this dependency from test because with a modular rt.jar and the other >>>> JAR files in the JDK go away. >>>> >>>> bug: https://bugs.openjdk.java.net/browse/JDK-8058855 >>>> webrev: http://cr.openjdk.java.net/~tyan/amylu/8058855/webrev.00/ >>> >>> test/java/util/zip/InterruptibleZip.java >>> >>> Where is input.jar coming from? >> >> It's an existing jar file in test dir. > > Is it copied-there/created-by some other part of the test? No http://hg.openjdk.java.net/jdk9/dev/jdk/log/tip/test/java/util/zip/input.jar Thanks, Amy > >>> >>> test/java/util/zip/ZipFile/FinalizeZipFile.java >>> >>> The File variable "lib" is no longer suitably named. >> >> Updated name "lib" to "testdir": >> http://cr.openjdk.java.net/~weijun/8058855/webrev.01/ > > Thanks, > David > >> Thanks, >> Amy >> >> >>> >>> Cheers, >>> David >>> >>>> Thanks, >>>> Amy >> From david.holmes at oracle.com Mon Oct 13 03:33:54 2014 From: david.holmes at oracle.com (David Holmes) Date: Mon, 13 Oct 2014 13:33:54 +1000 Subject: RFR 8058855: Update java.util.zip tests to work with modular image In-Reply-To: <543B4212.3030006@oracle.com> References: <543619FD.4040706@oracle.com> <54361BC3.9000408@oracle.com> <54362213.6070600@oracle.com> <543B2AE8.4080806@oracle.com> <543B4212.3030006@oracle.com> Message-ID: <543B4822.3090904@oracle.com> On 13/10/2014 1:08 PM, Amy Lu wrote: > On 10/13/14, 9:29 AM, David Holmes wrote: >> On 9/10/2014 3:50 PM, Amy Lu wrote: >>> On 10/9/14, 1:23 PM, David Holmes wrote: >>>> Hi Amy, >>>> >>>> On 9/10/2014 3:15 PM, Amy Lu wrote: >>>>> Two java/util/zip tests use JDK rt.jar in test, this fix is to remove >>>>> this dependency from test because with a modular rt.jar and the other >>>>> JAR files in the JDK go away. >>>>> >>>>> bug: https://bugs.openjdk.java.net/browse/JDK-8058855 >>>>> webrev: http://cr.openjdk.java.net/~tyan/amylu/8058855/webrev.00/ >>>> >>>> test/java/util/zip/InterruptibleZip.java >>>> >>>> Where is input.jar coming from? >>> >>> It's an existing jar file in test dir. >> >> Is it copied-there/created-by some other part of the test? > > No > http://hg.openjdk.java.net/jdk9/dev/jdk/log/tip/test/java/util/zip/input.jar Thanks - I was looking in the wrong place. I was thinking that this: System.getProperty("test.src", ".") would return the top-level test directory, but it will return the actual source directory for the current test. David > Thanks, > Amy >> >>>> >>>> test/java/util/zip/ZipFile/FinalizeZipFile.java >>>> >>>> The File variable "lib" is no longer suitably named. >>> >>> Updated name "lib" to "testdir": >>> http://cr.openjdk.java.net/~weijun/8058855/webrev.01/ >> >> Thanks, >> David >> >>> Thanks, >>> Amy >>> >>> >>>> >>>> Cheers, >>>> David >>>> >>>>> Thanks, >>>>> Amy >>> > From amy.lu at oracle.com Mon Oct 13 03:38:17 2014 From: amy.lu at oracle.com (Amy Lu) Date: Mon, 13 Oct 2014 11:38:17 +0800 Subject: RFR 8058855: Update java.util.zip tests to work with modular image In-Reply-To: <543B4822.3090904@oracle.com> References: <543619FD.4040706@oracle.com> <54361BC3.9000408@oracle.com> <54362213.6070600@oracle.com> <543B2AE8.4080806@oracle.com> <543B4212.3030006@oracle.com> <543B4822.3090904@oracle.com> Message-ID: <543B4929.40304@oracle.com> Thank you David, Alan and Sherman for your review. And thank you Alan for sponsor this for me. Thanks, Amy On 10/13/14, 11:33 AM, David Holmes wrote: > On 13/10/2014 1:08 PM, Amy Lu wrote: >> On 10/13/14, 9:29 AM, David Holmes wrote: >>> On 9/10/2014 3:50 PM, Amy Lu wrote: >>>> On 10/9/14, 1:23 PM, David Holmes wrote: >>>>> Hi Amy, >>>>> >>>>> On 9/10/2014 3:15 PM, Amy Lu wrote: >>>>>> Two java/util/zip tests use JDK rt.jar in test, this fix is to >>>>>> remove >>>>>> this dependency from test because with a modular rt.jar and the >>>>>> other >>>>>> JAR files in the JDK go away. >>>>>> >>>>>> bug: https://bugs.openjdk.java.net/browse/JDK-8058855 >>>>>> webrev: http://cr.openjdk.java.net/~tyan/amylu/8058855/webrev.00/ >>>>> >>>>> test/java/util/zip/InterruptibleZip.java >>>>> >>>>> Where is input.jar coming from? >>>> >>>> It's an existing jar file in test dir. >>> >>> Is it copied-there/created-by some other part of the test? >> >> No >> http://hg.openjdk.java.net/jdk9/dev/jdk/log/tip/test/java/util/zip/input.jar >> > > Thanks - I was looking in the wrong place. I was thinking that this: > > System.getProperty("test.src", ".") > > would return the top-level test directory, but it will return the > actual source directory for the current test. > > David > >> Thanks, >> Amy >>> >>>>> >>>>> test/java/util/zip/ZipFile/FinalizeZipFile.java >>>>> >>>>> The File variable "lib" is no longer suitably named. >>>> >>>> Updated name "lib" to "testdir": >>>> http://cr.openjdk.java.net/~weijun/8058855/webrev.01/ >>> >>> Thanks, >>> David >>> >>>> Thanks, >>>> Amy >>>> >>>> >>>>> >>>>> Cheers, >>>>> David >>>>> >>>>>> Thanks, >>>>>> Amy >>>> >> From amy.lu at oracle.com Mon Oct 13 08:23:47 2014 From: amy.lu at oracle.com (Amy Lu) Date: Mon, 13 Oct 2014 16:23:47 +0800 Subject: RFR 8058854: Remove dependency on dt.jar from test/tools/jar/normalize/TestNormal.java Message-ID: <543B8C13.6020201@oracle.com> tools/jar/normalize/TestNormal.java use JDK dt.jar in test, this fix is to remove this dependency from test because with a modular dt.jar and the other JAR files in the JDK go away. bug: https://bugs.openjdk.java.net/browse/JDK-8058854 webrev: http://cr.openjdk.java.net/~tyan/amylu/8058854/webrev.00/ Thanks, Amy From Alan.Bateman at oracle.com Mon Oct 13 08:47:47 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 13 Oct 2014 09:47:47 +0100 Subject: RFR 8058854: Remove dependency on dt.jar from test/tools/jar/normalize/TestNormal.java In-Reply-To: <543B8C13.6020201@oracle.com> References: <543B8C13.6020201@oracle.com> Message-ID: <543B91B3.2080401@oracle.com> On 13/10/2014 09:23, Amy Lu wrote: > tools/jar/normalize/TestNormal.java use JDK dt.jar in test, this fix > is to remove this dependency from test because with a modular dt.jar > and the other JAR files in the JDK go away. > > bug: https://bugs.openjdk.java.net/browse/JDK-8058854 > webrev: http://cr.openjdk.java.net/~tyan/amylu/8058854/webrev.00/ I'm not sure about @library ../../pack200 and using the pack200 test support as it created a non-obvious dependency in the test tree. An alternative would be to move the test to the pack200 test directory as this test is about create JAR files that invariant to pack200 operations. -Alan. From chris.hegarty at oracle.com Mon Oct 13 08:57:01 2014 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Mon, 13 Oct 2014 09:57:01 +0100 Subject: RFR 8058854: Remove dependency on dt.jar from test/tools/jar/normalize/TestNormal.java In-Reply-To: <543B91B3.2080401@oracle.com> References: <543B8C13.6020201@oracle.com> <543B91B3.2080401@oracle.com> Message-ID: <543B93DD.8050002@oracle.com> I'm not sure that it matters, in the context of this test, but the jar file being created will now contain a much smaller number of entries than was previously being tested. I have a similar comment about the previous cleanup too. I wonder if we need functionality in the testlibrary to create relatively substantial jar files to test with? Or maybe the number of entries has no great impact on some tests. -Chris. On 13/10/14 09:47, Alan Bateman wrote: > On 13/10/2014 09:23, Amy Lu wrote: >> tools/jar/normalize/TestNormal.java use JDK dt.jar in test, this fix >> is to remove this dependency from test because with a modular dt.jar >> and the other JAR files in the JDK go away. >> >> bug: https://bugs.openjdk.java.net/browse/JDK-8058854 >> webrev: http://cr.openjdk.java.net/~tyan/amylu/8058854/webrev.00/ > I'm not sure about @library ../../pack200 and using the pack200 test > support as it created a non-obvious dependency in the test tree. An > alternative would be to move the test to the pack200 test directory as > this test is about create JAR files that invariant to pack200 operations. > > -Alan. From peter.levart at gmail.com Mon Oct 13 09:04:49 2014 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 13 Oct 2014 11:04:49 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543B3675.2000802@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543B3675.2000802@oracle.com> Message-ID: <543B95B1.2090806@gmail.com> On 10/13/2014 04:18 AM, David Holmes wrote: > Hi Claes, > > Looking at version three ... > > You seemed to have changed the caching strategy for Packages in the > classloader. Previously a Package defined by a parent or the system > would be updated in the current loader's Package map; but now you > leave them separate so future lookups will always have to traverse the > hierarchy. This doesn't seem like a performance gain. > > Looking at definePackage it seems both old and new code have serious > race conditions due to a lack of atomicity when checking the > parent/system packages. A package of the same name could be defined in > the parent/system after definePackage has called getPackage - and we > then end up with two same named Packages in different loaders. Hmm... It's hard to come up with a consistent behaviour which would prevent parent / child ClassLoaders from defining classes in the same package. You can't prevent child prom defining a package before you know that parent has a package with the same name and you cant prevent a parent from defining a package if child has already defined a package with the same name. Packages are rarely backed by a resource which could be used to identify their existence. It's odd that the package that is returned from Class.getPackage() depends on the order of class loading. For example, if user code declares a "public class javax.swing.JNotSwing {}", then the following program: public class Test { public static void main(String[] args) { JNotSwing c1 = new JNotSwing(); Package p1 = c1.getClass().getPackage(); JComponent c2 = new JLabel(); Package p2 = c2.getClass().getPackage(); JComponent c3 = new JPanel(); Package p3 = c3.getClass().getPackage(); System.out.println("p1: " + p1); System.out.println("p2: " + p2); System.out.println("p3: " + p3); } } Prints: p1: package javax.swing p2: package javax.swing, Java Platform API Specification, version 1.9 p3: package javax.swing, Java Platform API Specification, version 1.9 Now if the order of class loading is changed: public class Test { public static void main(String[] args) { JComponent c2 = new JLabel(); Package p2 = c2.getClass().getPackage(); JNotSwing c1 = new JNotSwing(); Package p1 = c1.getClass().getPackage(); JComponent c3 = new JPanel(); Package p3 = c3.getClass().getPackage(); System.out.println("p1: " + p1); System.out.println("p2: " + p2); System.out.println("p3: " + p3); } } The following is printed: p1: package javax.swing, Java Platform API Specification, version 1.9 p2: package javax.swing, Java Platform API Specification, version 1.9 p3: package javax.swing, Java Platform API Specification, version 1.9 So reliable "sealed" packages can only exist if they are defined in-advance or at least one class from a particular sealed package is loaded by the authoritative ClassLoader before a child of that loader is given a chance to load classes. A: So perhaps, to support class-loading-order independent behaviour, a descendant ClassLoader could be given a chance to define it's own package although the ancestor has already defined one with the same name, unless this is a sealed package of course. B: A backwards-incompatible and more restrictive strategy could be to prevent an ancestor ClassLoader from defining a Package if one of descendants in the chain leading from initiating ClassLoader to the ancestor already defines a package with the same name. This would not prevent loading of such "conflicting" classes for the entire system, but only for a particular code that happens to be defined by the ClassLoader that (or it's ancestor) violates the constraint that a descendant ClassLoader must not define classes in the package of the same name as ancestor ClassLoader. It would prevent classes loaded by a violating ClassLoader from accessing classes in sealed packages, which might be enough to enforce intra-package access restrictions... How does Jigsaw solve this puzzle? Regards, Peter > > No comment on the manifest caching aspect - I'm not familiar enough > with the existing code. > > On 12/10/2014 12:09 PM, Claes Redestad wrote: >> On 2014-10-11 02:31, Mandy Chung wrote: >>> >>> On 10/10/2014 8:10 AM, Claes Redestad wrote: >>>> Hi all, >>>> >>>> please review this patch which attempts to clean up synchronization >>>> and improve scalability when >>>> defining and getting java.lang.Package objects. >>> >>> I agree with David that getting Package objects are not performance >>> critical. On the other hand, the code defining/getting Packages is >>> old and deserves some cleanup especially the synchronization part. >>> >>> If you run helloworld program, how does that change the list of loaded >>> classes besides the new CachedManifest class? >>> >>>> >>>> webrev: http://cr.openjdk.java.net/~redestad/8060130/webrev.02/ >>> >>> ClassLoader.java >>> line 272: can you change the declared type as Map. >> >> Map misses the atomicity requirement of putIfAbsent, ConcurrentMap is OK >> but leaves some >> related questions open (why we can't add a null value, specifically). >> I'm glad it was brought up >> and discussed and will use ConcurrentHashMap for private fields unless >> there's a strong >> preference otherwise. >> >>> >>> definePackage throws IAE if there exists an existing package either >>> in this class loader or one of its ancestors. >>> - this change would not catch if two definePackage calls to define >>> a package of the same name but with different spec version, title, >>> etc >>> concurrently. >>> >>> You may not be able to avoid synchronizing on packages for this case. >> >> Right, I was I think synchronization can still be avoided by throwing >> IAE if >> putIfAbsent doesn't return null: >> >> if (packages.putIfAbsent(name, pkg) != null) { >> throw new IllegalArgumentException(name); >> } >> return pkg; >> >>> >>> move line 1623 to 1630 so that the declaration of map is closer to >>> the assignment. >> >> Ok >> >>> >>> Package.java >>> >>> line 557 there is a possibility that new Package[pkgs.size()] is not >>> big enough and a new array would be created. As this method is not >>> popularly used, it's okay if another array is created. >> >> Yes, an unlikely race. >> >>> >>> line 563 and 565 can be merged >>> >>> line 570-575: do you think you can modify the private >>> Package(String name, Manifest man, URL url, ClassLoader loader) >>> constructor >>> to take null Manifest and null url so that these lines can be folded >>> into >>> >>> pkg = new Package(name, cachedManifest.getManifest(), >>> cachedManifest.getURL(), null); >> >> I think I'll take your suggestion below and ensure cachedManifest and >> it's getManifest() >> never evaluate to null, which makes for a cleaner patch. There is some >> code duplication >> here with URLClassLoader#definePackage. Future cleanup? >> >> It would seem the ClassLoader argument in this ctor is always called >> with null. Remove? >> >>> >>> I think CachedManifest class and the createCachedManifest method need >>> some work. Perhaps we can have the CachedManifest constructor to >>> obtain the URL. >>> >>> Each invalid fn will have one instance instead of NO_MANIFEST singleton >>> but that should not happen as fn is the filename where the classes >>> loaded from the bootclasspath. CachedManifest.url can then become >>> final. >>> >>> line 587-601 would not be needed. Can we avoid line 606 and write >>> the createCachedManifest method this way: >>> if (!manifests.containsKey(fn)) { >>> manifests.putIfAbsent(fn, new CachedManifest(fn)); >>> } >>> return manifests.get(fn); >> >> Yes. Looked a bit dangerous, but it seems we still maintain the >> necessary guarantees. >> >>> >>> You may be able to further simplify CachedManifest and remove the >>> resolved >>> field by storing an empty Manifest when loadManifest returns null. >>> That may help the private Package constructor not require any change >>> to merge line 570-575 as my comment noted above. >> >> Sure! Taking in all these suggestions as well as realizing a race could >> cause different Package >> to return from subsequent calls to Package.defineSystemPackage brings me >> to this: >> >> http://cr.openjdk.java.net/~redestad/8060130/webrev.03/ >> >> Now... How about a slightly alternative approach: instead of caching >> Manifests we could create >> and cache a Package - call it a prototype - then add a private >> constructor taking the >> package name and the "prototype" Package. The Package objects should >> come with a >> smaller footprint and have the added benefit of being effectively >> immutable. Does that >> sound like an improvement? >> >>> >>> You will need to check there is any test to verify Package created with >>> and without manifest. Do you mind making this change and tests (I >>> realize >>> it might be out of scope of this performance improvement you initially >>> anticipated)? >> >> I'll take a look at the current test coverage and give it some thought. >> >> Thanks! >> >> /Claes >> >>> >>> Mandy >>> >> From amy.lu at oracle.com Mon Oct 13 10:56:30 2014 From: amy.lu at oracle.com (Amy Lu) Date: Mon, 13 Oct 2014 18:56:30 +0800 Subject: RFR 8058854: Remove dependency on dt.jar from test/tools/jar/normalize/TestNormal.java In-Reply-To: <543B91B3.2080401@oracle.com> References: <543B8C13.6020201@oracle.com> <543B91B3.2080401@oracle.com> Message-ID: <543BAFDE.1010803@oracle.com> On 10/13/14, 4:47 PM, Alan Bateman wrote: > On 13/10/2014 09:23, Amy Lu wrote: >> tools/jar/normalize/TestNormal.java use JDK dt.jar in test, this fix >> is to remove this dependency from test because with a modular dt.jar >> and the other JAR files in the JDK go away. >> >> bug: https://bugs.openjdk.java.net/browse/JDK-8058854 >> webrev: http://cr.openjdk.java.net/~tyan/amylu/8058854/webrev.00/ > I'm not sure about @library ../../pack200 and using the pack200 test > support as it created a non-obvious dependency in the test tree. An > alternative would be to move the test to the pack200 test directory as > this test is about create JAR files that invariant to pack200 operations. > > -Alan. Moved the test to pack200 http://cr.openjdk.java.net/~weijun/8058854/webrev.01/ Thanks, Amy From olivier.lagneau at oracle.com Mon Oct 13 11:46:05 2014 From: olivier.lagneau at oracle.com (olivier.lagneau at oracle.com) Date: Mon, 13 Oct 2014 13:46:05 +0200 Subject: Sponsor needed : JDK-8039915 : Wrong NumberFormat.format() HALF_UP rounding when last digit exactly at rounding position greater than 5 Message-ID: <543BBB7D.90002@oracle.com> Could someone please sponsor this change for 9 ? The webrev and patch are here: http://cr.openjdk.java.net/~olagneau/8039915/webrev.03 And the review discussions are here: http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/028956.html http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-September/028583.html The changeset comment is: 8039915: Wrong NumberFormat.format() HALF_UP rounding when last digit exactly at rounding position greater than 5 Summary: Fixes erroneous rounding in DigitList for corner cases uncovered previously. Adds dedicated unit tests to TieRoundingTest Reviewed-by:bpb, darcy Thanks, Olivier From david.lloyd at redhat.com Mon Oct 13 12:50:43 2014 From: david.lloyd at redhat.com (David M. Lloyd) Date: Mon, 13 Oct 2014 07:50:43 -0500 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <54387A6D.90402@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> Message-ID: <543BCAA3.7020003@redhat.com> On 10/10/2014 07:31 PM, Mandy Chung wrote: > > On 10/10/2014 8:10 AM, Claes Redestad wrote: >> Hi all, >> >> please review this patch which attempts to clean up synchronization >> and improve scalability when >> defining and getting java.lang.Package objects. > > I agree with David that getting Package objects are not performance > critical. On the other hand, the code defining/getting Packages is > old and deserves some cleanup especially the synchronization part. I have a little more information on this subject. We've a possible (and somewhat likely) deadlock which occurs because one thread can attempt to define a system class while holding the java.lang.Package#pkgs lock, while another thread can attempt to get a package while defining a system class (while holding the class loader lock). I do not recall whether parallel class loading alleviates this issue. We solved the problem by loading Packages.getPackages() in early (single-threaded) bootstrap. So from my perspective, just getting rid of the synchronization on that field alone makes this change worthwhile. -- - DML From paul.sandoz at oracle.com Mon Oct 13 13:18:08 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 13 Oct 2014 15:18:08 +0200 Subject: [9] [8u40] RFR (M): 8059877: GWT branch frequencies pollution due to LF sharing In-Reply-To: <54382E90.7040105@oracle.com> References: <54382E90.7040105@oracle.com> Message-ID: <03B32851-A9DB-4C43-ABB3-2CFE36D7CB0C@oracle.com> On Oct 10, 2014, at 9:08 PM, Vladimir Ivanov wrote: > http://cr.openjdk.java.net/~vlivanov/8059877/webrev.00/ > https://bugs.openjdk.java.net/browse/JDK-8059877 > Generally looks ok. - MethodHandleImpl 786 if (wrapper.unblock()) { 787 // Reached invocation threshold. Replace counting/blocking wrapper with a reinvoker. 788 wrapper.isActivated = false; If unblock() returns true then isActivated is already false. At the expense of another box you could use an AtomicBoolean with compareAndSet if you want to really guarantee at most one unblocking, although the box can be removed if the boolean is changed to 'int' and Unsafe is used to CAS. I dunno if strengthening the visibility of MethodHandle.form by stamping in a memory fence after the following will help 792 wrapper.updateForm(lform); e.g. using Unsafe.fullFence. Perhaps isUnblocked is a better name than isActivated since there is no need to set the initial value and it tracks the same value as that returned from unblock? Also while on the subject of naming perhaps consider changing MethodTypeForm.LF_DELEGATE_COUNTING to ...LF_DELEGATE_BLOCK_INLINING? When DONT_INLINE_THRESHOLD > 0 and DONT_INLINE_THRESHOLD == COMPILE_THRESHOLD will that trigger both compilation of a BlockInliningWrapper's form and unblocking? I guess there is some fuzziness depending on concurrent execution. I am just wondering if there is any point compiling a BlockInliningWrapper's form if DONT_INLINE_THRESHOLD is expected to be ~ the same as COMPILE_THRESHOLD. Probably not terribly important especially if the JIT-compiler control approach replaces it. Paul. From claes.redestad at oracle.com Mon Oct 13 13:19:27 2014 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 13 Oct 2014 15:19:27 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543B3675.2000802@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543B3675.2000802@oracle.com> Message-ID: <543BD15F.7020205@oracle.com> On 10/13/2014 04:18 AM, David Holmes wrote: > Hi Claes, > > Looking at version three ... > > You seemed to have changed the caching strategy for Packages in the > classloader. Previously a Package defined by a parent or the system > would be updated in the current loader's Package map; but now you > leave them separate so future lookups will always have to traverse the > hierarchy. This doesn't seem like a performance gain. Right, this would be a throughput-footprint tradeoff: adding more CHM entries versus taking a small penalty for having to potentially look things up in all the ancestral classloaders + Packages.pkgs. I believe the caching was put in place mostly to avoid a chain of relatively expensive synchronization locks with potential for deadlocks, not to solve an actual throughput problem in uncontended cases. There might be a break-off somewhere due to chaining classloaders, but I've not been able to construct a benchmark where this is the case. I could swing either way on this, but with a trivial lookup cost even in the worst case I generally think we should favor footprint here and defer caching-for-performance to the application if ever necessary. > > Looking at definePackage it seems both old and new code have serious > race conditions due to a lack of atomicity when checking the > parent/system packages. A package of the same name could be defined in > the parent/system after definePackage has called getPackage - and we > then end up with two same named Packages in different loaders. Very interesting, but since we're not changing behavior and the issue of classloading order Peter points out can't be resolved by adding atomicity guarantees, I feel this is out of scope for this cleanup. Should we file a new bug to examine this? /Claes > > No comment on the manifest caching aspect - I'm not familiar enough > with the existing code. > > On 12/10/2014 12:09 PM, Claes Redestad wrote: >> On 2014-10-11 02:31, Mandy Chung wrote: >>> >>> On 10/10/2014 8:10 AM, Claes Redestad wrote: >>>> Hi all, >>>> >>>> please review this patch which attempts to clean up synchronization >>>> and improve scalability when >>>> defining and getting java.lang.Package objects. >>> >>> I agree with David that getting Package objects are not performance >>> critical. On the other hand, the code defining/getting Packages is >>> old and deserves some cleanup especially the synchronization part. >>> >>> If you run helloworld program, how does that change the list of loaded >>> classes besides the new CachedManifest class? >>> >>>> >>>> webrev: http://cr.openjdk.java.net/~redestad/8060130/webrev.02/ >>> >>> ClassLoader.java >>> line 272: can you change the declared type as Map. >> >> Map misses the atomicity requirement of putIfAbsent, ConcurrentMap is OK >> but leaves some >> related questions open (why we can't add a null value, specifically). >> I'm glad it was brought up >> and discussed and will use ConcurrentHashMap for private fields unless >> there's a strong >> preference otherwise. >> >>> >>> definePackage throws IAE if there exists an existing package either >>> in this class loader or one of its ancestors. >>> - this change would not catch if two definePackage calls to define >>> a package of the same name but with different spec version, title, >>> etc >>> concurrently. >>> >>> You may not be able to avoid synchronizing on packages for this case. >> >> Right, I was I think synchronization can still be avoided by throwing >> IAE if >> putIfAbsent doesn't return null: >> >> if (packages.putIfAbsent(name, pkg) != null) { >> throw new IllegalArgumentException(name); >> } >> return pkg; >> >>> >>> move line 1623 to 1630 so that the declaration of map is closer to >>> the assignment. >> >> Ok >> >>> >>> Package.java >>> >>> line 557 there is a possibility that new Package[pkgs.size()] is not >>> big enough and a new array would be created. As this method is not >>> popularly used, it's okay if another array is created. >> >> Yes, an unlikely race. >> >>> >>> line 563 and 565 can be merged >>> >>> line 570-575: do you think you can modify the private >>> Package(String name, Manifest man, URL url, ClassLoader loader) >>> constructor >>> to take null Manifest and null url so that these lines can be folded >>> into >>> >>> pkg = new Package(name, cachedManifest.getManifest(), >>> cachedManifest.getURL(), null); >> >> I think I'll take your suggestion below and ensure cachedManifest and >> it's getManifest() >> never evaluate to null, which makes for a cleaner patch. There is some >> code duplication >> here with URLClassLoader#definePackage. Future cleanup? >> >> It would seem the ClassLoader argument in this ctor is always called >> with null. Remove? >> >>> >>> I think CachedManifest class and the createCachedManifest method need >>> some work. Perhaps we can have the CachedManifest constructor to >>> obtain the URL. >>> >>> Each invalid fn will have one instance instead of NO_MANIFEST singleton >>> but that should not happen as fn is the filename where the classes >>> loaded from the bootclasspath. CachedManifest.url can then become >>> final. >>> >>> line 587-601 would not be needed. Can we avoid line 606 and write >>> the createCachedManifest method this way: >>> if (!manifests.containsKey(fn)) { >>> manifests.putIfAbsent(fn, new CachedManifest(fn)); >>> } >>> return manifests.get(fn); >> >> Yes. Looked a bit dangerous, but it seems we still maintain the >> necessary guarantees. >> >>> >>> You may be able to further simplify CachedManifest and remove the >>> resolved >>> field by storing an empty Manifest when loadManifest returns null. >>> That may help the private Package constructor not require any change >>> to merge line 570-575 as my comment noted above. >> >> Sure! Taking in all these suggestions as well as realizing a race could >> cause different Package >> to return from subsequent calls to Package.defineSystemPackage brings me >> to this: >> >> http://cr.openjdk.java.net/~redestad/8060130/webrev.03/ >> >> Now... How about a slightly alternative approach: instead of caching >> Manifests we could create >> and cache a Package - call it a prototype - then add a private >> constructor taking the >> package name and the "prototype" Package. The Package objects should >> come with a >> smaller footprint and have the added benefit of being effectively >> immutable. Does that >> sound like an improvement? >> >>> >>> You will need to check there is any test to verify Package created with >>> and without manifest. Do you mind making this change and tests (I >>> realize >>> it might be out of scope of this performance improvement you initially >>> anticipated)? >> >> I'll take a look at the current test coverage and give it some thought. >> >> Thanks! >> >> /Claes >> >>> >>> Mandy >>> >> From amy.lu at oracle.com Mon Oct 13 13:44:38 2014 From: amy.lu at oracle.com (Amy Lu) Date: Mon, 13 Oct 2014 21:44:38 +0800 Subject: RFR 8058856: tools/jar/LeadingGarbage.java, introduced in JDK-8058520, fails on Windows Message-ID: <543BD746.1070508@oracle.com> Please review the test fix. Test tools/jar/LeadingGarbage.java fails on Windows, wrong line separator used. Also fixed resource unclosed issue. bug: https://bugs.openjdk.java.net/browse/JDK-8058856 webrev: http://cr.openjdk.java.net/~weijun/8058856/webrev.00/ Thanks, Amy From Alan.Bateman at oracle.com Mon Oct 13 13:50:37 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 13 Oct 2014 14:50:37 +0100 Subject: RFR 8058856: tools/jar/LeadingGarbage.java, introduced in JDK-8058520, fails on Windows In-Reply-To: <543BD746.1070508@oracle.com> References: <543BD746.1070508@oracle.com> Message-ID: <543BD8AD.6080005@oracle.com> On 13/10/2014 14:44, Amy Lu wrote: > Please review the test fix. > > Test tools/jar/LeadingGarbage.java fails on Windows, wrong line > separator used. Also fixed resource unclosed issue. > > bug: https://bugs.openjdk.java.net/browse/JDK-8058856 > webrev: http://cr.openjdk.java.net/~weijun/8058856/webrev.00/ This looks okay to me. An alternative for createZipWithLeadingGarbage is to just use Files.copy(normalZip.toPath(), leadingGarbageZip.toPath()). -Alan. From amy.lu at oracle.com Mon Oct 13 13:58:22 2014 From: amy.lu at oracle.com (Amy Lu) Date: Mon, 13 Oct 2014 21:58:22 +0800 Subject: RFR 8058854: Remove dependency on dt.jar from test/tools/jar/normalize/TestNormal.java In-Reply-To: <543B93DD.8050002@oracle.com> References: <543B8C13.6020201@oracle.com> <543B91B3.2080401@oracle.com> <543B93DD.8050002@oracle.com> Message-ID: <543BDA7E.7070303@oracle.com> On 10/13/14, 4:57 PM, Chris Hegarty wrote: > I'm not sure that it matters, in the context of this test, but the jar > file being created will now contain a much smaller number of entries > than was previously being tested. I have a similar comment about the > previous cleanup too. > > I wonder if we need functionality in the testlibrary to create > relatively substantial jar files to test with? Or maybe the number of > entries has no great impact on some tests. The number of entries should not have great impact on these tests...But having a testlibrary for creating small/big jar for test would be good enhancement in the next milestone. Thanks, Amy > > -Chris. > > On 13/10/14 09:47, Alan Bateman wrote: >> On 13/10/2014 09:23, Amy Lu wrote: >>> tools/jar/normalize/TestNormal.java use JDK dt.jar in test, this fix >>> is to remove this dependency from test because with a modular dt.jar >>> and the other JAR files in the JDK go away. >>> >>> bug: https://bugs.openjdk.java.net/browse/JDK-8058854 >>> webrev: http://cr.openjdk.java.net/~tyan/amylu/8058854/webrev.00/ >> I'm not sure about @library ../../pack200 and using the pack200 test >> support as it created a non-obvious dependency in the test tree. An >> alternative would be to move the test to the pack200 test directory as >> this test is about create JAR files that invariant to pack200 >> operations. >> >> -Alan. From konstantin.shefov at oracle.com Mon Oct 13 14:22:13 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Mon, 13 Oct 2014 18:22:13 +0400 Subject: [8u40] Request for approval and review: JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError Message-ID: <543BE015.90505@oracle.com> Hello, Please review and approve the backport of the test bug fix to 8u40 The webrev is slightly different from that for JDK 9, because there is no segmented code cache feature in 8u40. The bug: https://bugs.openjdk.java.net/browse/JDK-8058695 The 8u40 webrev: http://cr.openjdk.java.net/~kshefov/8058733/webrev.01 JDK 9 changeset: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/5c507b7ee225 Review thread: http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029062.html http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029033.html Thanks -Konstantin From konstantin.shefov at oracle.com Mon Oct 13 14:24:46 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Mon, 13 Oct 2014 18:24:46 +0400 Subject: [8u40] Request for approval and review : 8058695: [TESTBUG] Reinvokers with arity >253 can't be cached In-Reply-To: <5437A195.6050200@oracle.com> References: <5437A195.6050200@oracle.com> Message-ID: <543BE0AE.9070304@oracle.com> On 10.10.2014 13:06, Konstantin Shefov wrote: > Hello, > > Please review and approve the backport of the test bug fix to 8u40 > > The bug: https://bugs.openjdk.java.net/browse/JDK-8058695 > The webrev: http://cr.openjdk.java.net/~kshefov/8058695/8u-dev/webrev.00 > > Thanks > > -Konstantin From peter.levart at gmail.com Mon Oct 13 14:32:57 2014 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 13 Oct 2014 16:32:57 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <5439E2DA.1040309@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> Message-ID: <543BE299.9070906@gmail.com> On 10/12/2014 04:09 AM, Claes Redestad wrote: > > > http://cr.openjdk.java.net/~redestad/8060130/webrev.03/ > Hi Claes, First, one more nit: 1635 if (!map.containsKey(pkgName)) { 1636 map.put(pkgName, pkg); 1637 } ..could be written as: map.putIfAbsent(pkgName, pkg); And second, I re-read the code of CachedManifest and noticed the following. You initialize the volatile instance field 'manifest' like that: 609 private volatile Manifest manifest = EMPTY_MANIFEST; So in following code: 631 public Manifest getManifest() { 632 resolveManifest(); 633 return manifest; 634 } 635 636 private void resolveManifest() { 637 if (manifest != null || url == null) { 638 return; 639 } 640 synchronized(this) { 641 if (manifest == null) { 642 manifest = AccessController.doPrivileged(new PrivilegedAction() { 643 public Manifest run() { 644 return loadManifest(fileName); 645 } 646 }); 647 } 648 } 649 } ... loadManifest() will never be executed. getManifest() will always return EMPTY_MANIFEST. You probably wanted line 637 to be written as: if (manivest != EMPTY_MANIFEST || url == null) { ... Likewise in loadManifest(), wou write: 586 private static Manifest loadManifest(String fn) { 587 try (FileInputStream fis = new FileInputStream(fn); 588 JarInputStream jis = new JarInputStream(fis, false)) 589 { 590 return jis.getManifest(); 591 } catch (IOException e) { 592 return EMPTY_MANIFEST; 593 } 594 } ..but you probably wanted the line 592 to return 'null' instead. Regards, Peter From vladimir.x.ivanov at oracle.com Mon Oct 13 15:04:56 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Mon, 13 Oct 2014 19:04:56 +0400 Subject: [8u40] Request for approval and review: JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <543BE015.90505@oracle.com> References: <543BE015.90505@oracle.com> Message-ID: <543BEA18.6060003@oracle.com> Looks good (not a Reviewer). Best regards, Vladimir Ivanov On 10/13/14, 6:22 PM, Konstantin Shefov wrote: > Hello, > > Please review and approve the backport of the test bug fix to 8u40 > > The webrev is slightly different from that for JDK 9, because there is > no segmented code cache feature in 8u40. > > The bug: https://bugs.openjdk.java.net/browse/JDK-8058695 > The 8u40 webrev: http://cr.openjdk.java.net/~kshefov/8058733/webrev.01 > > JDK 9 changeset: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/5c507b7ee225 > Review thread: > http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029062.html > > http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029033.html > > > Thanks > > -Konstantin From peter.levart at gmail.com Mon Oct 13 15:05:45 2014 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 13 Oct 2014 17:05:45 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543BE299.9070906@gmail.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> Message-ID: <543BEA49.7000009@gmail.com> Hi Claes, Regarding CachedManifest I have one more comment. It's usually better to use null/zero as "uninitialized" state for lazy-initialized fields. You spare one (volatile) write and don't worry about unsafe publication which might see the Java-default value instead of the one assigned in initializer as "uninitialized". So summing-up all comments from previous mails I would write CachedManifest class as: private static class CachedManifest { static final Manifest NO_MANIFEST = new Manifest(); final String fileName; private final URL url; private volatile Manifest manifest; CachedManifest(final String fileName) { this.fileName = fileName; this.url = AccessController.doPrivileged(new PrivilegedAction() { public URL run() { final File file = new File(fileName); if (file.isFile()) { try { return ParseUtil.fileToEncodedURL(file); } catch (MalformedURLException e) { } } return null; } }); } public URL getURL() { return url; } public Manifest getManifest() { if (url == null) return null; Manifest m = manifest; if (m == null) { synchronized (this) { if ((m = manifest) == null) { manifest = m = AccessController.doPrivileged(new PrivilegedAction() { public Manifest run() { try (FileInputStream fis = new FileInputStream(fileName); JarInputStream jis = new JarInputStream(fis, false)) { return jis.getManifest(); } catch (IOException e) { return NO_MANIFEST; } } }); } } } return (m == NO_MANIFEST) ? null : m; } } What do you say? Regards, Peter On 10/13/2014 04:32 PM, Peter Levart wrote: > On 10/12/2014 04:09 AM, Claes Redestad wrote: >> >> >> http://cr.openjdk.java.net/~redestad/8060130/webrev.03/ >> > > Hi Claes, > > First, one more nit: > > 1635 if (!map.containsKey(pkgName)) { > 1636 map.put(pkgName, pkg); > 1637 } > > ..could be written as: > > map.putIfAbsent(pkgName, pkg); > > > > And second, I re-read the code of CachedManifest and noticed the > following. You initialize the volatile instance field 'manifest' like > that: > > 609 private volatile Manifest manifest = EMPTY_MANIFEST; > > > So in following code: > > 631 public Manifest getManifest() { > 632 resolveManifest(); > 633 return manifest; > 634 } > 635 > 636 private void resolveManifest() { > 637 if (manifest != null || url == null) { > 638 return; > 639 } > 640 synchronized(this) { > 641 if (manifest == null) { > 642 manifest = AccessController.doPrivileged(new > PrivilegedAction() { > 643 public Manifest run() { > 644 return loadManifest(fileName); > 645 } > 646 }); > 647 } > 648 } > 649 } > > > > ... loadManifest() will never be executed. getManifest() will always > return EMPTY_MANIFEST. > > You probably wanted line 637 to be written as: > > if (manivest != EMPTY_MANIFEST || url == null) { ... > > > Likewise in loadManifest(), wou write: > > 586 private static Manifest loadManifest(String fn) { > 587 try (FileInputStream fis = new FileInputStream(fn); > 588 JarInputStream jis = new JarInputStream(fis, false)) > 589 { > 590 return jis.getManifest(); > 591 } catch (IOException e) { > 592 return EMPTY_MANIFEST; > 593 } > 594 } > > ..but you probably wanted the line 592 to return 'null' instead. > > > Regards, Peter > From claes.redestad at oracle.com Mon Oct 13 15:06:50 2014 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 13 Oct 2014 17:06:50 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543BE299.9070906@gmail.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> Message-ID: <543BEA8A.6090901@oracle.com> Hi Peter, On 10/13/2014 04:32 PM, Peter Levart wrote: > On 10/12/2014 04:09 AM, Claes Redestad wrote: >> >> >> http://cr.openjdk.java.net/~redestad/8060130/webrev.03/ >> > > Hi Claes, > > First, one more nit: > > 1635 if (!map.containsKey(pkgName)) { > 1636 map.put(pkgName, pkg); > 1637 } > > ..could be written as: > > map.putIfAbsent(pkgName, pkg); > Nice catch! > > And second, I re-read the code of CachedManifest and noticed the > following. You initialize the volatile instance field 'manifest' like > that: > > 609 private volatile Manifest manifest = EMPTY_MANIFEST; > > > So in following code: > > 631 public Manifest getManifest() { > 632 resolveManifest(); > 633 return manifest; > 634 } > 635 > 636 private void resolveManifest() { > 637 if (manifest != null || url == null) { > 638 return; > 639 } > 640 synchronized(this) { > 641 if (manifest == null) { > 642 manifest = AccessController.doPrivileged(new > PrivilegedAction() { > 643 public Manifest run() { > 644 return loadManifest(fileName); > 645 } > 646 }); > 647 } > 648 } > 649 } > > > > ... loadManifest() will never be executed. getManifest() will always > return EMPTY_MANIFEST. > > You probably wanted line 637 to be written as: > > if (manivest != EMPTY_MANIFEST || url == null) { ... > > > Likewise in loadManifest(), wou write: > > 586 private static Manifest loadManifest(String fn) { > 587 try (FileInputStream fis = new FileInputStream(fn); > 588 JarInputStream jis = new JarInputStream(fis, false)) > 589 { > 590 return jis.getManifest(); > 591 } catch (IOException e) { > 592 return EMPTY_MANIFEST; > 593 } > 594 } > > ..but you probably wanted the line 592 to return 'null' instead. Yes, I realized I got this messed up and have prepared a new patch which passes tests and includes your previous comments: http://cr.openjdk.java.net/~redestad/8060130/webrev.04 Aleksey Shipilev pointed out offline that we can't trust the volatile to be completely initialized here (requiring a null check either way), so the better solution is to initialize manifest to null and set it to EMPTY_MANIFEST as we resolve and consistently only do null checks. Inlining resolveManifest and loadManifest into getManifest as you suggested seems to get rid of a few generated access methods. It's cutting corners on line length limits, though, but maybe it can be allowed in this case? By also moving the static final EMPTY_MANIFEST into CachedManifest we avoid generating any access method for this as well, with no impact on readability. For reference I also did some java -verbose:class experiments: any Hello World program will load most ConcurrentHashMap classes already - in the same order - and the new inner class in j.l.Package won't be loaded unless the application goes to lengths to get a system package, so no reordering of startup load order is to be expected. The deviant is getPackages, which when invoked will additionally load a couple of ConcurrentHashMap traversal related classes, but I don't think that matters. Byte code size and complexity seems to drop a bit, too, if anyone's counting: javap -v java.lang.Package | wc -l before: 1263, after: 1139 javap -v java.lang.ClassLoader | wc -l before: 2800, after: 2687 Thanks! /Claes > > > Regards, Peter > From peter.levart at gmail.com Mon Oct 13 15:15:26 2014 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 13 Oct 2014 17:15:26 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543BEA8A.6090901@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> Message-ID: <543BEC8E.6050309@gmail.com> So we all came to same conclusions after all. I would call this a redundant concurrent "initialization" ;-) Regards, Peter On 10/13/2014 05:06 PM, Claes Redestad wrote: > Hi Peter, > > On 10/13/2014 04:32 PM, Peter Levart wrote: >> On 10/12/2014 04:09 AM, Claes Redestad wrote: >>> >>> >>> http://cr.openjdk.java.net/~redestad/8060130/webrev.03/ >>> >> >> Hi Claes, >> >> First, one more nit: >> >> 1635 if (!map.containsKey(pkgName)) { >> 1636 map.put(pkgName, pkg); >> 1637 } >> >> ..could be written as: >> >> map.putIfAbsent(pkgName, pkg); >> > > Nice catch! > >> >> And second, I re-read the code of CachedManifest and noticed the >> following. You initialize the volatile instance field 'manifest' like >> that: >> >> 609 private volatile Manifest manifest = EMPTY_MANIFEST; >> >> >> So in following code: >> >> 631 public Manifest getManifest() { >> 632 resolveManifest(); >> 633 return manifest; >> 634 } >> 635 >> 636 private void resolveManifest() { >> 637 if (manifest != null || url == null) { >> 638 return; >> 639 } >> 640 synchronized(this) { >> 641 if (manifest == null) { >> 642 manifest = AccessController.doPrivileged(new >> PrivilegedAction() { >> 643 public Manifest run() { >> 644 return loadManifest(fileName); >> 645 } >> 646 }); >> 647 } >> 648 } >> 649 } >> >> >> >> ... loadManifest() will never be executed. getManifest() will always >> return EMPTY_MANIFEST. >> >> You probably wanted line 637 to be written as: >> >> if (manivest != EMPTY_MANIFEST || url == null) { ... >> >> >> Likewise in loadManifest(), wou write: >> >> 586 private static Manifest loadManifest(String fn) { >> 587 try (FileInputStream fis = new FileInputStream(fn); >> 588 JarInputStream jis = new JarInputStream(fis, false)) >> 589 { >> 590 return jis.getManifest(); >> 591 } catch (IOException e) { >> 592 return EMPTY_MANIFEST; >> 593 } >> 594 } >> >> ..but you probably wanted the line 592 to return 'null' instead. > > Yes, I realized I got this messed up and have prepared a new patch > which passes tests and includes your previous > comments: > > http://cr.openjdk.java.net/~redestad/8060130/webrev.04 > > Aleksey Shipilev pointed out offline that we can't trust the volatile > to be completely initialized here (requiring a > null check either way), so the better solution is to initialize > manifest to null and set it to EMPTY_MANIFEST as > we resolve and consistently only do null checks. > > Inlining resolveManifest and loadManifest into getManifest as you > suggested seems to get rid of a few generated > access methods. It's cutting corners on line length limits, though, > but maybe it can be allowed in this case? > > By also moving the static final EMPTY_MANIFEST into CachedManifest we > avoid generating any access method for > this as well, with no impact on readability. > > For reference I also did some java -verbose:class experiments: any > Hello World program will load most > ConcurrentHashMap classes already - in the same order - and the new > inner class in j.l.Package won't be loaded > unless the application goes to lengths to get a system package, so no > reordering of startup load order is to be > expected. The deviant is getPackages, which when invoked will > additionally load a couple of ConcurrentHashMap > traversal related classes, but I don't think that matters. > > Byte code size and complexity seems to drop a bit, too, if anyone's > counting: > > javap -v java.lang.Package | wc -l > before: 1263, after: 1139 > > javap -v java.lang.ClassLoader | wc -l > before: 2800, after: 2687 > > Thanks! > > /Claes > >> >> >> Regards, Peter >> > From Alan.Bateman at oracle.com Mon Oct 13 15:18:06 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 13 Oct 2014 16:18:06 +0100 Subject: RFR 8058854: Remove dependency on dt.jar from test/tools/jar/normalize/TestNormal.java In-Reply-To: <543BAFDE.1010803@oracle.com> References: <543B8C13.6020201@oracle.com> <543B91B3.2080401@oracle.com> <543BAFDE.1010803@oracle.com> Message-ID: <543BED2E.1050905@oracle.com> On 13/10/2014 11:56, Amy Lu wrote: > > Moved the test to pack200 > http://cr.openjdk.java.net/~weijun/8058854/webrev.01/ > This looks okay to me now. -Alan From kumar.x.srinivasan at oracle.com Mon Oct 13 15:18:58 2014 From: kumar.x.srinivasan at oracle.com (Kumar Srinivasan) Date: Mon, 13 Oct 2014 08:18:58 -0700 Subject: RFR 8058854: Remove dependency on dt.jar from test/tools/jar/normalize/TestNormal.java In-Reply-To: <543BED2E.1050905@oracle.com> References: <543B8C13.6020201@oracle.com> <543B91B3.2080401@oracle.com> <543BAFDE.1010803@oracle.com> <543BED2E.1050905@oracle.com> Message-ID: <543BED62.4000006@oracle.com> +1 Kumar On 10/13/2014 8:18 AM, Alan Bateman wrote: > On 13/10/2014 11:56, Amy Lu wrote: >> >> Moved the test to pack200 >> http://cr.openjdk.java.net/~weijun/8058854/webrev.01/ >> > This looks okay to me now. > > -Alan From peter.levart at gmail.com Mon Oct 13 15:29:24 2014 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 13 Oct 2014 17:29:24 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543BEC8E.6050309@gmail.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> Message-ID: <543BEFD4.40707@gmail.com> On 10/13/2014 05:15 PM, Peter Levart wrote: > Yes, I realized I got this messed up and have prepared a new patch > which passes tests and includes your previous > comments: > > http://cr.openjdk.java.net/~redestad/8060130/webrev.04 Hi Claes, Hm, CachedManifest.getManifest() in 4th webrev is still a little faulty. It sometimes returns EMPTY_MANIFEST and sometimes null. I think it should always return null in case when no manifest is found (at least that was the old code behaviour). Regards, Peter From claes.redestad at oracle.com Mon Oct 13 15:41:18 2014 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 13 Oct 2014 17:41:18 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543BEFD4.40707@gmail.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> Message-ID: <543BF29E.70303@oracle.com> On 10/13/2014 05:29 PM, Peter Levart wrote: > On 10/13/2014 05:15 PM, Peter Levart wrote: >> Yes, I realized I got this messed up and have prepared a new patch >> which passes tests and includes your previous >> comments: >> >> http://cr.openjdk.java.net/~redestad/8060130/webrev.04 > > > Hi Claes, > > Hm, CachedManifest.getManifest() in 4th webrev is still a little > faulty. It sometimes returns EMPTY_MANIFEST and sometimes null. I > think it should always return null in case when no manifest is found > (at least that was the old code behaviour). Hmm, yes, that last little detail of making sure we also set m before returning: - manifest = (m == null ? EMPTY_MANIFEST : m); + manifest = m = (m == null ? EMPTY_MANIFEST : m); http://cr.openjdk.java.net/~redestad/8060130/webrev.05 We rely on returning a non-null manifest from CachedManifest.getManifest() in the current code, so returning null would be a bad idea unless we revert the simplifications to defineSystemPackage. /Claes > > Regards, Peter From peter.levart at gmail.com Mon Oct 13 15:52:21 2014 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 13 Oct 2014 17:52:21 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543BF29E.70303@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> Message-ID: <543BF535.3020403@gmail.com> On 10/13/2014 05:41 PM, Claes Redestad wrote: > On 10/13/2014 05:29 PM, Peter Levart wrote: >> On 10/13/2014 05:15 PM, Peter Levart wrote: >>> Yes, I realized I got this messed up and have prepared a new patch >>> which passes tests and includes your previous >>> comments: >>> >>> http://cr.openjdk.java.net/~redestad/8060130/webrev.04 >> >> >> Hi Claes, >> >> Hm, CachedManifest.getManifest() in 4th webrev is still a little >> faulty. It sometimes returns EMPTY_MANIFEST and sometimes null. I >> think it should always return null in case when no manifest is found >> (at least that was the old code behaviour). > > Hmm, yes, that last little detail of making sure we also set m before > returning: > > - manifest = (m == null ? EMPTY_MANIFEST : m); > + manifest = m = (m == null ? EMPTY_MANIFEST : m); > > http://cr.openjdk.java.net/~redestad/8060130/webrev.05 > > We rely on returning a non-null manifest from > CachedManifest.getManifest() in the current code, so returning null > would be a bad idea unless we revert the simplifications to > defineSystemPackage. Right, I missed that part. Peter > > /Claes > >> >> Regards, Peter > From martinrb at google.com Mon Oct 13 17:04:04 2014 From: martinrb at google.com (Martin Buchholz) Date: Mon, 13 Oct 2014 10:04:04 -0700 Subject: RFR 8058856: tools/jar/LeadingGarbage.java, introduced in JDK-8058520, fails on Windows In-Reply-To: <543BD746.1070508@oracle.com> References: <543BD746.1070508@oracle.com> Message-ID: Looks good to me. I'm sorry I keep on creating windows trouble. If you had external jprt, or some kind of external submission to an internal multi-platform jtreg testing service, that would help. On Mon, Oct 13, 2014 at 6:44 AM, Amy Lu wrote: > Please review the test fix. > > Test tools/jar/LeadingGarbage.java fails on Windows, wrong line separator > used. Also fixed resource unclosed issue. > > bug: https://bugs.openjdk.java.net/browse/JDK-8058856 > webrev: http://cr.openjdk.java.net/~weijun/8058856/webrev.00/ > > Thanks, > Amy > > > From xueming.shen at oracle.com Mon Oct 13 17:09:48 2014 From: xueming.shen at oracle.com (Xueming Shen) Date: Mon, 13 Oct 2014 10:09:48 -0700 Subject: RFR 8058856: tools/jar/LeadingGarbage.java, introduced in JDK-8058520, fails on Windows In-Reply-To: <543BD746.1070508@oracle.com> References: <543BD746.1070508@oracle.com> Message-ID: <543C075C.1070204@oracle.com> On 10/13/2014 06:44 AM, Amy Lu wrote: > Please review the test fix. > > Test tools/jar/LeadingGarbage.java fails on Windows, wrong line separator used. Also fixed resource unclosed issue. > > bug: https://bugs.openjdk.java.net/browse/JDK-8058856 > webrev: http://cr.openjdk.java.net/~weijun/8058856/webrev.00/ > > Thanks, > Amy > > looks fine. From lance.andersen at oracle.com Mon Oct 13 18:27:04 2014 From: lance.andersen at oracle.com (Lance Andersen) Date: Mon, 13 Oct 2014 14:27:04 -0400 Subject: RFR (JAXP): 8036951: Xerces Update: XMLSchemaValidator.java and XMLSchemaLoader.java In-Reply-To: <542EDAFD.7030406@oracle.com> References: <542EDAFD.7030406@oracle.com> Message-ID: Hi Joe, I have made a pass through this and it seems OK. Given that the TCK and JPRT is passing, I think you should be fine. Best Lance On Oct 3, 2014, at 1:21 PM, huizhe wang wrote: > Hi, > > This patch contains updates to 52 classes, mostly completely updated to the trunk except a few. I replaced some obsolete usages (e.g. Vector), but not all of them in order to not expand the update into more classes. With this patch, the main validation section is updated to the current trunk. > > New tests were added. Previously added tests were updated. Fixed a few test failures caused by later revisions, or difference in the JDK implementation with regards to the default settings of FEATURE_SECURE_PROCESSING (JDK set the default to true, see FeaturePropagationTest.java). > > A full-test (JPRT, unit/funtional/TCK tests) passed. > > Please review: > https://bugs.openjdk.java.net/browse/JDK-8036951 > http://cr.openjdk.java.net/~joehw/jdk9/8036951/webrev/ > > Thanks, > Joe Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From huizhe.wang at oracle.com Mon Oct 13 19:08:31 2014 From: huizhe.wang at oracle.com (huizhe wang) Date: Mon, 13 Oct 2014 12:08:31 -0700 Subject: RFR (JAXP): 8036951: Xerces Update: XMLSchemaValidator.java and XMLSchemaLoader.java In-Reply-To: References: <542EDAFD.7030406@oracle.com> Message-ID: <543C232F.1090100@oracle.com> Thanks Lance! Joe On 10/13/2014 11:27 AM, Lance Andersen wrote: > Hi Joe, > > I have made a pass through this and it seems OK. Given that the TCK > and JPRT is passing, I think you should be fine. > > Best > Lance > On Oct 3, 2014, at 1:21 PM, huizhe wang > wrote: > >> Hi, >> >> This patch contains updates to 52 classes, mostly completely updated >> to the trunk except a few. I replaced some obsolete usages (e.g. >> Vector), but not all of them in order to not expand the update into >> more classes. With this patch, the main validation section is updated >> to the current trunk. >> >> New tests were added. Previously added tests were updated. Fixed a >> few test failures caused by later revisions, or difference in the JDK >> implementation with regards to the default settings of >> FEATURE_SECURE_PROCESSING (JDK set the default to true, see >> FeaturePropagationTest.java). >> >> A full-test (JPRT, unit/funtional/TCK tests) passed. >> >> Please review: >> https://bugs.openjdk.java.net/browse/JDK-8036951 >> http://cr.openjdk.java.net/~joehw/jdk9/8036951/webrev/ >> >> Thanks, >> Joe > > > > Lance > Andersen| Principal Member of Technical Staff | +1.781.442.2037 > Oracle Java Engineering > 1 Network Drive > Burlington, MA 01803 > Lance.Andersen at oracle.com > > > From martinrb at google.com Tue Oct 14 06:34:39 2014 From: martinrb at google.com (Martin Buchholz) Date: Mon, 13 Oct 2014 23:34:39 -0700 Subject: RFR [9] - 8060052: FutureTask; fix underflow when timeout = Long.MIN_VALUE In-Reply-To: <1413071802.93800.YahooMailNeo@web172401.mail.ir2.yahoo.com> References: <5437FB76.3070709@oracle.com> <1413071802.93800.YahooMailNeo@web172401.mail.ir2.yahoo.com> Message-ID: On Sat, Oct 11, 2014 at 4:56 PM, Jeff Hain wrote: > > Chris wrote: > >Webrev: > > http://cr.openjdk.java.net/~chegar/8060052/webrev.00/webrev/ > > An aside remark: > > Every time some nanos timeout needs to be kept track of, and that > remaining time does not need to be returned, one could consider > the timeout to be infinite (timed = false) above, say, Long.MAX_VALUE/2 > (not Long.MAX_VALUE, because some (actual) durations might be > subtracted from the specified timeout by intermediate treatments), > to get a small (in absolute) but relatively noticeable performance boost > on configurations where System.nanoTime() is slow. > > In the curent case, if not wanting to have System.nanoTime() calls, > there is the get() method, but generic code might use get(long,TimeUnit) > even for huge timeouts. > I thought about this. It's a tradeoff between the small extra complexity and the small penalty when you don't have huge timeouts vs the slightly bigger performance benefit when you do. Not worth it. An existing API that only accepts a finite user-specified timeout could have an optimized implementation to call untimed get() when the user-specified timeout is close to Long.MAX_VALUE. Hmmm.... but maybe we should always be rechecking the state between calling nanoTime and parking, since parking/unparking is a bigger performance killer.... leveraging the slowness of nanoTime to our benefit by extending the "spinloop". --- src/main/java/util/concurrent/FutureTask.java 22 Aug 2014 03:30:56 -0000 1.106 +++ src/main/java/util/concurrent/FutureTask.java 14 Oct 2014 06:29:57 -0000 @@ -411,7 +411,8 @@ } parkNanos = nanos - elapsed; } - LockSupport.parkNanos(this, parkNanos); + if (state < COMPLETING) + LockSupport.parkNanos(this, parkNanos); } else LockSupport.park(this); > Or maybe we don't want users to dangerously tinker around this > hidden and huge threshold... > > > -Jeff > From aleksej.efimov at oracle.com Tue Oct 14 07:29:36 2014 From: aleksej.efimov at oracle.com (Aleksej Efimov) Date: Tue, 14 Oct 2014 11:29:36 +0400 Subject: RFR: 8046817: JDK 8 schemagen tool does not generate xsd files for enum types In-Reply-To: <5434FF2D.104@oracle.com> References: <5434FF2D.104@oracle.com> Message-ID: <543CD0E0.7060109@oracle.com> Hi XML experts, Can I humbly ask to review this simple fix. Thank you, Aleksej On 08.10.2014 13:09, Aleksej Efimov wrote: > Hello, > > Please, review the fix [1] for the 8046817 [2]. > Problem: schemagen tool doesn't generate schema file for the enum > types [3]. > SchemaGenerator class gets a list of annotated elements and filters > out only the class variables, but annotation parser > (AnnotationParser.java) filters out the Class and Enum. The proposed > fix solves the problem: SchemaGenerator filters like AnnotationParser. > Testing: JPRT build and test passes on platforms (with new regression > test). JTREG tests: javax/xml - no failures. > > Thanks, > Aleksej > > [1] Webrev: http://cr.openjdk.java.net/~aefimov/8046817/9/webrev.00/ > [2] Bug: https://bugs.openjdk.java.net/browse/JDK-8046817 > [3] Enum type: > http://cr.openjdk.java.net/~aefimov/8046817/9/webrev.00/jdk/test/javax/xml/ws/8046817/TestEnumType.java.html From konstantin.shefov at oracle.com Tue Oct 14 08:26:24 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Tue, 14 Oct 2014 12:26:24 +0400 Subject: [8u40] Request for approval and review: JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <543BEA18.6060003@oracle.com> References: <543BE015.90505@oracle.com> <543BEA18.6060003@oracle.com> Message-ID: <543CDE30.7010506@oracle.com> Gently reminder Please, review -Konstantin On 13.10.2014 19:04, Vladimir Ivanov wrote: > Looks good (not a Reviewer). > > Best regards, > Vladimir Ivanov > > On 10/13/14, 6:22 PM, Konstantin Shefov wrote: >> Hello, >> >> Please review and approve the backport of the test bug fix to 8u40 >> >> The webrev is slightly different from that for JDK 9, because there is >> no segmented code cache feature in 8u40. >> >> The bug: https://bugs.openjdk.java.net/browse/JDK-8058695 >> The 8u40 webrev: http://cr.openjdk.java.net/~kshefov/8058733/webrev.01 >> >> JDK 9 changeset: >> http://hg.openjdk.java.net/jdk9/dev/jdk/rev/5c507b7ee225 >> Review thread: >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029062.html >> >> >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029033.html >> >> >> >> Thanks >> >> -Konstantin From konstantin.shefov at oracle.com Tue Oct 14 09:44:42 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Tue, 14 Oct 2014 13:44:42 +0400 Subject: [8u40] Request for approval and review : 8058695: [TESTBUG] Reinvokers with arity >253 can't be cached In-Reply-To: <543BE0AE.9070304@oracle.com> References: <5437A195.6050200@oracle.com> <543BE0AE.9070304@oracle.com> Message-ID: <543CF08A.3060503@oracle.com> Gently reminder Please, review this test bug fix backport -Konstantin On 13.10.2014 18:24, Konstantin Shefov wrote: > > On 10.10.2014 13:06, Konstantin Shefov wrote: >> Hello, >> >> Please review and approve the backport of the test bug fix to 8u40 >> >> The bug: https://bugs.openjdk.java.net/browse/JDK-8058695 >> The webrev: http://cr.openjdk.java.net/~kshefov/8058695/8u-dev/webrev.00 >> >> Thanks >> >> -Konstantin > From paul.sandoz at oracle.com Tue Oct 14 10:50:56 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 14 Oct 2014 12:50:56 +0200 Subject: [8u40] Request for approval and review: JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <543CDE30.7010506@oracle.com> References: <543BE015.90505@oracle.com> <543BEA18.6060003@oracle.com> <543CDE30.7010506@oracle.com> Message-ID: On Oct 14, 2014, at 10:26 AM, Konstantin Shefov wrote: > Gently reminder > Please, review > +1 Paul. > -Konstantin > > On 13.10.2014 19:04, Vladimir Ivanov wrote: >> Looks good (not a Reviewer). >> >> Best regards, >> Vladimir Ivanov >> >> On 10/13/14, 6:22 PM, Konstantin Shefov wrote: >>> Hello, >>> >>> Please review and approve the backport of the test bug fix to 8u40 >>> >>> The webrev is slightly different from that for JDK 9, because there is >>> no segmented code cache feature in 8u40. >>> >>> The bug: https://bugs.openjdk.java.net/browse/JDK-8058695 >>> The 8u40 webrev: http://cr.openjdk.java.net/~kshefov/8058733/webrev.01 >>> >>> JDK 9 changeset: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/5c507b7ee225 >>> Review thread: >>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029062.html >>> >>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029033.html >>> >>> >>> Thanks >>> >>> -Konstantin > From daniel.fuchs at oracle.com Tue Oct 14 10:55:48 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Tue, 14 Oct 2014 12:55:48 +0200 Subject: RFR: 8059767: FileHandler should allow 'long' limits and handle overflow of MeteredStream.written. In-Reply-To: <543507F2.2050804@oracle.com> References: <5433E6E9.2080009@oracle.com> <5434D91C.4040902@oracle.com> <543507F2.2050804@oracle.com> Message-ID: <543D0134.4010605@oracle.com> Hi, Following a feedback from Alan - I dropped 'SecurityException' from the throws clause of the new constructor - keeping only the @throws in the API documentation. Here is the new webrev (the above is the only change compared to the previous webrev.01). http://cr.openjdk.java.net/~dfuchs/webrev_8059767/webrev.02 I also logged JDK-8060457 to follow up and cleanup that in all handlers subclasses (no impact on the actual implementation / behavior - it's just cleanup). Attempting the cleanup in this fix was just too much noise. best regards, -- daniel On 08/10/14 11:46, Daniel Fuchs wrote: > On 08/10/14 08:26, Ivan Gerasimov wrote: >> Hi Daniel! >> >> Would it make sense to make the old constructor FileHandler(String, >> *int*, int, boolean) call the new one, casting the limit to long? > > Hi Ivan, > > I was about to reply 'no' out of consistency with the other > constructors - which don't call each others - when I realized > that it was not be possible to make the other constructors > call each others anyway - as passing a parameter to a constructor > means overriding the default value read from the configuration > file. > > This however doesn't hold in our case as both constructors > have exactly the same code - so there's no reason for not making > FileHandler(String, *int*, int, boolean) call > FileHandler(String, *long*, int, boolean). > > Which now makes me question whether I should add a second constructor > FileHandler(String, *long*, int) to shadow FileHandler(String, *int*, > int) - as Stanimir aleready suggested. > > My feeling is that the case where you would want to rely on the > default value of 'append' configured in the logging.properties file > instead of specifying one to the constructor should be sufficiently > rare to not warrant the addition of a second constructor. > And if you really wanted to rely on that default value you could > go and fetch it before calling the constructor. > > Anyway - good remark - and here is a new webrev including yours and > Jason's comments. > > http://cr.openjdk.java.net/~dfuchs/webrev_8059767/webrev.01 > > best regards, > > -- daniel > >> >> Sincerely yours, >> Ivan >> >> On 07.10.2014 17:13, Daniel Fuchs wrote: >>> Hi, >>> >>> Please find below a patch for: >>> >>> 8059767: FileHandler should allow 'long' limits and handle overflow >>> of MeteredStream.written. >>> https://bugs.openjdk.java.net/browse/JDK-8059767 >>> >>> webrev: >>> http://cr.openjdk.java.net/~dfuchs/webrev_8059767/webrev.00/ >>> >>> This follows an issue reported on this list: >>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-August/028280.html >>> >>> >>> >>> The patch changes 'limit' from 'int' to 'long', fixes the >>> handling of overflow, and adds a new constructor that allows >>> to pass a long for 'limit'. >>> It also makes it possible to specify a long value for 'limit' >>> in the configuration. >>> >>> The test checks the handling of overflow by tweaking the >>> internal of MeteredStream through reflection. Not ideal, but >>> I couldn't find any other way. >>> >>> best regards, >>> >>> -- daniel >>> >>> >> > From paul.sandoz at oracle.com Tue Oct 14 10:59:41 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 14 Oct 2014 12:59:41 +0200 Subject: [8u40] Request for approval and review : 8058695: [TESTBUG] Reinvokers with arity >253 can't be cached In-Reply-To: <543CF08A.3060503@oracle.com> References: <5437A195.6050200@oracle.com> <543BE0AE.9070304@oracle.com> <543CF08A.3060503@oracle.com> Message-ID: On Oct 14, 2014, at 11:44 AM, Konstantin Shefov wrote: > Gently reminder > Please, review this test bug fix backport > Looks ok to me, but i did not detect any difference between: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/d37a314f2f64 and: http://cr.openjdk.java.net/~kshefov/8058695/8u-dev/webrev.00/test/java/lang/invoke/LFCaching/TestMethods.java.sdiff.html Did i miss something? Paul. > -Konstantin > > On 13.10.2014 18:24, Konstantin Shefov wrote: >> >> On 10.10.2014 13:06, Konstantin Shefov wrote: >>> Hello, >>> >>> Please review and approve the backport of the test bug fix to 8u40 >>> >>> The bug: https://bugs.openjdk.java.net/browse/JDK-8058695 >>> The webrev: http://cr.openjdk.java.net/~kshefov/8058695/8u-dev/webrev.00 >>> >>> Thanks >>> >>> -Konstantin >> > From pavel.rappo at oracle.com Tue Oct 14 11:11:25 2014 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Tue, 14 Oct 2014 12:11:25 +0100 Subject: RFR JDK-8044627: Update JNDI to work with modules In-Reply-To: <541FE404.8080503@oracle.com> References: <541FE404.8080503@oracle.com> Message-ID: <11A1E834-2978-45F9-B057-3372E9D0EFA7@oracle.com> Here's the updated webrev: http://cr.openjdk.java.net/~prappo/8044627/webrev.01/ -Pavel On 22 Sep 2014, at 09:55, Alan Bateman wrote: > On 16/09/2014 12:12, Pavel Rappo wrote: >> Hi everyone, >> >> Could you please review my change for JDK-8044627? >> > Pavel - are you planning to send an updated webrev based on the discussion so far? > > The other thing that I meant to ask is whether this change will add service configuration files for the RMI, DNS and CosNaming implementations, maybe this is going to be another patch? > > -Alan From konstantin.shefov at oracle.com Tue Oct 14 12:58:22 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Tue, 14 Oct 2014 16:58:22 +0400 Subject: [9] Review request : JDK-8059070: [TESTBUG] java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java failed - timeout Message-ID: <543D1DEE.8030206@oracle.com> Hello, Please review the test bug fix https://bugs.openjdk.java.net/browse/JDK-8059070 Webrev is http://cr.openjdk.java.net/~kshefov/8059070/webrev.00/ Thanks -Konstantin From pavel.rappo at oracle.com Tue Oct 14 14:03:53 2014 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Tue, 14 Oct 2014 15:03:53 +0100 Subject: RFR JDK-8044627: Update JNDI to work with modules In-Reply-To: <543D28DA.40402@oracle.com> References: <541FE404.8080503@oracle.com> <11A1E834-2978-45F9-B057-3372E9D0EFA7@oracle.com> <543D2666.1070809@oracle.com> <543D28DA.40402@oracle.com> Message-ID: <90BD8855-2945-4293-8959-B76B4940A613@oracle.com> OK, so what I will do for now is I exclude these 4 files and push without them. I'll create a new issue to add them later. -Pavel On 14 Oct 2014, at 14:44, Alan Bateman wrote: > On 14/10/2014 14:34, Daniel Fuchs wrote: >> Hi Pavel, >> >> I saw your mail on build-dev. >> I guess the issue will resolve itself once we have the >> modular image. >> >> I wonder whether the way to go for now would be >> to add a single META-INF/services file - as you suggest - >> in java.naming, with the 4 lines inside, and log a bug/RFE >> to follow up on that once the modular image is there. >> >> best regards, >> >> -- daniel > Once we move to modules then these service configuration files will go away. The resolver will build a service-use graph based on the provides/uses in the module descriptors and that will link the JNDI module to the providers. Pavel just needs a short term solution and having all the providers in one file is okay for that. A better short term solution is to just concatenate them in the build, we are already doing this in the jigsaw/m2 forest for the JDI connectors. > > -Alan From chris.hegarty at oracle.com Tue Oct 14 14:09:23 2014 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Tue, 14 Oct 2014 15:09:23 +0100 Subject: RFR JDK-8044627: Update JNDI to work with modules In-Reply-To: <90BD8855-2945-4293-8959-B76B4940A613@oracle.com> References: <541FE404.8080503@oracle.com> <11A1E834-2978-45F9-B057-3372E9D0EFA7@oracle.com> <543D2666.1070809@oracle.com> <543D28DA.40402@oracle.com> <90BD8855-2945-4293-8959-B76B4940A613@oracle.com> Message-ID: <7263E2E3-6FF4-4CE8-AEB8-57156239CE91@oracle.com> On 14 Oct 2014, at 15:03, Pavel Rappo wrote: > OK, so what I will do for now is I exclude these 4 files and push without them. I'll create a new issue to add them later. That sounds like a fine plan. This issue has already gone on for long enough, and I don?t think that the crooks of the change should have to wait even longer. Consider this issue Reviewed, provided that the changes in the webrev minus the 4 services files compile and test ok. Then you can push the services files once build support is added. -Chris. > -Pavel > > On 14 Oct 2014, at 14:44, Alan Bateman wrote: > >> On 14/10/2014 14:34, Daniel Fuchs wrote: >>> Hi Pavel, >>> >>> I saw your mail on build-dev. >>> I guess the issue will resolve itself once we have the >>> modular image. >>> >>> I wonder whether the way to go for now would be >>> to add a single META-INF/services file - as you suggest - >>> in java.naming, with the 4 lines inside, and log a bug/RFE >>> to follow up on that once the modular image is there. >>> >>> best regards, >>> >>> -- daniel >> Once we move to modules then these service configuration files will go away. The resolver will build a service-use graph based on the provides/uses in the module descriptors and that will link the JNDI module to the providers. Pavel just needs a short term solution and having all the providers in one file is okay for that. A better short term solution is to just concatenate them in the build, we are already doing this in the jigsaw/m2 forest for the JDI connectors. >> >> -Alan > From daniel.fuchs at oracle.com Tue Oct 14 14:15:49 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Tue, 14 Oct 2014 16:15:49 +0200 Subject: RFR JDK-8044627: Update JNDI to work with modules In-Reply-To: <7263E2E3-6FF4-4CE8-AEB8-57156239CE91@oracle.com> References: <541FE404.8080503@oracle.com> <11A1E834-2978-45F9-B057-3372E9D0EFA7@oracle.com> <543D2666.1070809@oracle.com> <543D28DA.40402@oracle.com> <90BD8855-2945-4293-8959-B76B4940A613@oracle.com> <7263E2E3-6FF4-4CE8-AEB8-57156239CE91@oracle.com> Message-ID: <543D3015.7070502@oracle.com> On 14/10/14 16:09, Chris Hegarty wrote: > On 14 Oct 2014, at 15:03, Pavel Rappo wrote: > >> OK, so what I will do for now is I exclude these 4 files and push without them. I'll create a new issue to add them later. > > That sounds like a fine plan. This issue has already gone on for long enough, and I don?t think that the crooks of the change should have to wait even longer. Right. I see it now. If you have no providers - then the old 'helper.loadClass(className).newInstance();' code will be executed - which should still work for now. So not pushing the META-INF/services files sounds fine. best regards, -- daniel > > Consider this issue Reviewed, provided that the changes in the webrev minus the 4 services files compile and test ok. Then you can push the services files once build support is added. > > -Chris. > >> -Pavel >> >> On 14 Oct 2014, at 14:44, Alan Bateman wrote: >> >>> On 14/10/2014 14:34, Daniel Fuchs wrote: >>>> Hi Pavel, >>>> >>>> I saw your mail on build-dev. >>>> I guess the issue will resolve itself once we have the >>>> modular image. >>>> >>>> I wonder whether the way to go for now would be >>>> to add a single META-INF/services file - as you suggest - >>>> in java.naming, with the 4 lines inside, and log a bug/RFE >>>> to follow up on that once the modular image is there. >>>> >>>> best regards, >>>> >>>> -- daniel >>> Once we move to modules then these service configuration files will go away. The resolver will build a service-use graph based on the provides/uses in the module descriptors and that will link the JNDI module to the providers. Pavel just needs a short term solution and having all the providers in one file is okay for that. A better short term solution is to just concatenate them in the build, we are already doing this in the jigsaw/m2 forest for the JDI connectors. >>> >>> -Alan >> > From amy.lu at oracle.com Tue Oct 14 14:19:29 2014 From: amy.lu at oracle.com (Amy Lu) Date: Tue, 14 Oct 2014 22:19:29 +0800 Subject: RFR 8060432: tools/pack200/TestNormal.java fails on Windows with java.io.FileNotFoundException after JDK-8058854 Message-ID: <543D30F1.2090505@oracle.com> Please review the test fix. bug: https://bugs.openjdk.java.net/browse/JDK-8060432 webrev: http://cr.openjdk.java.net/~weijun/8060432/webrev.00/ This test is to test compareJars(new JarFile("normalized.jar"), new JarFile("repacked.jar")); where the jar files (normalized.jar repacked.jar and original.jar) are created by "jar cnf" "jar cf" or "pack200 -r?. extractJar(JarFile jf, File where) is not really needed as this method just try to provide some files for the test to do "jar cnf?. Actually, "jar cnf" can work on any files, test just need some files to jar with. Test can just simply created some files for that purpose. Thanks, Amy From chris.hegarty at oracle.com Tue Oct 14 14:33:07 2014 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Tue, 14 Oct 2014 15:33:07 +0100 Subject: RFR JDK-8044627: Update JNDI to work with modules In-Reply-To: <543D3015.7070502@oracle.com> References: <541FE404.8080503@oracle.com> <11A1E834-2978-45F9-B057-3372E9D0EFA7@oracle.com> <543D2666.1070809@oracle.com> <543D28DA.40402@oracle.com> <90BD8855-2945-4293-8959-B76B4940A613@oracle.com> <7263E2E3-6FF4-4CE8-AEB8-57156239CE91@oracle.com> <543D3015.7070502@oracle.com> Message-ID: <6AF45538-5139-4102-868C-14FA1560213F@oracle.com> On 14 Oct 2014, at 15:15, Daniel Fuchs wrote: > On 14/10/14 16:09, Chris Hegarty wrote: >> On 14 Oct 2014, at 15:03, Pavel Rappo wrote: >> >>> OK, so what I will do for now is I exclude these 4 files and push without them. I'll create a new issue to add them later. >> >> That sounds like a fine plan. This issue has already gone on for long enough, and I don?t think that the crooks of the change should have to wait even longer. > > Right. I see it now. If you have no providers - then the old > 'helper.loadClass(className).newInstance();' > code will be executed - which should still work for now. Exactly. > So not pushing the META-INF/services files sounds fine. Erik just pinged me in relation to the META-INF files in the webrev, two of which are in the wrong location. They are directly under 'META-INF?, where they should all be under ?META-INF/services?. This is just a note for Pavel, when he follows up later with the addition of these service configuration files, and also to avoid confusion. -Chris. > best regards, > > -- daniel > >> >> Consider this issue Reviewed, provided that the changes in the webrev minus the 4 services files compile and test ok. Then you can push the services files once build support is added. >> >> -Chris. >> >>> -Pavel >>> >>> On 14 Oct 2014, at 14:44, Alan Bateman wrote: >>> >>>> On 14/10/2014 14:34, Daniel Fuchs wrote: >>>>> Hi Pavel, >>>>> >>>>> I saw your mail on build-dev. >>>>> I guess the issue will resolve itself once we have the >>>>> modular image. >>>>> >>>>> I wonder whether the way to go for now would be >>>>> to add a single META-INF/services file - as you suggest - >>>>> in java.naming, with the 4 lines inside, and log a bug/RFE >>>>> to follow up on that once the modular image is there. >>>>> >>>>> best regards, >>>>> >>>>> -- daniel >>>> Once we move to modules then these service configuration files will go away. The resolver will build a service-use graph based on the provides/uses in the module descriptors and that will link the JNDI module to the providers. Pavel just needs a short term solution and having all the providers in one file is okay for that. A better short term solution is to just concatenate them in the build, we are already doing this in the jigsaw/m2 forest for the JDI connectors. >>>> >>>> -Alan >>> >> > From pavel.rappo at oracle.com Tue Oct 14 14:36:41 2014 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Tue, 14 Oct 2014 15:36:41 +0100 Subject: RFR JDK-8044627: Update JNDI to work with modules In-Reply-To: <6AF45538-5139-4102-868C-14FA1560213F@oracle.com> References: <541FE404.8080503@oracle.com> <11A1E834-2978-45F9-B057-3372E9D0EFA7@oracle.com> <543D2666.1070809@oracle.com> <543D28DA.40402@oracle.com> <90BD8855-2945-4293-8959-B76B4940A613@oracle.com> <7263E2E3-6FF4-4CE8-AEB8-57156239CE91@oracle.com> <543D3015.7070502@oracle.com> <6AF45538-5139-4102-868C-14FA1560213F@oracle.com> Message-ID: Thanks a lot! -Pavel On 14 Oct 2014, at 15:33, Chris Hegarty wrote: > META-INF files in the webrev, two of which are in the wrong location. They are directly under 'META-INF?, where they should all be under ?META-INF/services?. This is just a note for Pavel, when he follows up later with the addition of these service configuration files, and also to avoid confusion. From aleksey.shipilev at oracle.com Tue Oct 14 16:05:56 2014 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Tue, 14 Oct 2014 18:05:56 +0200 Subject: RFR (XS) 8060485: (str) contentEquals checks the String contents twice on mismatch Message-ID: <543D49E4.6060309@oracle.com> Hi, Please review a trivial change in String.contentEquals: https://bugs.openjdk.java.net/browse/JDK-8060485 http://cr.openjdk.java.net/~shade/8060485/webrev.00/ It improves the performance drastically: http://cr.openjdk.java.net/~shade/8060485/perf.txt ...not to mention it improves the code readability, and protects us from rogue CharSequence-s. Testing: microbenchmarks, jdk/test/String* jtreg. Thanks, -Aleksey. From martinrb at google.com Tue Oct 14 16:33:42 2014 From: martinrb at google.com (Martin Buchholz) Date: Tue, 14 Oct 2014 09:33:42 -0700 Subject: RFR (XS) 8060485: (str) contentEquals checks the String contents twice on mismatch In-Reply-To: <543D49E4.6060309@oracle.com> References: <543D49E4.6060309@oracle.com> Message-ID: Looks good to me! On Tue, Oct 14, 2014 at 9:05 AM, Aleksey Shipilev < aleksey.shipilev at oracle.com> wrote: > Hi, > > Please review a trivial change in String.contentEquals: > https://bugs.openjdk.java.net/browse/JDK-8060485 > http://cr.openjdk.java.net/~shade/8060485/webrev.00/ > > It improves the performance drastically: > http://cr.openjdk.java.net/~shade/8060485/perf.txt > > ...not to mention it improves the code readability, and protects us from > rogue CharSequence-s. > > Testing: microbenchmarks, jdk/test/String* jtreg. > > Thanks, > -Aleksey. > > From chris.hegarty at oracle.com Tue Oct 14 17:13:54 2014 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Tue, 14 Oct 2014 18:13:54 +0100 Subject: RFR (XS) 8060485: (str) contentEquals checks the String contents twice on mismatch In-Reply-To: References: <543D49E4.6060309@oracle.com> Message-ID: <2718EC0D-A8D2-4A8B-B7D8-98981930E0BA@oracle.com> On 14 Oct 2014, at 17:33, Martin Buchholz wrote: > Looks good to me! +1 'noreg-hard' -Chris. > On Tue, Oct 14, 2014 at 9:05 AM, Aleksey Shipilev < > aleksey.shipilev at oracle.com> wrote: > >> Hi, >> >> Please review a trivial change in String.contentEquals: >> https://bugs.openjdk.java.net/browse/JDK-8060485 >> http://cr.openjdk.java.net/~shade/8060485/webrev.00/ >> >> It improves the performance drastically: >> http://cr.openjdk.java.net/~shade/8060485/perf.txt >> >> ...not to mention it improves the code readability, and protects us from >> rogue CharSequence-s. >> >> Testing: microbenchmarks, jdk/test/String* jtreg. >> >> Thanks, >> -Aleksey. >> >> From stanimir at riflexo.com Tue Oct 14 17:32:26 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Tue, 14 Oct 2014 20:32:26 +0300 Subject: RFR (XS) 8060485: (str) contentEquals checks the String contents twice on mismatch In-Reply-To: <2718EC0D-A8D2-4A8B-B7D8-98981930E0BA@oracle.com> References: <543D49E4.6060309@oracle.com> <2718EC0D-A8D2-4A8B-B7D8-98981930E0BA@oracle.com> Message-ID: Hi, This is an unrelated issue, yet is there any reason for the inner loop of equals to be written in such a (confusing) way? if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } instead of just "for (int i=0;i wrote: > On 14 Oct 2014, at 17:33, Martin Buchholz wrote: > > > Looks good to me! > > +1 'noreg-hard' > > -Chris. > > > On Tue, Oct 14, 2014 at 9:05 AM, Aleksey Shipilev < > > aleksey.shipilev at oracle.com> wrote: > > > >> Hi, > >> > >> Please review a trivial change in String.contentEquals: > >> https://bugs.openjdk.java.net/browse/JDK-8060485 > >> http://cr.openjdk.java.net/~shade/8060485/webrev.00/ > >> > >> It improves the performance drastically: > >> http://cr.openjdk.java.net/~shade/8060485/perf.txt > >> > >> ...not to mention it improves the code readability, and protects us from > >> rogue CharSequence-s. > >> > >> Testing: microbenchmarks, jdk/test/String* jtreg. > >> > >> Thanks, > >> -Aleksey. > >> > >> > > From aleksey.shipilev at oracle.com Tue Oct 14 17:38:22 2014 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Tue, 14 Oct 2014 19:38:22 +0200 Subject: RFR (XS) 8060485: (str) contentEquals checks the String contents twice on mismatch In-Reply-To: <2718EC0D-A8D2-4A8B-B7D8-98981930E0BA@oracle.com> References: <543D49E4.6060309@oracle.com> <2718EC0D-A8D2-4A8B-B7D8-98981930E0BA@oracle.com> Message-ID: <543D5F8E.9010002@oracle.com> Thanks guys! And of course, I managed to do two minor mistakes in a two-line change: the indentation is a bit wrong, and cast to String is redundant. Here is the updated webrev and the changeset (need a Sponsor!): http://cr.openjdk.java.net/~shade/8060485/webrev.01/ http://cr.openjdk.java.net/~shade/8060485/8060485.changeset -Aleksey. On 14.10.2014 19:13, Chris Hegarty wrote: > On 14 Oct 2014, at 17:33, Martin Buchholz wrote: > >> Looks good to me! > > +1 'noreg-hard' > > -Chris. > >> On Tue, Oct 14, 2014 at 9:05 AM, Aleksey Shipilev < >> aleksey.shipilev at oracle.com> wrote: >> >>> Hi, >>> >>> Please review a trivial change in String.contentEquals: >>> https://bugs.openjdk.java.net/browse/JDK-8060485 >>> http://cr.openjdk.java.net/~shade/8060485/webrev.00/ >>> >>> It improves the performance drastically: >>> http://cr.openjdk.java.net/~shade/8060485/perf.txt >>> >>> ...not to mention it improves the code readability, and protects us from >>> rogue CharSequence-s. >>> >>> Testing: microbenchmarks, jdk/test/String* jtreg. >>> >>> Thanks, >>> -Aleksey. >>> >>> > From aleksey.shipilev at oracle.com Tue Oct 14 17:41:08 2014 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Tue, 14 Oct 2014 19:41:08 +0200 Subject: RFR (XS) 8060485: (str) contentEquals checks the String contents twice on mismatch In-Reply-To: References: <543D49E4.6060309@oracle.com> <2718EC0D-A8D2-4A8B-B7D8-98981930E0BA@oracle.com> Message-ID: <543D6034.1050303@oracle.com> On 14.10.2014 19:32, Stanimir Simeonoff wrote: > Hi, > > This is an unrelated issue, yet is there any reason for the inner loop > of equals to be written in such a (confusing) way? > > if (n == anotherString.value.length) { > char v1[] = value; > char v2[] = anotherString.value; > int i = 0; > while (n-- != 0) { > if (v1[i] != v2[i]) > return false; > i++; > } > return true; > } > > instead of just "for (int i=0;i References: <54382E90.7040105@oracle.com> <03B32851-A9DB-4C43-ABB3-2CFE36D7CB0C@oracle.com> Message-ID: <543D717C.3090508@oracle.com> Paul, Thanks for the feedback! Updated version: http://cr.openjdk.java.net/~vlivanov/8059877/webrev.01/ >> http://cr.openjdk.java.net/~vlivanov/8059877/webrev.00/ >> https://bugs.openjdk.java.net/browse/JDK-8059877 >> > > Generally looks ok. > > - MethodHandleImpl > > 786 if (wrapper.unblock()) { > 787 // Reached invocation threshold. Replace counting/blocking wrapper with a reinvoker. > 788 wrapper.isActivated = false; > > If unblock() returns true then isActivated is already false. Fixed. > At the expense of another box you could use an AtomicBoolean with compareAndSet if you want to really guarantee at most one unblocking, although the box can be removed if the boolean is changed to 'int' and Unsafe is used to CAS. I considered that, but I decided not to go that route. GuardWithTest is a very common combinator, so footprint overhead could be noticeable. There's no need to guarantee uniqueness of unblocking operation. The operation is idempotent, so no problems performing it multiple times. What I try to achieve with the flag is avoid pathological situation when some thread continuously updates the form. > I dunno if strengthening the visibility of MethodHandle.form by stamping in a memory fence after the following will help > > 792 wrapper.updateForm(lform); > > e.g. using Unsafe.fullFence. I think the fence should be there. It won't help guarantee the update is visible everywhere though. But it is expected. > Perhaps isUnblocked is a better name than isActivated since there is no need to set the initial value and it tracks the same value as that returned from unblock? Done. > Also while on the subject of naming perhaps consider changing MethodTypeForm.LF_DELEGATE_COUNTING to ...LF_DELEGATE_BLOCK_INLINING? Done. > When DONT_INLINE_THRESHOLD > 0 and DONT_INLINE_THRESHOLD == COMPILE_THRESHOLD will that trigger both compilation of a BlockInliningWrapper's form and unblocking? I guess there is some fuzziness depending on concurrent execution. No problems expected in this scenario - COMPILE_THRESHOLD updates LambdaForm entry point and unblocking operates on a method handle. > I am just wondering if there is any point compiling a BlockInliningWrapper's form if DONT_INLINE_THRESHOLD is expected to be ~ the same as COMPILE_THRESHOLD. Probably not terribly important especially if the JIT-compiler control approach replaces it. I don't see any value in keeping BlockInliningWrapper interpreted. It would allow to avoid LambdaForm.forceInline flag, but there should be a special case to skip compilation (in LambdaForm::checkInvocationCounter()). Moreover, if we get rid of LambdaForm interpreter, we will need to precompile BlockInliningWrapper again. Best regards, Vladimir Ivanov From Alan.Bateman at oracle.com Tue Oct 14 19:55:59 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 14 Oct 2014 20:55:59 +0100 Subject: RFR (XS) 8060485: (str) contentEquals checks the String contents twice on mismatch In-Reply-To: <543D5F8E.9010002@oracle.com> References: <543D49E4.6060309@oracle.com> <2718EC0D-A8D2-4A8B-B7D8-98981930E0BA@oracle.com> <543D5F8E.9010002@oracle.com> Message-ID: <543D7FCF.1020009@oracle.com> On 14/10/2014 18:38, Aleksey Shipilev wrote: > Thanks guys! > > And of course, I managed to do two minor mistakes in a two-line change: > the indentation is a bit wrong, and cast to String is redundant. Here is > the updated webrev and the changeset (need a Sponsor!): > http://cr.openjdk.java.net/~shade/8060485/webrev.01/ > http://cr.openjdk.java.net/~shade/8060485/8060485.changeset > > -Aleksey. > Updated version looks okay. I wonder how common it might be to call this method with String vs. a StringBuilder, just wondering if it should check for a String first (although the type check should be really quick and probably wouldn't make a difference). -Alan From stanimir at riflexo.com Tue Oct 14 20:20:20 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Tue, 14 Oct 2014 23:20:20 +0300 Subject: RFR (XS) 8060485: (str) contentEquals checks the String contents twice on mismatch In-Reply-To: <543D7FCF.1020009@oracle.com> References: <543D49E4.6060309@oracle.com> <2718EC0D-A8D2-4A8B-B7D8-98981930E0BA@oracle.com> <543D5F8E.9010002@oracle.com> <543D7FCF.1020009@oracle.com> Message-ID: a On Tue, Oct 14, 2014 at 10:55 PM, Alan Bateman wrote: > On 14/10/2014 18:38, Aleksey Shipilev wrote: > >> Thanks guys! >> >> And of course, I managed to do two minor mistakes in a two-line change: >> the indentation is a bit wrong, and cast to String is redundant. Here is >> the updated webrev and the changeset (need a Sponsor!): >> http://cr.openjdk.java.net/~shade/8060485/webrev.01/ >> http://cr.openjdk.java.net/~shade/8060485/8060485.changeset >> >> -Aleksey. >> >> > Updated version looks okay. I wonder how common it might be to call this > method with String vs. a StringBuilder, just wondering if it should check > for a String first (although the type check should be really quick and > probably wouldn't make a difference). > > I was wondering the exactly same but usually allowing CharSequence in the code means "likely no String", so while there is no statistical evidence it seems reasonable. Another minor issue is the legacy contentEquals(StringBuffer sb) that can call directly synchronized(sb){nonSyncContentEquals(sb);} but C2 should be able to inline it pretty good just in case. Stanimir From kumar.x.srinivasan at oracle.com Tue Oct 14 20:44:23 2014 From: kumar.x.srinivasan at oracle.com (Kumar Srinivasan) Date: Tue, 14 Oct 2014 13:44:23 -0700 Subject: RFR 8060432: tools/pack200/TestNormal.java fails on Windows with java.io.FileNotFoundException after JDK-8058854 In-Reply-To: <543D30F1.2090505@oracle.com> References: <543D30F1.2090505@oracle.com> Message-ID: <543D8B27.5090201@oracle.com> Amy, The modifications you have made will not test pack200 compression and normalization correctly, as the test needs ".class" files. Do you know why the test fails on windows ? Kumar On 10/14/2014 7:19 AM, Amy Lu wrote: > Please review the test fix. > > bug: https://bugs.openjdk.java.net/browse/JDK-8060432 > webrev: http://cr.openjdk.java.net/~weijun/8060432/webrev.00/ > > This test is to test > compareJars(new JarFile("normalized.jar"), new JarFile("repacked.jar")); > where the jar files (normalized.jar repacked.jar and original.jar) are > created by "jar cnf" "jar cf" or "pack200 -r?. > > extractJar(JarFile jf, File where) is not really needed as this method > just try to provide some files for the test to do "jar cnf?. Actually, > "jar cnf" can work on any files, test just need some files to jar with. > > Test can just simply created some files for that purpose. > > Thanks, > Amy > From tristan.yan at oracle.com Tue Oct 14 21:57:27 2014 From: tristan.yan at oracle.com (Tristan Yan) Date: Tue, 14 Oct 2014 14:57:27 -0700 Subject: Review request for JDK-8051561: Convert JAXP function tests: javax.xml.xpath.* to jtreg (testNG) tests In-Reply-To: <5400C4A4.1080907@oracle.com> References: <53D257BB.8010303@oracle.com> <6587E2F4-B626-43BE-9D76-6295CBCD22F4@oracle.com> <5400C4A4.1080907@oracle.com> Message-ID: <4FE08FAC-2BB6-4C7A-8718-5E9199707CB1@oracle.com> Hi Joe If you?re okay with the code; would you be my sponsor for this. We need move forward and push these tests into openjdk repo. Thank you so much Tristan > On Aug 29, 2014, at 11:21 AM, huizhe wang wrote: > > Hi Tristan, > > Looks good. I left notes in the bug's comment section as a record and status of the original test development. > > Thanks, > Joe > > On 8/29/2014 9:50 AM, Tristan Yan wrote: >> Hi Joe, Alan and others >> I took over Eric?s last work and did some refactor for his code. Please help to review the code change again. >> webrev: http://cr.openjdk.java.net/~tyan/JDK-8051561/webrev.01/ >> bug: https://bugs.openjdk.java.net/browse/JDK-8051561 >> >> These code has been run with security manager and without security manager both and all passed. >> Thank you >> Tristan >> >>> On Jul 25, 2014, at 6:12 AM, Eric Wang > wrote: >>> >>> Hi Joe, alan and every one >>> >>> I'm working on jaxp functional test colocation which is traced by the bug JDK-8043091 . >>> We have finished to convert a few suite and the jaxp/xpath tracked by bug JDK-8051561 is the first one chosen for public review. >>> >>> Can you please review the webrev below? your comments given would be helpful for our future work. >>> http://cr.openjdk.java.net/~ewang/JDK-8051561/webrev.00/ >>> >>> Thanks, >>> Eric >>> >> > From tristan.yan at oracle.com Tue Oct 14 22:10:09 2014 From: tristan.yan at oracle.com (Tristan Yan) Date: Tue, 14 Oct 2014 15:10:09 -0700 Subject: Review request for JDK-8051540: Convert JAXP functin tests: org.xml.sax to jtreg (testNG) tests In-Reply-To: <53FE6BF9.3070305@oracle.com> References: <53D257BB.8010303@oracle.com> <2DA2DB81-DAC7-431C-AFD7-A73CB0C748C6@oracle.com> <53F28CF9.9030907@oracle.com> <87EB6F2A-260C-4419-9A65-D46A2AFEA0A2@oracle.com> <53F38A26.2080608@oracle.com> <53FE6BF9.3070305@oracle.com> Message-ID: <527B8686-4173-4FC6-9245-D0F7A35D0FB0@oracle.com> Hi Joe Could you be my sponsor to push this if you?re okay with the code. Thank you Tristan > On Aug 27, 2014, at 4:38 PM, huizhe wang wrote: > > > On 8/27/2014 4:03 PM, Tristan Yan wrote: >> Hi Joe and others >> >> I updated the tests with putting them in jaxp repo. I also run these tests with security manager and they all passed >> http://cr.openjdk.java.net/~tyan/JDK-8051540/webrev01/ >> > > Awesome. > >> Also I?d like to propose our way for handling jaxp tests run with security manager. The way we?d use is creating two targets for running jaxp tests. One is for normal run; which will run all the tests without security manager. One is secure run; the target only run the tests that have to be run with security manager. This could be easy to be handled with adding two targets in makefile. And for most of people they only care about the function. They only need run normal run target. We would run two targets for any of our formal tests like nightly, ci build and jprt tests. > > Yes, please coordinate with Frank and Eric so that all of the jaxp tests share the same configuration. > >> For the tests which can not be run in secure mode(like tests for xsltc direct extension), we'd add testng group called ?secure-hostile?. We won?t run these tests in secure mode by bypassing them in secure run target. By this way we could easily transform our tests as usual without additional effort. > > I had been previously updated them so that all of the tests were capable of running with and without security manager. Sustaining SQE had invested several month to incorporate the changes into that hosted in Aurora. Please consider taking the patches from them if you haven't already done so. > > Thanks, > Joe > >> >> Thank you >> Tristan >> >>> On Aug 19, 2014, at 10:32 AM, huizhe wang > wrote: >>> >>> By the way, the plan has been that all of the JAXP SQE and Unit tests be migrated into [openjdk]/jaxp repo under jaxp/test. Tests currently in the jdk repo shall be moved to jaxp/test as well. I see that your webrev was generated in jdk9/dev/jdk. I hope it doesn't mean you're checking tests into the jdk repo. >>> >>> Thanks, >>> Joe >>> >>> On 8/18/2014 4:42 PM, Tristan Yan wrote: >>>> Thanks Joe >>>> We intend to replace the base class with test library because that doesn?t look like a real base class but an utilities class. >>>> I haven?t tried to run these tests with security manager, I will run them with security manager then get back you soon. >>>> Thank you. >>>> Tristan >>>> >>>>> On Aug 18, 2014, at 4:32 PM, huizhe wang > wrote: >>>>> >>>>> >>>> >>> >> > From mandy.chung at oracle.com Wed Oct 15 00:22:52 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 14 Oct 2014 17:22:52 -0700 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543BCAA3.7020003@redhat.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <543BCAA3.7020003@redhat.com> Message-ID: <543DBE5C.1070907@oracle.com> On 10/13/2014 5:50 AM, David M. Lloyd wrote: > On 10/10/2014 07:31 PM, Mandy Chung wrote: >> >> On 10/10/2014 8:10 AM, Claes Redestad wrote: >>> Hi all, >>> >>> please review this patch which attempts to clean up synchronization >>> and improve scalability when >>> defining and getting java.lang.Package objects. >> >> I agree with David that getting Package objects are not performance >> critical. On the other hand, the code defining/getting Packages is >> old and deserves some cleanup especially the synchronization part. > > I have a little more information on this subject. We've a possible > (and somewhat likely) deadlock which occurs because one thread can > attempt to define a system class while holding the > java.lang.Package#pkgs lock, while another thread can attempt to get a > package while defining a system class (while holding the class loader > lock). I do not recall whether parallel class loading alleviates this > issue. We solved the problem by loading Packages.getPackages() in > early (single-threaded) bootstrap. > Do you recall what JDK version you observed this possible deadlock? I wonder if the fix for 7001933 [1] in JDK 7 and 6u25 resolved the deadlock problem you ran into. [1] http://hg.openjdk.java.net/jdk9/dev/jdk/rev/4a7da412db38 > So from my perspective, just getting rid of the synchronization on > that field alone makes this change worthwhile. Yes that's what I think too. Mandy From mandy.chung at oracle.com Wed Oct 15 01:07:37 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 14 Oct 2014 18:07:37 -0700 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543BF29E.70303@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> Message-ID: <543DC8D9.8010709@oracle.com> Claes, Peter, Thanks for the revised webrev and Peter's thorough review. webrev.05 looks much better. My comment is mostly minor. On 10/13/2014 8:41 AM, Claes Redestad wrote: > http://cr.openjdk.java.net/~redestad/8060130/webrev.05 ClassLoader.java line 1582-1586 - I suggest to get rid of the "oldpkg" variable (it's really the package to be used and not an old pkg). pkg = new Package(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase, this); if (packages.putIfAbsent(name, pkg) != null) { throw new IllegalArgumentException(name + " already defined"); } return pkg; line 1634-1635: nit: the pkgName variable is not really needed. it's in the existing code and probably good to remove it. Package.java line 473: maybe better to leave the ClassLoader parameter in the constructor. I thought about adding a comment saying that this private constructor is only used for system package but keeping the loader parameter makes it more explicit. line 569: nit: formatting - indent to the right to align the first parameter to new Package(...) line 621-623: is this really needed? Uncontended case seems to be the common case. It seems the synchronized overhead would be insignificant. line 624: a space is missing between synchronized and "(" Looks like there is one test jdk/test/java/lang/ClassLoader/GetPackage.java about packages. Can you add a new test to verify the system packages as that is one major change in your patch? Thanks Mandy From mandy.chung at oracle.com Wed Oct 15 01:23:15 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 14 Oct 2014 18:23:15 -0700 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543B95B1.2090806@gmail.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543B3675.2000802@oracle.com> <543B95B1.2090806@gmail.com> Message-ID: <543DCC83.4010702@oracle.com> On 10/13/2014 2:04 AM, Peter Levart wrote: > On 10/13/2014 04:18 AM, David Holmes wrote: >> >> Looking at definePackage it seems both old and new code have serious >> race conditions due to a lack of atomicity when checking the >> parent/system packages. A package of the same name could be defined >> in the parent/system after definePackage has called getPackage - and >> we then end up with two same named Packages in different loaders. > I don't know the history of the getPackage(s) methods. Since two different class loaders can define a package of the same name and effectively two separate runtime packages, it seems to me that ClassLoader.getPackages should return all Package objects including the duplicated names. Claes - do you mind filing a bug for it? > ... > p1: package javax.swing > p2: package javax.swing, Java Platform API Specification, version 1.9 > p3: package javax.swing, Java Platform API Specification, version 1.9 > > > Now if the order of class loading is changed: > > ... > p1: package javax.swing, Java Platform API Specification, version 1.9 > p2: package javax.swing, Java Platform API Specification, version 1.9 > p3: package javax.swing, Java Platform API Specification, version 1.9 > > > So reliable "sealed" packages can only exist if they are defined > in-advance or at least one class from a particular sealed package is > loaded by the authoritative ClassLoader before a child of that loader > is given a chance to load classes. > > A: So perhaps, to support class-loading-order independent behaviour, a > descendant ClassLoader could be given a chance to define it's own > package although the ancestor has already defined one with the same > name, unless this is a sealed package of course. > > B: A backwards-incompatible and more restrictive strategy could be to > prevent an ancestor ClassLoader from defining a Package if one of > descendants in the chain leading from initiating ClassLoader to the > ancestor already defines a package with the same name. This would not > prevent loading of such "conflicting" classes for the entire system, > but only for a particular code that happens to be defined by the > ClassLoader that (or it's ancestor) violates the constraint that a > descendant ClassLoader must not define classes in the package of the > same name as ancestor ClassLoader. It would prevent classes loaded by > a violating ClassLoader from accessing classes in sealed packages, > which might be enough to enforce intra-package access restrictions... > > How does Jigsaw solve this puzzle? java.lang.Package is not used at runtime. I think ClassLoader.getPackage(s) method should be revisited whether it should lookup its parent loader. I think your question concerns the runtime package that is not effect by java.lang.Package. Mandy From amy.lu at oracle.com Wed Oct 15 02:42:41 2014 From: amy.lu at oracle.com (Amy Lu) Date: Wed, 15 Oct 2014 10:42:41 +0800 Subject: RFR 8060432: tools/pack200/TestNormal.java fails on Windows with java.io.FileNotFoundException after JDK-8058854 In-Reply-To: <543D8B27.5090201@oracle.com> References: <543D30F1.2090505@oracle.com> <543D8B27.5090201@oracle.com> Message-ID: <543DDF21.7090402@oracle.com> On 10/15/14, 4:44 AM, Kumar Srinivasan wrote: > Amy, > > The modifications you have made will not test pack200 compression > and normalization correctly, as the test needs ".class" files. Sorry, I missed that. Please review the updated version, test works on ".class" files (Utils.TEST_CLS_DIR) http://cr.openjdk.java.net/~weijun/8060432/webrev.01/ > Do you know > why the test fails on windows ? extractJar(JarFile jf, File where) try to extract jar files to folder "testdir", as the jar contains files of C:/blabla extractJar method run into issue on Windows as it try to extract it to testdir\\C:\\blabla Anyway, as there already has some ".class" files to working on (Utils.TEST_CLS_DIR), extractJar method is not needed. Thanks, Amy > > Kumar > > > On 10/14/2014 7:19 AM, Amy Lu wrote: >> Please review the test fix. >> >> bug: https://bugs.openjdk.java.net/browse/JDK-8060432 >> webrev: http://cr.openjdk.java.net/~weijun/8060432/webrev.00/ >> >> This test is to test >> compareJars(new JarFile("normalized.jar"), new JarFile("repacked.jar")); >> where the jar files (normalized.jar repacked.jar and original.jar) >> are created by "jar cnf" "jar cf" or "pack200 -r?. >> >> extractJar(JarFile jf, File where) is not really needed as this >> method just try to provide some files for the test to do "jar cnf?. >> Actually, "jar cnf" can work on any files, test just need some files >> to jar with. >> >> Test can just simply created some files for that purpose. >> >> Thanks, >> Amy >> > From aleksey.shipilev at oracle.com Wed Oct 15 07:54:24 2014 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Wed, 15 Oct 2014 09:54:24 +0200 Subject: RFR (XS) 8060485: (str) contentEquals checks the String contents twice on mismatch In-Reply-To: <543D7FCF.1020009@oracle.com> References: <543D49E4.6060309@oracle.com> <2718EC0D-A8D2-4A8B-B7D8-98981930E0BA@oracle.com> <543D5F8E.9010002@oracle.com> <543D7FCF.1020009@oracle.com> Message-ID: <543E2830.9000109@oracle.com> On 14.10.2014 21:55, Alan Bateman wrote: > On 14/10/2014 18:38, Aleksey Shipilev wrote: >> Thanks guys! >> >> And of course, I managed to do two minor mistakes in a two-line change: >> the indentation is a bit wrong, and cast to String is redundant. Here is >> the updated webrev and the changeset (need a Sponsor!): >> http://cr.openjdk.java.net/~shade/8060485/webrev.01/ >> http://cr.openjdk.java.net/~shade/8060485/8060485.changeset >> >> -Aleksey. >> > Updated version looks okay. I wonder how common it might be to call this > method with String vs. a StringBuilder, just wondering if it should > check for a String first (although the type check should be really quick > and probably wouldn't make a difference). Thanks Alan. One of my Twitter followers has pointed this thing to me, so I presume they got hit by this quirk while calling contentEquals with String. I concur the instanceof check is very cheap, and so it does not matter to check the String first. In either case, I think the most preferred way for checking the String vs. String equality is equals(), not contentEquals(). Added you as the reviewer: http://cr.openjdk.java.net/~shade/8060485/8060485.changeset Need a sponsor to push! -Aleksey. From huizhe.wang at oracle.com Wed Oct 15 08:43:49 2014 From: huizhe.wang at oracle.com (huizhe wang) Date: Wed, 15 Oct 2014 01:43:49 -0700 Subject: Review request for JDK-8051540: Convert JAXP functin tests: org.xml.sax to jtreg (testNG) tests In-Reply-To: <527B8686-4173-4FC6-9245-D0F7A35D0FB0@oracle.com> References: <53D257BB.8010303@oracle.com> <2DA2DB81-DAC7-431C-AFD7-A73CB0C748C6@oracle.com> <53F28CF9.9030907@oracle.com> <87EB6F2A-260C-4419-9A65-D46A2AFEA0A2@oracle.com> <53F38A26.2080608@oracle.com> <53FE6BF9.3070305@oracle.com> <527B8686-4173-4FC6-9245-D0F7A35D0FB0@oracle.com> Message-ID: <543E33C5.7000207@oracle.com> Joe, You mentioned recently that you were considering folding the jaxp repo into some other repos. Would it matter if we put these functional tests into the existing jaxp repo (/jaxp/test)? Or, would jaxp tests be under whatever the 'other' repo is? We had planned to migrate jaxp unit and functional tests to jaxp repo/test, and then move jaxp tests currently under jdk/test to jaxp/test as well. These patches are big. I hope we don't have to move them around :-) Thanks, Joe On 10/14/2014 3:10 PM, Tristan Yan wrote: > Hi Joe > Could you be my sponsor to push this if you?re okay with the code. > Thank you > Tristan > >> On Aug 27, 2014, at 4:38 PM, huizhe wang > > wrote: >> >> >> On 8/27/2014 4:03 PM, Tristan Yan wrote: >>> Hi Joe and others >>> >>> I updated the tests with putting them in jaxp repo. I also run these >>> tests with security manager and they all passed >>> http://cr.openjdk.java.net/~tyan/JDK-8051540/webrev01/ >>> >>> >> >> Awesome. >> >>> Also I?d like to propose our way for handling jaxp tests run with >>> security manager. The way we?d use is creating two targets for >>> running jaxp tests. One is for normal run; which will run all the >>> tests without security manager. One is secure run; the target only >>> run the tests that have to be run with security manager. This could >>> be easy to be handled with adding two targets in makefile. And for >>> most of people they only care about the function. They only need run >>> normal run target. We would run two targets for any of our formal >>> tests like nightly, ci build and jprt tests. >> >> Yes, please coordinate with Frank and Eric so that all of the jaxp >> tests share the same configuration. >> >>> For the tests which can not be run in secure mode(like tests for >>> xsltc direct extension), we'd add testng group called >>> ?secure-hostile?. We won?t run these tests in secure mode by >>> bypassing them in secure run target. By this way we could easily >>> transform our tests as usual without additional effort. >> >> I had been previously updated them so that all of the tests were >> capable of running with and without security manager. Sustaining SQE >> had invested several month to incorporate the changes into that >> hosted in Aurora. Please consider taking the patches from them if you >> haven't already done so. >> >> Thanks, >> Joe >> >>> >>> Thank you >>> Tristan >>> >>>> On Aug 19, 2014, at 10:32 AM, huizhe wang >>> > wrote: >>>> >>>> By the way, the plan has been that all of the JAXP SQE and Unit >>>> tests be migrated into [openjdk]/jaxp repo under jaxp/test. Tests >>>> currently in the jdk repo shall be moved to jaxp/test as well. I >>>> see that your webrev was generated in jdk9/dev/jdk. I hope it >>>> doesn't mean you're checking tests into the jdk repo. >>>> >>>> Thanks, >>>> Joe >>>> >>>> On 8/18/2014 4:42 PM, Tristan Yan wrote: >>>>> Thanks Joe >>>>> We intend to replace the base class with test library because that >>>>> doesn?t look like a real base class but an utilities class. >>>>> I haven?t tried to run these tests with security manager, I will >>>>> run them with security manager then get back you soon. >>>>> Thank you. >>>>> Tristan >>>>> >>>>>> On Aug 18, 2014, at 4:32 PM, huizhe wang >>>>> > wrote: >>>>>> >>>>>> >>>>> >>>> >>> >> > From paul.sandoz at oracle.com Wed Oct 15 08:57:36 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 15 Oct 2014 10:57:36 +0200 Subject: RFR (XS) 8060485: (str) contentEquals checks the String contents twice on mismatch In-Reply-To: <543E2830.9000109@oracle.com> References: <543D49E4.6060309@oracle.com> <2718EC0D-A8D2-4A8B-B7D8-98981930E0BA@oracle.com> <543D5F8E.9010002@oracle.com> <543D7FCF.1020009@oracle.com> <543E2830.9000109@oracle.com> Message-ID: <3E2A6DFD-ED6D-48BD-84F3-394331ECD899@oracle.com> On Oct 15, 2014, at 9:54 AM, Aleksey Shipilev wrote: > On 14.10.2014 21:55, Alan Bateman wrote: >> On 14/10/2014 18:38, Aleksey Shipilev wrote: >>> Thanks guys! >>> >>> And of course, I managed to do two minor mistakes in a two-line change: >>> the indentation is a bit wrong, and cast to String is redundant. Here is >>> the updated webrev and the changeset (need a Sponsor!): >>> http://cr.openjdk.java.net/~shade/8060485/webrev.01/ >>> http://cr.openjdk.java.net/~shade/8060485/8060485.changeset >>> >>> -Aleksey. >>> >> Updated version looks okay. I wonder how common it might be to call this >> method with String vs. a StringBuilder, just wondering if it should >> check for a String first (although the type check should be really quick >> and probably wouldn't make a difference). > > Thanks Alan. > > One of my Twitter followers has pointed this thing to me, so I presume > they got hit by this quirk while calling contentEquals with String. I > concur the instanceof check is very cheap, and so it does not matter to > check the String first. In either case, I think the most preferred way > for checking the String vs. String equality is equals(), not > contentEquals(). > > Added you as the reviewer: > http://cr.openjdk.java.net/~shade/8060485/8060485.changeset > > Need a sponsor to push! > I can do it later today. Paul. From paul.sandoz at oracle.com Wed Oct 15 08:59:21 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 15 Oct 2014 10:59:21 +0200 Subject: RFR (XS) 8060485: (str) contentEquals checks the String contents twice on mismatch In-Reply-To: <3E2A6DFD-ED6D-48BD-84F3-394331ECD899@oracle.com> References: <543D49E4.6060309@oracle.com> <2718EC0D-A8D2-4A8B-B7D8-98981930E0BA@oracle.com> <543D5F8E.9010002@oracle.com> <543D7FCF.1020009@oracle.com> <543E2830.9000109@oracle.com> <3E2A6DFD-ED6D-48BD-84F3-394331ECD899@oracle.com> Message-ID: <21E9F931-AEE7-476C-8DD9-822B6B42DE2A@oracle.com> On Oct 15, 2014, at 10:57 AM, Paul Sandoz wrote: >> >> Need a sponsor to push! >> > > I can do it later today. > I knew i should of checked before hand, i see Alan has already pushed it, Pauk. From miroslav.kos at oracle.com Wed Oct 15 11:08:17 2014 From: miroslav.kos at oracle.com (Miroslav Kos) Date: Wed, 15 Oct 2014 13:08:17 +0200 Subject: RFR: 8046817: JDK 8 schemagen tool does not generate xsd files for enum types In-Reply-To: <543CD0E0.7060109@oracle.com> References: <5434FF2D.104@oracle.com> <543CD0E0.7060109@oracle.com> Message-ID: <543E55A1.8060903@oracle.com> Hi Aleksej, the change looks ok to me, but it would be good to integrate it into upstream (standalone JAX-B RI project) first to be on safe side - there are much more tests then in OpenJDK. Copying Iaroslav who is JAX-B RI lead and can help you with integration and running tests. Thanks Miran On 14/10/14 09:29, Aleksej Efimov wrote: > Hi XML experts, > Can I humbly ask to review this simple fix. > > Thank you, > Aleksej > > On 08.10.2014 13:09, Aleksej Efimov wrote: >> Hello, >> >> Please, review the fix [1] for the 8046817 [2]. >> Problem: schemagen tool doesn't generate schema file for the enum >> types [3]. >> SchemaGenerator class gets a list of annotated elements and filters >> out only the class variables, but annotation parser >> (AnnotationParser.java) filters out the Class and Enum. The proposed >> fix solves the problem: SchemaGenerator filters like AnnotationParser. >> Testing: JPRT build and test passes on platforms (with new regression >> test). JTREG tests: javax/xml - no failures. >> >> Thanks, >> Aleksej >> >> [1] Webrev: http://cr.openjdk.java.net/~aefimov/8046817/9/webrev.00/ >> [2] Bug: https://bugs.openjdk.java.net/browse/JDK-8046817 >> [3] Enum type: >> http://cr.openjdk.java.net/~aefimov/8046817/9/webrev.00/jdk/test/javax/xml/ws/8046817/TestEnumType.java.html > From aleksej.efimov at oracle.com Wed Oct 15 11:16:46 2014 From: aleksej.efimov at oracle.com (Aleksej Efimov) Date: Wed, 15 Oct 2014 15:16:46 +0400 Subject: RFR: 8046817: JDK 8 schemagen tool does not generate xsd files for enum types In-Reply-To: <543E55A1.8060903@oracle.com> References: <5434FF2D.104@oracle.com> <543CD0E0.7060109@oracle.com> <543E55A1.8060903@oracle.com> Message-ID: <543E579E.30108@oracle.com> Miran, Thank you for review. I will work with Iaroslav on integration into upstream. Iaroslav, I can prepare the patch for JAX-B RI source code (as we discussed earlier). Do we need to convert new regression test to JAX-B RI unit tests OR we can leave it as it is? Thanks, Aleksej On 10/15/2014 03:08 PM, Miroslav Kos wrote: > Hi Aleksej, > > the change looks ok to me, but it would be good to integrate it into > upstream (standalone JAX-B RI project) first to be on safe side - > there are much more tests then in OpenJDK. > > Copying Iaroslav who is JAX-B RI lead and can help you with > integration and running tests. > > Thanks > Miran > > > On 14/10/14 09:29, Aleksej Efimov wrote: >> Hi XML experts, >> Can I humbly ask to review this simple fix. >> >> Thank you, >> Aleksej >> >> On 08.10.2014 13:09, Aleksej Efimov wrote: >>> Hello, >>> >>> Please, review the fix [1] for the 8046817 [2]. >>> Problem: schemagen tool doesn't generate schema file for the enum >>> types [3]. >>> SchemaGenerator class gets a list of annotated elements and filters >>> out only the class variables, but annotation parser >>> (AnnotationParser.java) filters out the Class and Enum. The proposed >>> fix solves the problem: SchemaGenerator filters like AnnotationParser. >>> Testing: JPRT build and test passes on platforms (with new >>> regression test). JTREG tests: javax/xml - no failures. >>> >>> Thanks, >>> Aleksej >>> >>> [1] Webrev: http://cr.openjdk.java.net/~aefimov/8046817/9/webrev.00/ >>> [2] Bug: https://bugs.openjdk.java.net/browse/JDK-8046817 >>> [3] Enum type: >>> http://cr.openjdk.java.net/~aefimov/8046817/9/webrev.00/jdk/test/javax/xml/ws/8046817/TestEnumType.java.html >> > From vladimir.x.ivanov at oracle.com Wed Oct 15 12:12:45 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Wed, 15 Oct 2014 16:12:45 +0400 Subject: [9] RFR (XS): 8060483: NPE with explicitCastArguments unboxing null Message-ID: <543E64BD.9000103@oracle.com> http://cr.openjdk.java.net/~vlivanov/8060483/webrev.00/ https://bugs.openjdk.java.net/browse/JDK-8060483 Recent changes broke MHs.explicitCastArguments for null values when unboxing taking place. The fix corrects the equivalence check for MHs.eCA & MH.asType() in MT.explicitCastEquivalentToAsType(). Also, will file a followup enhancement request to improve test coverage for MHs.eCA method. Testing: regression test, jck (api/java_lang/invoke), jdk/java/lang/invoke Thanks! Best regards, Vladimir Ivanov From paul.sandoz at oracle.com Wed Oct 15 12:40:30 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 15 Oct 2014 14:40:30 +0200 Subject: [9] [8u40] RFR (M): 8059877: GWT branch frequencies pollution due to LF sharing In-Reply-To: <543D717C.3090508@oracle.com> References: <54382E90.7040105@oracle.com> <03B32851-A9DB-4C43-ABB3-2CFE36D7CB0C@oracle.com> <543D717C.3090508@oracle.com> Message-ID: <0F6750AB-3949-4E5A-B67B-1FA1A10E5CA2@oracle.com> On Oct 14, 2014, at 8:54 PM, Vladimir Ivanov wrote: > Paul, > > Thanks for the feedback! > > Updated version: > http://cr.openjdk.java.net/~vlivanov/8059877/webrev.01/ > >>> http://cr.openjdk.java.net/~vlivanov/8059877/webrev.00/ >>> https://bugs.openjdk.java.net/browse/JDK-8059877 >>> >> >> Generally looks ok. >> >> - MethodHandleImpl >> >> 786 if (wrapper.unblock()) { >> 787 // Reached invocation threshold. Replace counting/blocking wrapper with a reinvoker. >> 788 wrapper.isActivated = false; >> >> If unblock() returns true then isActivated is already false. > Fixed. > >> At the expense of another box you could use an AtomicBoolean with compareAndSet if you want to really guarantee at most one unblocking, although the box can be removed if the boolean is changed to 'int' and Unsafe is used to CAS. > I considered that, but I decided not to go that route. GuardWithTest is a very common combinator, so footprint overhead could be noticeable. There's no need to guarantee uniqueness of unblocking operation. The operation is idempotent, so no problems performing it multiple times. What I try to achieve with the flag is avoid pathological situation when some thread continuously updates the form. Ok. > >> I dunno if strengthening the visibility of MethodHandle.form by stamping in a memory fence after the following will help >> >> 792 wrapper.updateForm(lform); >> >> e.g. using Unsafe.fullFence. > I think the fence should be there. It won't help guarantee the update is visible everywhere though. But it is expected. > I see you added it to MethodHandle.updateForm, i was incorrectly assuming you just wanted to add in the context of BlockInliningWrapper after the update call, so not all updates incur the full barrier cost for other calls to updateForm, but it makes sense in light of the ISSUE comment. Actually i forgot MethodHandle.form is marked final!, i better understand some of your comments now, so visibility is even more restricted that i previously thought. This is a good example to add to our "stomping on a final field" discussion, i think here it is definitely a very special case with a careful dance between updating and inlining (updateForm is also called by a direct method handle to a static method or field, such a handle initially holds a form with a check to initialize the class and after that occurs the handle is updated with a new form without the check). >> Perhaps isUnblocked is a better name than isActivated since there is no need to set the initial value and it tracks the same value as that returned from unblock? > Done. > 765 isUnblocked = false; Should be "isUnblocked = true". 756 MethodHandle newTarget = target.asType(newType); 757 return asTypeCache = isUnblocked ? make(newTarget) 758 : newTarget; // no need for a wrapper anymore Should be "return asTypeCache = !isUnblocked ? ? make(newTarget)" No need for another review round. >> Also while on the subject of naming perhaps consider changing MethodTypeForm.LF_DELEGATE_COUNTING to ...LF_DELEGATE_BLOCK_INLINING? > Done. > >> When DONT_INLINE_THRESHOLD > 0 and DONT_INLINE_THRESHOLD == COMPILE_THRESHOLD will that trigger both compilation of a BlockInliningWrapper's form and unblocking? I guess there is some fuzziness depending on concurrent execution. > No problems expected in this scenario - COMPILE_THRESHOLD updates LambdaForm entry point and unblocking operates on a method handle. > >> I am just wondering if there is any point compiling a BlockInliningWrapper's form if DONT_INLINE_THRESHOLD is expected to be ~ the same as COMPILE_THRESHOLD. Probably not terribly important especially if the JIT-compiler control approach replaces it. > I don't see any value in keeping BlockInliningWrapper interpreted. > It would allow to avoid LambdaForm.forceInline flag, but there should be a special case to skip compilation (in LambdaForm::checkInvocationCounter()). Moreover, if we get rid of LambdaForm interpreter, we will need to precompile BlockInliningWrapper again. > Ok. Paul. From david.lloyd at redhat.com Wed Oct 15 12:43:43 2014 From: david.lloyd at redhat.com (David M. Lloyd) Date: Wed, 15 Oct 2014 07:43:43 -0500 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543DBE5C.1070907@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <543BCAA3.7020003@redhat.com> <543DBE5C.1070907@oracle.com> Message-ID: <543E6BFF.30107@redhat.com> On 10/14/2014 07:22 PM, Mandy Chung wrote: > > On 10/13/2014 5:50 AM, David M. Lloyd wrote: >> On 10/10/2014 07:31 PM, Mandy Chung wrote: >>> >>> On 10/10/2014 8:10 AM, Claes Redestad wrote: >>>> Hi all, >>>> >>>> please review this patch which attempts to clean up synchronization >>>> and improve scalability when >>>> defining and getting java.lang.Package objects. >>> >>> I agree with David that getting Package objects are not performance >>> critical. On the other hand, the code defining/getting Packages is >>> old and deserves some cleanup especially the synchronization part. >> >> I have a little more information on this subject. We've a possible >> (and somewhat likely) deadlock which occurs because one thread can >> attempt to define a system class while holding the >> java.lang.Package#pkgs lock, while another thread can attempt to get a >> package while defining a system class (while holding the class loader >> lock). I do not recall whether parallel class loading alleviates this >> issue. We solved the problem by loading Packages.getPackages() in >> early (single-threaded) bootstrap. >> > > Do you recall what JDK version you observed this possible deadlock? I > wonder if the fix for 7001933 [1] in JDK 7 and 6u25 resolved the > deadlock problem you ran into. > > [1] http://hg.openjdk.java.net/jdk9/dev/jdk/rev/4a7da412db38 The change would have been observed in early 2011 so I think it was probably a JDK 6 version before 25 (which I did not install until April of that year) - looks like most likely candidate based on my JDK directory is 1.6.0_22. >> So from my perspective, just getting rid of the synchronization on >> that field alone makes this change worthwhile. > > Yes that's what I think too. > > Mandy -- - DML From marcus.lagergren at oracle.com Wed Oct 15 14:34:58 2014 From: marcus.lagergren at oracle.com (Marcus Lagergren) Date: Wed, 15 Oct 2014 16:34:58 +0200 Subject: [9] RFR (XS): 8060483: NPE with explicitCastArguments unboxing null In-Reply-To: <543E64BD.9000103@oracle.com> References: <543E64BD.9000103@oracle.com> Message-ID: <21620D7A-F5EA-4DA6-85A4-DD051DD1A955@oracle.com> +1 for me. I assume that Wrapper.java is only reformatting. It looks like it. Regards Marcus On 15 Oct 2014, at 14:12, Vladimir Ivanov wrote: > http://cr.openjdk.java.net/~vlivanov/8060483/webrev.00/ > https://bugs.openjdk.java.net/browse/JDK-8060483 > > Recent changes broke MHs.explicitCastArguments for null values when unboxing taking place. > > The fix corrects the equivalence check for MHs.eCA & MH.asType() in MT.explicitCastEquivalentToAsType(). > > Also, will file a followup enhancement request to improve test coverage for MHs.eCA method. > > Testing: regression test, jck (api/java_lang/invoke), jdk/java/lang/invoke > > Thanks! > > Best regards, > Vladimir Ivanov From vladimir.x.ivanov at oracle.com Wed Oct 15 14:49:14 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Wed, 15 Oct 2014 18:49:14 +0400 Subject: [9] RFR (XS): 8060483: NPE with explicitCastArguments unboxing null In-Reply-To: <21620D7A-F5EA-4DA6-85A4-DD051DD1A955@oracle.com> References: <543E64BD.9000103@oracle.com> <21620D7A-F5EA-4DA6-85A4-DD051DD1A955@oracle.com> Message-ID: <543E896A.1020007@oracle.com> Marcus, Attila, thanks for the prompt review! Yes, I only reformatted Wrapper a bit to make it more readable. I should've mentioned that in original request. Best regards, Vladimir Ivanov On 10/15/14, 6:34 PM, Marcus Lagergren wrote: > +1 for me. I assume that Wrapper.java is only reformatting. It looks like it. > > Regards > Marcus > > On 15 Oct 2014, at 14:12, Vladimir Ivanov wrote: > >> http://cr.openjdk.java.net/~vlivanov/8060483/webrev.00/ >> https://bugs.openjdk.java.net/browse/JDK-8060483 >> >> Recent changes broke MHs.explicitCastArguments for null values when unboxing taking place. >> >> The fix corrects the equivalence check for MHs.eCA & MH.asType() in MT.explicitCastEquivalentToAsType(). >> >> Also, will file a followup enhancement request to improve test coverage for MHs.eCA method. >> >> Testing: regression test, jck (api/java_lang/invoke), jdk/java/lang/invoke >> >> Thanks! >> >> Best regards, >> Vladimir Ivanov > From vladimir.x.ivanov at oracle.com Wed Oct 15 14:56:07 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Wed, 15 Oct 2014 18:56:07 +0400 Subject: [9] RFR (XS): 8060483: NPE with explicitCastArguments unboxing null In-Reply-To: <543E896A.1020007@oracle.com> References: <543E64BD.9000103@oracle.com> <21620D7A-F5EA-4DA6-85A4-DD051DD1A955@oracle.com> <543E896A.1020007@oracle.com> Message-ID: <543E8B07.30708@oracle.com> FTR filed request for additional test development [1] Best regards, Vladimir Ivanov [1] https://bugs.openjdk.java.net/browse/JDK-8060717 On 10/15/14, 6:49 PM, Vladimir Ivanov wrote: > Marcus, Attila, thanks for the prompt review! > > Yes, I only reformatted Wrapper a bit to make it more readable. > I should've mentioned that in original request. > > Best regards, > Vladimir Ivanov > > On 10/15/14, 6:34 PM, Marcus Lagergren wrote: >> +1 for me. I assume that Wrapper.java is only reformatting. It looks >> like it. >> >> Regards >> Marcus >> >> On 15 Oct 2014, at 14:12, Vladimir Ivanov >> wrote: >> >>> http://cr.openjdk.java.net/~vlivanov/8060483/webrev.00/ >>> https://bugs.openjdk.java.net/browse/JDK-8060483 >>> >>> Recent changes broke MHs.explicitCastArguments for null values when >>> unboxing taking place. >>> >>> The fix corrects the equivalence check for MHs.eCA & MH.asType() in >>> MT.explicitCastEquivalentToAsType(). >>> >>> Also, will file a followup enhancement request to improve test >>> coverage for MHs.eCA method. >>> >>> Testing: regression test, jck (api/java_lang/invoke), >>> jdk/java/lang/invoke >>> >>> Thanks! >>> >>> Best regards, >>> Vladimir Ivanov >> From pavel.rappo at oracle.com Wed Oct 15 15:09:28 2014 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Wed, 15 Oct 2014 16:09:28 +0100 Subject: RFR JDK-8042888: Remove extcheck tool In-Reply-To: <1F65F028-5F02-4608-9221-EF10498CF8A7@oracle.com> References: <1F65F028-5F02-4608-9221-EF10498CF8A7@oracle.com> Message-ID: <5D00970F-5387-4FFF-84DA-DBB45F52EE46@oracle.com> Hi everyone, Could you please review my change for JDK-8042888? http://cr.openjdk.java.net/~prappo/8042888/webrev.00/ Previously I sent an email to see if anyone uses this tool or has any thoughts on its future [1]. ----------------------------------------------------------------------------------- [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-September/028648.html Thanks -Pavel From vladimir.x.ivanov at oracle.com Wed Oct 15 15:21:04 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Wed, 15 Oct 2014 19:21:04 +0400 Subject: [9] [8u40] RFR (M): 8059877: GWT branch frequencies pollution due to LF sharing In-Reply-To: <0F6750AB-3949-4E5A-B67B-1FA1A10E5CA2@oracle.com> References: <54382E90.7040105@oracle.com> <03B32851-A9DB-4C43-ABB3-2CFE36D7CB0C@oracle.com> <543D717C.3090508@oracle.com> <0F6750AB-3949-4E5A-B67B-1FA1A10E5CA2@oracle.com> Message-ID: <543E90E0.6080200@oracle.com> Thanks, Paul! >> Updated version: >> http://cr.openjdk.java.net/~vlivanov/8059877/webrev.01/ >> ... > This is a good example to add to our "stomping on a final field" discussion, i think here it is definitely a very special case with a careful dance between updating and inlining (updateForm is also called by a direct method handle to a static method or field, such a handle initially holds a form with a check to initialize the class and after that occurs the handle is updated with a new form without the check). Yes, MethodHandle.updateForm is an inherently unsafe mechanism. It doesn't allow to arbitrarily change method handle behavior at will. It is used to evolve a method handle to a more performant version when possible. >>> Perhaps isUnblocked is a better name than isActivated since there is no need to set the initial value and it tracks the same value as that returned from unblock? >> Done. >> > > 765 isUnblocked = false; > > Should be "isUnblocked = true". > > 756 MethodHandle newTarget = target.asType(newType); > 757 return asTypeCache = isUnblocked ? make(newTarget) > 758 : newTarget; // no need for a wrapper anymore > > Should be "return asTypeCache = !isUnblocked ? ? make(newTarget)" Gosh. Thanks for catching that! Best regards, Vladimir Ivanov From joe.darcy at oracle.com Wed Oct 15 15:35:39 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Wed, 15 Oct 2014 08:35:39 -0700 Subject: Review request for JDK-8051540: Convert JAXP functin tests: org.xml.sax to jtreg (testNG) tests In-Reply-To: <543E33C5.7000207@oracle.com> References: <53D257BB.8010303@oracle.com> <2DA2DB81-DAC7-431C-AFD7-A73CB0C748C6@oracle.com> <53F28CF9.9030907@oracle.com> <87EB6F2A-260C-4419-9A65-D46A2AFEA0A2@oracle.com> <53F38A26.2080608@oracle.com> <53FE6BF9.3070305@oracle.com> <527B8686-4173-4FC6-9245-D0F7A35D0FB0@oracle.com> <543E33C5.7000207@oracle.com> Message-ID: <543E944B.3000503@oracle.com> Hi Joe, Before performing the full investigation, I'm now leaning toward have a "base" repo which would host files currently in the jdk, langtools, and hotspot repos and then another repo for all the other library code (jaxp, jaxws, corba). Compared to moving around all the source files in the jdk repo, I think the other potential changes are fairly small! HTH, -Joe On 10/15/2014 1:43 AM, huizhe wang wrote: > Joe, > > You mentioned recently that you were considering folding the jaxp repo > into some other repos. Would it matter if we put these functional > tests into the existing jaxp repo (/jaxp/test)? Or, > would jaxp tests be under whatever the 'other' repo is? > > We had planned to migrate jaxp unit and functional tests to jaxp > repo/test, and then move jaxp tests currently under jdk/test to > jaxp/test as well. > > These patches are big. I hope we don't have to move them around :-) > > Thanks, > Joe > > On 10/14/2014 3:10 PM, Tristan Yan wrote: >> Hi Joe >> Could you be my sponsor to push this if you?re okay with the code. >> Thank you >> Tristan >> >>> On Aug 27, 2014, at 4:38 PM, huizhe wang >> > wrote: >>> >>> >>> On 8/27/2014 4:03 PM, Tristan Yan wrote: >>>> Hi Joe and others >>>> >>>> I updated the tests with putting them in jaxp repo. I also run >>>> these tests with security manager and they all passed >>>> http://cr.openjdk.java.net/~tyan/JDK-8051540/webrev01/ >>>> >>>> >>> >>> Awesome. >>> >>>> Also I?d like to propose our way for handling jaxp tests run with >>>> security manager. The way we?d use is creating two targets for >>>> running jaxp tests. One is for normal run; which will run all the >>>> tests without security manager. One is secure run; the target only >>>> run the tests that have to be run with security manager. This could >>>> be easy to be handled with adding two targets in makefile. And for >>>> most of people they only care about the function. They only need >>>> run normal run target. We would run two targets for any of our >>>> formal tests like nightly, ci build and jprt tests. >>> >>> Yes, please coordinate with Frank and Eric so that all of the jaxp >>> tests share the same configuration. >>> >>>> For the tests which can not be run in secure mode(like tests for >>>> xsltc direct extension), we'd add testng group called >>>> ?secure-hostile?. We won?t run these tests in secure mode by >>>> bypassing them in secure run target. By this way we could easily >>>> transform our tests as usual without additional effort. >>> >>> I had been previously updated them so that all of the tests were >>> capable of running with and without security manager. Sustaining SQE >>> had invested several month to incorporate the changes into that >>> hosted in Aurora. Please consider taking the patches from them if >>> you haven't already done so. >>> >>> Thanks, >>> Joe >>> >>>> >>>> Thank you >>>> Tristan >>>> >>>>> On Aug 19, 2014, at 10:32 AM, huizhe wang >>>> > wrote: >>>>> >>>>> By the way, the plan has been that all of the JAXP SQE and Unit >>>>> tests be migrated into [openjdk]/jaxp repo under jaxp/test. Tests >>>>> currently in the jdk repo shall be moved to jaxp/test as well. I >>>>> see that your webrev was generated in jdk9/dev/jdk. I hope it >>>>> doesn't mean you're checking tests into the jdk repo. >>>>> >>>>> Thanks, >>>>> Joe >>>>> >>>>> On 8/18/2014 4:42 PM, Tristan Yan wrote: >>>>>> Thanks Joe >>>>>> We intend to replace the base class with test library because >>>>>> that doesn?t look like a real base class but an utilities class. >>>>>> I haven?t tried to run these tests with security manager, I will >>>>>> run them with security manager then get back you soon. >>>>>> Thank you. >>>>>> Tristan >>>>>> >>>>>>> On Aug 18, 2014, at 4:32 PM, huizhe wang >>>>>> > wrote: >>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > From Alan.Bateman at oracle.com Wed Oct 15 15:52:01 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 15 Oct 2014 16:52:01 +0100 Subject: RFR JDK-8042888: Remove extcheck tool In-Reply-To: <5D00970F-5387-4FFF-84DA-DBB45F52EE46@oracle.com> References: <1F65F028-5F02-4608-9221-EF10498CF8A7@oracle.com> <5D00970F-5387-4FFF-84DA-DBB45F52EE46@oracle.com> Message-ID: <543E9821.8070708@oracle.com> On 15/10/2014 16:09, Pavel Rappo wrote: > Hi everyone, > > Could you please review my change for JDK-8042888? > > http://cr.openjdk.java.net/~prappo/8042888/webrev.00/ > > This looks good, you seem to have caught everything. -Alan. From huizhe.wang at oracle.com Wed Oct 15 18:09:03 2014 From: huizhe.wang at oracle.com (huizhe wang) Date: Wed, 15 Oct 2014 11:09:03 -0700 Subject: Review request for JDK-8051540: Convert JAXP functin tests: org.xml.sax to jtreg (testNG) tests In-Reply-To: <543E944B.3000503@oracle.com> References: <53D257BB.8010303@oracle.com> <2DA2DB81-DAC7-431C-AFD7-A73CB0C748C6@oracle.com> <53F28CF9.9030907@oracle.com> <87EB6F2A-260C-4419-9A65-D46A2AFEA0A2@oracle.com> <53F38A26.2080608@oracle.com> <53FE6BF9.3070305@oracle.com> <527B8686-4173-4FC6-9245-D0F7A35D0FB0@oracle.com> <543E33C5.7000207@oracle.com> <543E944B.3000503@oracle.com> Message-ID: <543EB83F.6010001@oracle.com> On 10/15/2014 8:35 AM, Joe Darcy wrote: > Hi Joe, > > Before performing the full investigation, I'm now leaning toward have > a "base" repo which would host files currently in the jdk, langtools, > and hotspot repos and then another repo for all the other library code > (jaxp, jaxws, corba). Something like this? otherlib repo/ jaxp/src and etc. jaxws corba Currently, we are enjoying the benefit of being a repo by itself, that is, using the whole repo as our workspace. But I understand the need for consolidating, as long as it's in its own root directory, I think it would be fine. > > Compared to moving around all the source files in the jdk repo, I > think the other potential changes are fairly small! True, I'll push the change then. Thanks! Joe > > HTH, > > -Joe > > On 10/15/2014 1:43 AM, huizhe wang wrote: >> Joe, >> >> You mentioned recently that you were considering folding the jaxp >> repo into some other repos. Would it matter if we put these >> functional tests into the existing jaxp repo (> forest>/jaxp/test)? Or, would jaxp tests be under whatever the >> 'other' repo is? >> >> We had planned to migrate jaxp unit and functional tests to jaxp >> repo/test, and then move jaxp tests currently under jdk/test to >> jaxp/test as well. >> >> These patches are big. I hope we don't have to move them around :-) >> >> Thanks, >> Joe >> >> On 10/14/2014 3:10 PM, Tristan Yan wrote: >>> Hi Joe >>> Could you be my sponsor to push this if you?re okay with the code. >>> Thank you >>> Tristan >>> >>>> On Aug 27, 2014, at 4:38 PM, huizhe wang >>> > wrote: >>>> >>>> >>>> On 8/27/2014 4:03 PM, Tristan Yan wrote: >>>>> Hi Joe and others >>>>> >>>>> I updated the tests with putting them in jaxp repo. I also run >>>>> these tests with security manager and they all passed >>>>> http://cr.openjdk.java.net/~tyan/JDK-8051540/webrev01/ >>>>> >>>>> >>>> >>>> Awesome. >>>> >>>>> Also I?d like to propose our way for handling jaxp tests run with >>>>> security manager. The way we?d use is creating two targets for >>>>> running jaxp tests. One is for normal run; which will run all the >>>>> tests without security manager. One is secure run; the target only >>>>> run the tests that have to be run with security manager. This >>>>> could be easy to be handled with adding two targets in makefile. >>>>> And for most of people they only care about the function. They >>>>> only need run normal run target. We would run two targets for any >>>>> of our formal tests like nightly, ci build and jprt tests. >>>> >>>> Yes, please coordinate with Frank and Eric so that all of the jaxp >>>> tests share the same configuration. >>>> >>>>> For the tests which can not be run in secure mode(like tests for >>>>> xsltc direct extension), we'd add testng group called >>>>> ?secure-hostile?. We won?t run these tests in secure mode by >>>>> bypassing them in secure run target. By this way we could easily >>>>> transform our tests as usual without additional effort. >>>> >>>> I had been previously updated them so that all of the tests were >>>> capable of running with and without security manager. Sustaining >>>> SQE had invested several month to incorporate the changes into that >>>> hosted in Aurora. Please consider taking the patches from them if >>>> you haven't already done so. >>>> >>>> Thanks, >>>> Joe >>>> >>>>> >>>>> Thank you >>>>> Tristan >>>>> >>>>>> On Aug 19, 2014, at 10:32 AM, huizhe wang >>>>> > wrote: >>>>>> >>>>>> By the way, the plan has been that all of the JAXP SQE and Unit >>>>>> tests be migrated into [openjdk]/jaxp repo under jaxp/test. Tests >>>>>> currently in the jdk repo shall be moved to jaxp/test as well. I >>>>>> see that your webrev was generated in jdk9/dev/jdk. I hope it >>>>>> doesn't mean you're checking tests into the jdk repo. >>>>>> >>>>>> Thanks, >>>>>> Joe >>>>>> >>>>>> On 8/18/2014 4:42 PM, Tristan Yan wrote: >>>>>>> Thanks Joe >>>>>>> We intend to replace the base class with test library because >>>>>>> that doesn?t look like a real base class but an utilities class. >>>>>>> I haven?t tried to run these tests with security manager, I will >>>>>>> run them with security manager then get back you soon. >>>>>>> Thank you. >>>>>>> Tristan >>>>>>> >>>>>>>> On Aug 18, 2014, at 4:32 PM, huizhe wang >>>>>>>> > wrote: >>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > From mandy.chung at oracle.com Wed Oct 15 18:08:16 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 15 Oct 2014 11:08:16 -0700 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543E6BFF.30107@redhat.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <543BCAA3.7020003@redhat.com> <543DBE5C.1070907@oracle.com> <543E6BFF.30107@redhat.com> Message-ID: <543EB810.7000609@oracle.com> On 10/15/2014 5:43 AM, David M. Lloyd wrote: > On 10/14/2014 07:22 PM, Mandy Chung wrote: >> >> On 10/13/2014 5:50 AM, David M. Lloyd wrote: >>> >>> I have a little more information on this subject. We've a possible >>> (and somewhat likely) deadlock which occurs because one thread can >>> attempt to define a system class while holding the >>> java.lang.Package#pkgs lock, while another thread can attempt to get a >>> package while defining a system class (while holding the class loader >>> lock). I do not recall whether parallel class loading alleviates this >>> issue. We solved the problem by loading Packages.getPackages() in >>> early (single-threaded) bootstrap. >>> >> >> Do you recall what JDK version you observed this possible deadlock? I >> wonder if the fix for 7001933 [1] in JDK 7 and 6u25 resolved the >> deadlock problem you ran into. >> >> [1] http://hg.openjdk.java.net/jdk9/dev/jdk/rev/4a7da412db38 > > The change would have been observed in early 2011 so I think it was > probably a JDK 6 version before 25 (which I did not install until > April of that year) - looks like most likely candidate based on my JDK > directory is 1.6.0_22. > Thanks. It's possible that it's the same deadlock issue. Mandy From joe.darcy at oracle.com Wed Oct 15 19:06:53 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Wed, 15 Oct 2014 12:06:53 -0700 Subject: Review request for JDK-8051540: Convert JAXP functin tests: org.xml.sax to jtreg (testNG) tests In-Reply-To: <543EB83F.6010001@oracle.com> References: <53D257BB.8010303@oracle.com> <2DA2DB81-DAC7-431C-AFD7-A73CB0C748C6@oracle.com> <53F28CF9.9030907@oracle.com> <87EB6F2A-260C-4419-9A65-D46A2AFEA0A2@oracle.com> <53F38A26.2080608@oracle.com> <53FE6BF9.3070305@oracle.com> <527B8686-4173-4FC6-9245-D0F7A35D0FB0@oracle.com> <543E33C5.7000207@oracle.com> <543E944B.3000503@oracle.com> <543EB83F.6010001@oracle.com> Message-ID: <543EC5CD.6050002@oracle.com> On 10/15/2014 11:09 AM, huizhe wang wrote: > > On 10/15/2014 8:35 AM, Joe Darcy wrote: >> Hi Joe, >> >> Before performing the full investigation, I'm now leaning toward have >> a "base" repo which would host files currently in the jdk, langtools, >> and hotspot repos and then another repo for all the other library >> code (jaxp, jaxws, corba). > > Something like this? > otherlib repo/ > jaxp/src and etc. > jaxws > corba > > Currently, we are enjoying the benefit of being a repo by itself, that > is, using the whole repo as our workspace. > But I understand the need for consolidating, as long as it's in its > own root directory, I think it would be fine. I'd expect something more like otherlib repo/ src/$MODULE_NAME_FOR_JAXP src/$MODULE_NAME_FOR_JAXWS ... as now in the jdk repo, which may end up being basically isomorphic to the above. Thanks, -Joe From chris.hegarty at oracle.com Wed Oct 15 19:53:42 2014 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Wed, 15 Oct 2014 20:53:42 +0100 Subject: RFR JDK-8042888: Remove extcheck tool In-Reply-To: <543E9821.8070708@oracle.com> References: <1F65F028-5F02-4608-9221-EF10498CF8A7@oracle.com> <5D00970F-5387-4FFF-84DA-DBB45F52EE46@oracle.com> <543E9821.8070708@oracle.com> Message-ID: <89C839F8-D36D-4006-B2B5-434F406909BF@oracle.com> On 15 Oct 2014, at 16:52, Alan Bateman wrote: > On 15/10/2014 16:09, Pavel Rappo wrote: >> Hi everyone, >> >> Could you please review my change for JDK-8042888? >> >> http://cr.openjdk.java.net/~prappo/8042888/webrev.00/ >> >> > This looks good, you seem to have caught everything. +1. -Chris. > -Alan. From huizhe.wang at oracle.com Wed Oct 15 20:04:02 2014 From: huizhe.wang at oracle.com (huizhe wang) Date: Wed, 15 Oct 2014 13:04:02 -0700 Subject: Review request for JDK-8051540: Convert JAXP functin tests: org.xml.sax to jtreg (testNG) tests In-Reply-To: <543EC5CD.6050002@oracle.com> References: <53D257BB.8010303@oracle.com> <2DA2DB81-DAC7-431C-AFD7-A73CB0C748C6@oracle.com> <53F28CF9.9030907@oracle.com> <87EB6F2A-260C-4419-9A65-D46A2AFEA0A2@oracle.com> <53F38A26.2080608@oracle.com> <53FE6BF9.3070305@oracle.com> <527B8686-4173-4FC6-9245-D0F7A35D0FB0@oracle.com> <543E33C5.7000207@oracle.com> <543E944B.3000503@oracle.com> <543EB83F.6010001@oracle.com> <543EC5CD.6050002@oracle.com> Message-ID: <543ED332.2020701@oracle.com> On 10/15/2014 12:06 PM, Joe Darcy wrote: > On 10/15/2014 11:09 AM, huizhe wang wrote: >> >> On 10/15/2014 8:35 AM, Joe Darcy wrote: >>> Hi Joe, >>> >>> Before performing the full investigation, I'm now leaning toward >>> have a "base" repo which would host files currently in the jdk, >>> langtools, and hotspot repos and then another repo for all the other >>> library code (jaxp, jaxws, corba). >> >> Something like this? >> otherlib repo/ >> jaxp/src and etc. >> jaxws >> corba >> >> Currently, we are enjoying the benefit of being a repo by itself, >> that is, using the whole repo as our workspace. >> But I understand the need for consolidating, as long as it's in its >> own root directory, I think it would be fine. > > I'd expect something more like > > otherlib repo/ > > src/$MODULE_NAME_FOR_JAXP > src/$MODULE_NAME_FOR_JAXWS > ... > > as now in the jdk repo, which may end up being basically isomorphic to > the above. Make sense. JAXP is in one module anyways -- a positive for me :-) Where would you think the tests would end up? otherlib repo/test? otherlib repo/test jaxp jaxws ... in which case, jaxp/test would be moved to otherlib repo/test/jaxp. Thanks, Joe > > Thanks, > > -Joe From mandy.chung at oracle.com Wed Oct 15 20:11:13 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 15 Oct 2014 13:11:13 -0700 Subject: RFR: 8059767: FileHandler should allow 'long' limits and handle overflow of MeteredStream.written. In-Reply-To: <543D0134.4010605@oracle.com> References: <5433E6E9.2080009@oracle.com> <5434D91C.4040902@oracle.com> <543507F2.2050804@oracle.com> <543D0134.4010605@oracle.com> Message-ID: <543ED4E1.6090906@oracle.com> On 10/14/2014 3:55 AM, Daniel Fuchs wrote: > > http://cr.openjdk.java.net/~dfuchs/webrev_8059767/webrev.02 Looks good. Nit: use {@code...} instead of .... It may be inconsistent with the javadoc for other existing constructors that I think it's good to clean up the new one at least. No need to generate a new webrev. Mandy From peter.levart at gmail.com Wed Oct 15 22:30:42 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 16 Oct 2014 00:30:42 +0200 Subject: Preview: JDK-8055854 Examine overhead in java.net.URLClassLoader (stack-less exceptions) Message-ID: <543EF592.3030409@gmail.com> Hi, Recently a patch was applied to JDK9 for issue "JDK-8057936: java.net.URLClassLoader.findClass uses exceptions in control flow", which optimizes frequent exceptional path out of doPrivileged block in URLClassLoader.findClass() and replaces it with null return (which is not wrapped with PrivilegedActionException) and hence eliminates one exception construction. This was the low-hanging fruit. Here I present a similar-sized fruit which hangs a little higher... The most time-consuming part of exception construction is "remembering the stack trace" - the Throwable.fillInStackTrace() method. Do we always need stack-traces? ClassLoader API consists of two protected methods that are meant to be used for communication among ClassLoaders: protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException protected Class findClass(String name) throws ClassNotFoundException loadClass() is meant to call findClass() and parent loader's loadClass() and both of them are meant to be arranged in subclass overrides which call super methods. ClassNotFoundException thrown in that arrangement is used only to signal unsuccessful loading of a particular class from one ClassLoader to the other or from super method to overriding method where stack traces are not needed. ClassLoader.loadClass(String name) public method is the public API for programmatic access and Class.forName() public API is wired through it. VM upcall also appears to be using the public loadClass(String) method. I searched for callers of protected loadClass(String name, boolean resolve) method and apart from some tests, all JDK code seems to calls this method either from overriding protected method of a subclass (the super call) or from protected loadClass(String name, boolean resolve) method of another ClassLoader that happens to have access to it either because the caller is in the same package as the callee or nested in the same enclosing class. The notable exceptions are: sun.applet.AppletClassLoader (a subclasss of URLClassLoader): overrides the method with public method (potentially accessible as public API), calls super and propagates unchanged CNFE, but it also overrides findClass(), calls super and never propagates exceptions from super (throws it's own CNF exceptions with full stacks). java.net.FactoryURLClassLoader (a subclass of URLClassLoader): overrides the method with public method (probably a mistake), calls super and propagates CNFE, but the class is package-private, so there's no public access to this method. sun.misc.Launcher.AppClassLoader (a subclass of URLClassLoader): overrides the method with public method(probably a mistake), calls super and propagates CNFE, but the class is package-private, so there's no public access to this method. And of course: java.lang.ClassLoader: delegates to the method from public loadClass(String name) method. That appears to be it. So here's a preview of a patch that uses stack-less ClassNotFoundException(s) for intra/inter-class-loader communication and replaces them with full-stack variants on the public API border: http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.01/ I also prepared a benchmark which shows the improvement (results attached as comments): http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/CLBench.java The loadSameClassFailureand loadSameClassSuccess are throughput benchmarks which constantly call loadClass() on the AppClassLoader with the same unexistent and existent class names respectively. loadSameClassFailure shows improvement because CNF exception thrown from ExtClassLoader (parent of AppClassLoader) has no stack. The loadNewClassFailure and loadNewClassSuccess are one-shot benchmarks which run each shot on fresh VM instance. A shot loads 100,000 different classes. Both benchmarks show improvement because of intra/inter-class-loader communication is using stack-less CNF exceptions. I guess there exist other internal Oracle benchmarks that could be run with this patch to get some more evidence of possible improvement. So what is the effect on stack-traces? The following simple test: package test; public class Test { static void doIt() throws Exception { Class.forName("XXX"); } public static void main(String[] args) throws Exception { doIt(); } } Prints using original JDK code: Exception in thread "main" java.lang.ClassNotFoundException: XXX at java.net.URLClassLoader$1.run(URLClassLoader.java:372) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:360) at java.lang.ClassLoader.loadClass(ClassLoader.java:426) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:317) at java.lang.ClassLoader.loadClass(ClassLoader.java:359) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:264) at test.Test.doIt(Test.java:11) at test.Test.main(Test.java:15) And using patched JDK code: Exception in thread "main" java.lang.ClassNotFoundException: XXX at java.lang.ClassLoader.loadClass(ClassLoader.java:366) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:264) at test.Test.doIt(Test.java:11) at test.Test.main(Test.java:15) Some internal intra/inter-class-loader frames are missing, but the application stack-trace is visible. Is this too much hiding? Regards, Peter From stanimir at riflexo.com Wed Oct 15 23:49:36 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Thu, 16 Oct 2014 02:49:36 +0300 Subject: Preview: JDK-8055854 Examine overhead in java.net.URLClassLoader (stack-less exceptions) In-Reply-To: <543EF592.3030409@gmail.com> References: <543EF592.3030409@gmail.com> Message-ID: First, really nice tests. As for hiding: missing the real classloader impl. might be quite a bumper for some middleware implementations. That would make pretty hard to trace dependency issues without explicit logging, the latter is usually available but still. Also it'd depend if the classloaders actually use super.findClass() or not. IMO, the option should be switchable via some system property. I am not sure about the need to hide the stackless c-tor as the effect can be achieved by overriding fillInStackTrace(); w/o the extra baggage of JavaLangAccess. Overall very decent improvement. Cheers Stanimir On Thu, Oct 16, 2014 at 1:30 AM, Peter Levart wrote: > Hi, > > Recently a patch was applied to JDK9 for issue "JDK-8057936: > java.net.URLClassLoader.findClass uses exceptions in control flow", which > optimizes frequent exceptional path out of doPrivileged block in > URLClassLoader.findClass() and replaces it with null return (which is not > wrapped with PrivilegedActionException) and hence eliminates one exception > construction. This was the low-hanging fruit. Here I present a > similar-sized fruit which hangs a little higher... > > The most time-consuming part of exception construction is "remembering the > stack trace" - the Throwable.fillInStackTrace() method. Do we always need > stack-traces? > > ClassLoader API consists of two protected methods that are meant to be > used for communication among ClassLoaders: > > protected Class loadClass(String name, boolean resolve) throws > ClassNotFoundException > > protected Class findClass(String name) throws ClassNotFoundException > > > loadClass() is meant to call findClass() and parent loader's loadClass() > and both of them are meant to be arranged in subclass overrides which call > super methods. ClassNotFoundException thrown in that arrangement is used > only to signal unsuccessful loading of a particular class from one > ClassLoader to the other or from super method to overriding method where > stack traces are not needed. ClassLoader.loadClass(String name) public > method is the public API for programmatic access and Class.forName() public > API is wired through it. VM upcall also appears to be using the public > loadClass(String) method. > > I searched for callers of protected loadClass(String name, boolean > resolve) method and apart from some tests, all JDK code seems to calls this > method either from overriding protected method of a subclass (the super > call) or from protected loadClass(String name, boolean resolve) method of > another ClassLoader that happens to have access to it either because the > caller is in the same package as the callee or nested in the same enclosing > class. The notable exceptions are: > > sun.applet.AppletClassLoader (a subclasss of URLClassLoader): overrides > the method with public method (potentially accessible as public API), calls > super and propagates unchanged CNFE, but it also overrides findClass(), > calls super and never propagates exceptions from super (throws it's own CNF > exceptions with full stacks). > > java.net.FactoryURLClassLoader (a subclass of URLClassLoader): overrides > the method with public method (probably a mistake), calls super and > propagates CNFE, but the class is package-private, so there's no public > access to this method. > > sun.misc.Launcher.AppClassLoader (a subclass of URLClassLoader): > overrides the method with public method(probably a mistake), calls super > and propagates CNFE, but the class is package-private, so there's no public > access to this method. > > And of course: > > java.lang.ClassLoader: delegates to the method from public > loadClass(String name) method. > > That appears to be it. > > So here's a preview of a patch that uses stack-less > ClassNotFoundException(s) for intra/inter-class-loader communication and > replaces them with full-stack variants on the public API border: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.01/ > > I also prepared a benchmark which shows the improvement (results attached > as comments): > > http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/CLBench.java > > The loadSameClassFailureand loadSameClassSuccess are throughput benchmarks > which constantly call loadClass() on the AppClassLoader with the same > unexistent and existent class names respectively. loadSameClassFailure > shows improvement because CNF exception thrown from ExtClassLoader (parent > of AppClassLoader) has no stack. > > The loadNewClassFailure and loadNewClassSuccess are one-shot benchmarks > which run each shot on fresh VM instance. A shot loads 100,000 different > classes. Both benchmarks show improvement because of > intra/inter-class-loader communication is using stack-less CNF exceptions. > > I guess there exist other internal Oracle benchmarks that could be run > with this patch to get some more evidence of possible improvement. > > So what is the effect on stack-traces? The following simple test: > > package test; > public class Test { > static void doIt() throws Exception { > Class.forName("XXX"); > } > public static void main(String[] args) throws Exception { > doIt(); > } > } > > > Prints using original JDK code: > > Exception in thread "main" java.lang.ClassNotFoundException: XXX > at java.net.URLClassLoader$1.run(URLClassLoader.java:372) > at java.net.URLClassLoader$1.run(URLClassLoader.java:361) > at java.security.AccessController.doPrivileged(Native Method) > at java.net.URLClassLoader.findClass(URLClassLoader.java:360) > at java.lang.ClassLoader.loadClass(ClassLoader.java:426) > at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:317) > at java.lang.ClassLoader.loadClass(ClassLoader.java:359) > at java.lang.Class.forName0(Native Method) > at java.lang.Class.forName(Class.java:264) > at test.Test.doIt(Test.java:11) > at test.Test.main(Test.java:15) > > And using patched JDK code: > > Exception in thread "main" java.lang.ClassNotFoundException: XXX > at java.lang.ClassLoader.loadClass(ClassLoader.java:366) > at java.lang.Class.forName0(Native Method) > at java.lang.Class.forName(Class.java:264) > at test.Test.doIt(Test.java:11) > at test.Test.main(Test.java:15) > > > Some internal intra/inter-class-loader frames are missing, but the > application stack-trace is visible. Is this too much hiding? > > > Regards, Peter > > From kumar.x.srinivasan at oracle.com Thu Oct 16 00:31:11 2014 From: kumar.x.srinivasan at oracle.com (Kumar Srinivasan) Date: Wed, 15 Oct 2014 17:31:11 -0700 Subject: RFR 8060432: tools/pack200/TestNormal.java fails on Windows with java.io.FileNotFoundException after JDK-8058854 In-Reply-To: <543DDF21.7090402@oracle.com> References: <543D30F1.2090505@oracle.com> <543D8B27.5090201@oracle.com> <543DDF21.7090402@oracle.com> Message-ID: <543F11CF.5060605@oracle.com> Looks good! Kumar On 10/14/2014 7:42 PM, Amy Lu wrote: > On 10/15/14, 4:44 AM, Kumar Srinivasan wrote: >> Amy, >> >> The modifications you have made will not test pack200 compression >> and normalization correctly, as the test needs ".class" files. > > Sorry, I missed that. > Please review the updated version, test works on ".class" files > (Utils.TEST_CLS_DIR) > http://cr.openjdk.java.net/~weijun/8060432/webrev.01/ > >> Do you know >> why the test fails on windows ? > > extractJar(JarFile jf, File where) try to extract jar files to folder > "testdir", as the jar contains files of > C:/blabla > extractJar method run into issue on Windows as it try to extract it to > testdir\\C:\\blabla > > Anyway, as there already has some ".class" files to working on > (Utils.TEST_CLS_DIR), extractJar method is not needed. > > Thanks, > Amy >> >> Kumar >> >> >> On 10/14/2014 7:19 AM, Amy Lu wrote: >>> Please review the test fix. >>> >>> bug: https://bugs.openjdk.java.net/browse/JDK-8060432 >>> webrev: http://cr.openjdk.java.net/~weijun/8060432/webrev.00/ >>> >>> This test is to test >>> compareJars(new JarFile("normalized.jar"), new >>> JarFile("repacked.jar")); >>> where the jar files (normalized.jar repacked.jar and original.jar) >>> are created by "jar cnf" "jar cf" or "pack200 -r?. >>> >>> extractJar(JarFile jf, File where) is not really needed as this >>> method just try to provide some files for the test to do "jar cnf?. >>> Actually, "jar cnf" can work on any files, test just need some files >>> to jar with. >>> >>> Test can just simply created some files for that purpose. >>> >>> Thanks, >>> Amy >>> >> > From szegedia at gmail.com Wed Oct 15 14:46:27 2014 From: szegedia at gmail.com (Attila Szegedi) Date: Wed, 15 Oct 2014 16:46:27 +0200 Subject: [9] RFR (XS): 8060483: NPE with explicitCastArguments unboxing null In-Reply-To: <543E64BD.9000103@oracle.com> References: <543E64BD.9000103@oracle.com> Message-ID: +1 On Wed, Oct 15, 2014 at 2:12 PM, Vladimir Ivanov < vladimir.x.ivanov at oracle.com> wrote: > http://cr.openjdk.java.net/~vlivanov/8060483/webrev.00/ > https://bugs.openjdk.java.net/browse/JDK-8060483 > > Recent changes broke MHs.explicitCastArguments for null values when > unboxing taking place. > > The fix corrects the equivalence check for MHs.eCA & MH.asType() in MT. > explicitCastEquivalentToAsType(). > > Also, will file a followup enhancement request to improve test coverage > for MHs.eCA method. > > Testing: regression test, jck (api/java_lang/invoke), jdk/java/lang/invoke > > Thanks! > > Best regards, > Vladimir Ivanov > _______________________________________________ > mlvm-dev mailing list > mlvm-dev at openjdk.java.net > http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev > From peter.levart at gmail.com Thu Oct 16 07:35:39 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 16 Oct 2014 09:35:39 +0200 Subject: Preview: JDK-8055854 Examine overhead in java.net.URLClassLoader (stack-less exceptions) In-Reply-To: References: <543EF592.3030409@gmail.com> Message-ID: <543F754B.4020001@gmail.com> On 10/16/2014 01:49 AM, Stanimir Simeonoff wrote: > First, really nice tests. > > As for hiding: missing the real classloader impl. might be quite a bumper > for some middleware implementations. That would make pretty hard to trace > dependency issues without explicit logging, the latter is usually available > but still. Also it'd depend if the classloaders actually use > super.findClass() or not. > IMO, the option should be switchable via some system property. With a little tweak, the message of the stack-less exception thrown from findClass() methods can be extended to include the classloader's runtime class name and this message can be inherited by a replacement stack-full exception. So the stack-trace would look like: Exception in thread "main" java.lang.ClassNotFoundException: XXX (thrown by: sun.misc.Launcher$AppClassLoader) at java.lang.ClassLoader.loadClass(ClassLoader.java:366) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:265) at Test.doIt(Test.java:7) at Test.main(Test.java:11) Instead of what we have now: Exception in thread "main" java.lang.ClassNotFoundException: XXX at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:426) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:317) at java.lang.ClassLoader.loadClass(ClassLoader.java:359) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:265) at Test.doIt(Test.java:7) at Test.main(Test.java:11) Would this be enough to cover your concern? Regards, Peter > > I am not sure about the need to hide the stackless c-tor as the effect can > be achieved by overriding fillInStackTrace(); w/o the extra baggage of > JavaLangAccess. > > Overall very decent improvement. > > Cheers > Stanimir > > From amy.lu at oracle.com Thu Oct 16 07:36:55 2014 From: amy.lu at oracle.com (Amy Lu) Date: Thu, 16 Oct 2014 15:36:55 +0800 Subject: RFR 8060432: tools/pack200/TestNormal.java fails on Windows with java.io.FileNotFoundException after JDK-8058854 In-Reply-To: <543F11CF.5060605@oracle.com> References: <543D30F1.2090505@oracle.com> <543D8B27.5090201@oracle.com> <543DDF21.7090402@oracle.com> <543F11CF.5060605@oracle.com> Message-ID: <543F7597.7060008@oracle.com> Thank you Kumar for your review. I need a sponsorfor push this fix. Alan, may I get your help? Thanks, Amy On 10/16/14, 8:31 AM, Kumar Srinivasan wrote: > Looks good! > > Kumar > > On 10/14/2014 7:42 PM, Amy Lu wrote: >> On 10/15/14, 4:44 AM, Kumar Srinivasan wrote: >>> Amy, >>> >>> The modifications you have made will not test pack200 compression >>> and normalization correctly, as the test needs ".class" files. >> >> Sorry, I missed that. >> Please review the updated version, test works on ".class" files >> (Utils.TEST_CLS_DIR) >> http://cr.openjdk.java.net/~weijun/8060432/webrev.01/ >> >>> Do you know >>> why the test fails on windows ? >> >> extractJar(JarFile jf, File where) try to extract jar files to folder >> "testdir", as the jar contains files of >> C:/blabla >> extractJar method run into issue on Windows as it try to extract it >> to testdir\\C:\\blabla >> >> Anyway, as there already has some ".class" files to working on >> (Utils.TEST_CLS_DIR), extractJar method is not needed. >> >> Thanks, >> Amy >>> >>> Kumar >>> >>> >>> On 10/14/2014 7:19 AM, Amy Lu wrote: >>>> Please review the test fix. >>>> >>>> bug: https://bugs.openjdk.java.net/browse/JDK-8060432 >>>> webrev: http://cr.openjdk.java.net/~weijun/8060432/webrev.00/ >>>> >>>> This test is to test >>>> compareJars(new JarFile("normalized.jar"), new >>>> JarFile("repacked.jar")); >>>> where the jar files (normalized.jar repacked.jar and original.jar) >>>> are created by "jar cnf" "jar cf" or "pack200 -r?. >>>> >>>> extractJar(JarFile jf, File where) is not really needed as this >>>> method just try to provide some files for the test to do "jar cnf?. >>>> Actually, "jar cnf" can work on any files, test just need some >>>> files to jar with. >>>> >>>> Test can just simply created some files for that purpose. >>>> >>>> Thanks, >>>> Amy >>>> >>> >> > From konstantin.shefov at oracle.com Thu Oct 16 08:43:12 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Thu, 16 Oct 2014 12:43:12 +0400 Subject: [9] Review request : JDK-8059070: [TESTBUG] java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java failed - timeout In-Reply-To: <543D1DEE.8030206@oracle.com> References: <543D1DEE.8030206@oracle.com> Message-ID: <543F8520.9090408@oracle.com> Gently reminder On 14.10.2014 16:58, Konstantin Shefov wrote: > Hello, > > Please review the test bug fix > https://bugs.openjdk.java.net/browse/JDK-8059070 > Webrev is http://cr.openjdk.java.net/~kshefov/8059070/webrev.00/ > > Thanks > > -Konstantin From peter.levart at gmail.com Thu Oct 16 08:44:08 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 16 Oct 2014 10:44:08 +0200 Subject: Preview: JDK-8055854 Examine overhead in java.net.URLClassLoader (stack-less exceptions) In-Reply-To: <543F754B.4020001@gmail.com> References: <543EF592.3030409@gmail.com> <543F754B.4020001@gmail.com> Message-ID: <543F8558.2030401@gmail.com> Hi, As for usage of SharedSecrets, they are not needed to access CNFE package-private constructor from java.lang.ClassLoader, since they are in the same package, and from java.net.URLClassLoader, the call to super.findClass(name) does the job. So here's an updated webrev that also includes more descriptive message: http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.02/ Regards, Peter On 10/16/2014 09:35 AM, Peter Levart wrote: > On 10/16/2014 01:49 AM, Stanimir Simeonoff wrote: >> First, really nice tests. >> >> As for hiding: missing the real classloader impl. might be quite a >> bumper >> for some middleware implementations. That would make pretty hard to >> trace >> dependency issues without explicit logging, the latter is usually >> available >> but still. Also it'd depend if the classloaders actually use >> super.findClass() or not. >> IMO, the option should be switchable via some system property. > > With a little tweak, the message of the stack-less exception thrown > from findClass() methods can be extended to include the classloader's > runtime class name and this message can be inherited by a replacement > stack-full exception. So the stack-trace would look like: > > Exception in thread "main" java.lang.ClassNotFoundException: XXX > (thrown by: sun.misc.Launcher$AppClassLoader) > at java.lang.ClassLoader.loadClass(ClassLoader.java:366) > at java.lang.Class.forName0(Native Method) > at java.lang.Class.forName(Class.java:265) > at Test.doIt(Test.java:7) > at Test.main(Test.java:11) > > Instead of what we have now: > > Exception in thread "main" java.lang.ClassNotFoundException: XXX > at java.net.URLClassLoader.findClass(URLClassLoader.java:381) > at java.lang.ClassLoader.loadClass(ClassLoader.java:426) > at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:317) > at java.lang.ClassLoader.loadClass(ClassLoader.java:359) > at java.lang.Class.forName0(Native Method) > at java.lang.Class.forName(Class.java:265) > at Test.doIt(Test.java:7) > at Test.main(Test.java:11) > > > Would this be enough to cover your concern? > > Regards, Peter > >> >> I am not sure about the need to hide the stackless c-tor as the >> effect can >> be achieved by overriding fillInStackTrace(); w/o the extra baggage of >> JavaLangAccess. >> >> Overall very decent improvement. >> >> Cheers >> Stanimir >> >> From konstantin.shefov at oracle.com Thu Oct 16 08:51:53 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Thu, 16 Oct 2014 12:51:53 +0400 Subject: [8u40] Request for approval and review: JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: References: <543BE015.90505@oracle.com> <543BEA18.6060003@oracle.com> <543CDE30.7010506@oracle.com> Message-ID: <543F8729.5080200@oracle.com> Sean, Rob I have to reviews of this backport request (Vladimir is jdk 9 reviewer, but not 8u40). Can I get an approval for 8u40 in this case? Thanks -Konstantin On 14.10.2014 14:50, Paul Sandoz wrote: > On Oct 14, 2014, at 10:26 AM, Konstantin Shefov wrote: > >> Gently reminder >> Please, review >> > +1 > > Paul. > >> -Konstantin >> >> On 13.10.2014 19:04, Vladimir Ivanov wrote: >>> Looks good (not a Reviewer). >>> >>> Best regards, >>> Vladimir Ivanov >>> >>> On 10/13/14, 6:22 PM, Konstantin Shefov wrote: >>>> Hello, >>>> >>>> Please review and approve the backport of the test bug fix to 8u40 >>>> >>>> The webrev is slightly different from that for JDK 9, because there is >>>> no segmented code cache feature in 8u40. >>>> >>>> The bug: https://bugs.openjdk.java.net/browse/JDK-8058695 >>>> The 8u40 webrev: http://cr.openjdk.java.net/~kshefov/8058733/webrev.01 >>>> >>>> JDK 9 changeset: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/5c507b7ee225 >>>> Review thread: >>>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029062.html >>>> >>>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029033.html >>>> >>>> >>>> Thanks >>>> >>>> -Konstantin From sean.coffey at oracle.com Thu Oct 16 08:58:46 2014 From: sean.coffey at oracle.com (=?windows-1252?Q?Se=E1n_Coffey?=) Date: Thu, 16 Oct 2014 09:58:46 +0100 Subject: [8u40] Request for approval and review: JDK-8058733: [TESTBUG] java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java and LFMultiThreadCachingTest.java failed on some platforms due to java.lang.VirtualMachineError In-Reply-To: <543F8729.5080200@oracle.com> References: <543BE015.90505@oracle.com> <543BEA18.6060003@oracle.com> <543CDE30.7010506@oracle.com> <543F8729.5080200@oracle.com> Message-ID: <543F88C6.5080509@oracle.com> Approved for jdk8u-dev. regards, Sean. On 16/10/2014 09:51, Konstantin Shefov wrote: > Sean, Rob > > I have to reviews of this backport request (Vladimir is jdk 9 > reviewer, but not 8u40). > Can I get an approval for 8u40 in this case? > > Thanks > -Konstantin > > On 14.10.2014 14:50, Paul Sandoz wrote: >> On Oct 14, 2014, at 10:26 AM, Konstantin Shefov >> wrote: >> >>> Gently reminder >>> Please, review >>> >> +1 >> >> Paul. >> >>> -Konstantin >>> >>> On 13.10.2014 19:04, Vladimir Ivanov wrote: >>>> Looks good (not a Reviewer). >>>> >>>> Best regards, >>>> Vladimir Ivanov >>>> >>>> On 10/13/14, 6:22 PM, Konstantin Shefov wrote: >>>>> Hello, >>>>> >>>>> Please review and approve the backport of the test bug fix to 8u40 >>>>> >>>>> The webrev is slightly different from that for JDK 9, because >>>>> there is >>>>> no segmented code cache feature in 8u40. >>>>> >>>>> The bug: https://bugs.openjdk.java.net/browse/JDK-8058695 >>>>> The 8u40 webrev: >>>>> http://cr.openjdk.java.net/~kshefov/8058733/webrev.01 >>>>> >>>>> JDK 9 changeset: >>>>> http://hg.openjdk.java.net/jdk9/dev/jdk/rev/5c507b7ee225 >>>>> Review thread: >>>>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029062.html >>>>> >>>>> >>>>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029033.html >>>>> >>>>> >>>>> >>>>> Thanks >>>>> >>>>> -Konstantin > From stanimir at riflexo.com Thu Oct 16 09:09:52 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Thu, 16 Oct 2014 12:09:52 +0300 Subject: Preview: JDK-8055854 Examine overhead in java.net.URLClassLoader (stack-less exceptions) In-Reply-To: <543F8558.2030401@gmail.com> References: <543EF592.3030409@gmail.com> <543F754B.4020001@gmail.com> <543F8558.2030401@gmail.com> Message-ID: Hi Peter, The changes look good indeed. Actually in real environments the benefits would be larger due to much deeper stack traces. Perhaps the the doc of ClassLoader.findClass should advise calling the super instead of throwing a new CNFE? Stanimir On Thu, Oct 16, 2014 at 11:44 AM, Peter Levart wrote: > Hi, > > As for usage of SharedSecrets, they are not needed to access CNFE > package-private constructor from java.lang.ClassLoader, since they are in > the same package, and from java.net.URLClassLoader, the call to > super.findClass(name) does the job. So here's an updated webrev that also > includes more descriptive message: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.02/ > > > Regards, Peter > > > On 10/16/2014 09:35 AM, Peter Levart wrote: > >> On 10/16/2014 01:49 AM, Stanimir Simeonoff wrote: >> >>> First, really nice tests. >>> >>> As for hiding: missing the real classloader impl. might be quite a bumper >>> for some middleware implementations. That would make pretty hard to trace >>> dependency issues without explicit logging, the latter is usually >>> available >>> but still. Also it'd depend if the classloaders actually use >>> super.findClass() or not. >>> IMO, the option should be switchable via some system property. >>> >> >> With a little tweak, the message of the stack-less exception thrown from >> findClass() methods can be extended to include the classloader's runtime >> class name and this message can be inherited by a replacement stack-full >> exception. So the stack-trace would look like: >> >> Exception in thread "main" java.lang.ClassNotFoundException: XXX (thrown >> by: sun.misc.Launcher$AppClassLoader) >> at java.lang.ClassLoader.loadClass(ClassLoader.java:366) >> at java.lang.Class.forName0(Native Method) >> at java.lang.Class.forName(Class.java:265) >> at Test.doIt(Test.java:7) >> at Test.main(Test.java:11) >> >> Instead of what we have now: >> >> Exception in thread "main" java.lang.ClassNotFoundException: XXX >> at java.net.URLClassLoader.findClass(URLClassLoader.java:381) >> at java.lang.ClassLoader.loadClass(ClassLoader.java:426) >> at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:317) >> at java.lang.ClassLoader.loadClass(ClassLoader.java:359) >> at java.lang.Class.forName0(Native Method) >> at java.lang.Class.forName(Class.java:265) >> at Test.doIt(Test.java:7) >> at Test.main(Test.java:11) >> >> >> Would this be enough to cover your concern? >> >> Regards, Peter >> >> >>> I am not sure about the need to hide the stackless c-tor as the effect >>> can >>> be achieved by overriding fillInStackTrace(); w/o the extra baggage of >>> JavaLangAccess. >>> >>> Overall very decent improvement. >>> >>> Cheers >>> Stanimir >>> >>> >>> > From paul.sandoz at oracle.com Thu Oct 16 09:30:08 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 16 Oct 2014 11:30:08 +0200 Subject: [9] Review request : JDK-8059070: [TESTBUG] java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java failed - timeout In-Reply-To: <543F8520.9090408@oracle.com> References: <543D1DEE.8030206@oracle.com> <543F8520.9090408@oracle.com> Message-ID: <8F9DD322-1793-4739-8155-61CE7D2C5AAB@oracle.com> On Oct 16, 2014, at 10:43 AM, Konstantin Shefov wrote: > Gently reminder > > On 14.10.2014 16:58, Konstantin Shefov wrote: >> Hello, >> >> Please review the test bug fix https://bugs.openjdk.java.net/browse/JDK-8059070 >> Webrev is http://cr.openjdk.java.net/~kshefov/8059070/webrev.00/ >> 45 private static final long TIMEOUT = 300000; Does jtreg define a system property for this value? and is 300s the same as what jtreg defines as the default? The online documentation (jtreg -onlineHelp) says the default is 2 minutes, but that might be out of date. Might be more readable to use: TimeUnit.SECONDS.toMillis(300); 143 long passedTime = new Date().getTime() - startTime; Why don't you use System.currentTimeMillis() instead of "new Date().getTime()" ? 145 double timeoutFactor = new Double(System.getProperty("test.timeout.factor", "1.0")); You can that pull out into a static and perhaps merge with TIMEOUT. 147 if (avgIterTime > 2 * remainTime) { That seems sufficient but it will be interesting to see if intermittent failures still occur due to high variance. Paul. From Alan.Bateman at oracle.com Thu Oct 16 09:54:04 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 16 Oct 2014 10:54:04 +0100 Subject: [9] Review request : JDK-8059070: [TESTBUG] java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java failed - timeout In-Reply-To: <8F9DD322-1793-4739-8155-61CE7D2C5AAB@oracle.com> References: <543D1DEE.8030206@oracle.com> <543F8520.9090408@oracle.com> <8F9DD322-1793-4739-8155-61CE7D2C5AAB@oracle.com> Message-ID: <543F95BC.7000900@oracle.com> On 16/10/2014 10:30, Paul Sandoz wrote: > : > 45 private static final long TIMEOUT = 300000; > > Does jtreg define a system property for this value? and is 300s the same as what jtreg defines as the default? > > The online documentation (jtreg -onlineHelp) says the default is 2 minutes, but that might be out of date. > It make the timeout factor available via the system property "test.timeout.factor", not the actual timeout (which is factor * 2mins assuming the test description doesn't override it). -Alan. From konstantin.shefov at oracle.com Thu Oct 16 10:03:44 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Thu, 16 Oct 2014 14:03:44 +0400 Subject: [9] Review request : JDK-8059070: [TESTBUG] java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java failed - timeout In-Reply-To: <8F9DD322-1793-4739-8155-61CE7D2C5AAB@oracle.com> References: <543D1DEE.8030206@oracle.com> <543F8520.9090408@oracle.com> <8F9DD322-1793-4739-8155-61CE7D2C5AAB@oracle.com> Message-ID: <543F9800.7040406@oracle.com> Paul, Thanks for reviewing In the jtreg scripts of the three existing LFCaching tests timeout is set explicitly to 300 seconds. The file currently being changed is not a test itself, it is parent class of tests. In fact we can unset this explicit timeout and use the current fix together with default JTREG timeout and jtreg timeout factor option. These test cases are randomly generated, so the more iterations, the better, but in fact we need at least one iteration. As for "if (avgIterTime > 2 * remainTime)", I think 2 is enough. -Konstantin On 16.10.2014 13:30, Paul Sandoz wrote: > On Oct 16, 2014, at 10:43 AM, Konstantin Shefov wrote: > >> Gently reminder >> >> On 14.10.2014 16:58, Konstantin Shefov wrote: >>> Hello, >>> >>> Please review the test bug fix https://bugs.openjdk.java.net/browse/JDK-8059070 >>> Webrev is http://cr.openjdk.java.net/~kshefov/8059070/webrev.00/ >>> > 45 private static final long TIMEOUT = 300000; > > Does jtreg define a system property for this value? and is 300s the same as what jtreg defines as the default? > > The online documentation (jtreg -onlineHelp) says the default is 2 minutes, but that might be out of date. > > Might be more readable to use: > > TimeUnit.SECONDS.toMillis(300); > > > 143 long passedTime = new Date().getTime() - startTime; > > Why don't you use System.currentTimeMillis() instead of "new Date().getTime()" ? > > > 145 double timeoutFactor = new Double(System.getProperty("test.timeout.factor", "1.0")); > > You can that pull out into a static and perhaps merge with TIMEOUT. > > > 147 if (avgIterTime > 2 * remainTime) { > > That seems sufficient but it will be interesting to see if intermittent failures still occur due to high variance. > > Paul. From igor.ignatyev at oracle.com Thu Oct 16 13:24:47 2014 From: igor.ignatyev at oracle.com (Igor Ignatyev) Date: Thu, 16 Oct 2014 17:24:47 +0400 Subject: [9] Review request : JDK-8059070: [TESTBUG] java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java failed - timeout In-Reply-To: <543F9800.7040406@oracle.com> References: <543D1DEE.8030206@oracle.com> <543F8520.9090408@oracle.com> <8F9DD322-1793-4739-8155-61CE7D2C5AAB@oracle.com> <543F9800.7040406@oracle.com> Message-ID: <543FC71F.8020504@oracle.com> Konstantin, I haven't looked at code religiously, so I wouldn't say that I have reviewed it. however I have some comments, please see them inline. On 10/16/2014 02:03 PM, Konstantin Shefov wrote: > Paul, > > Thanks for reviewing > > In the jtreg scripts of the three existing LFCaching tests timeout is > set explicitly to 300 seconds. The file currently being changed is not a > test itself, it is parent class of tests. > In fact we can unset this explicit timeout and use the current fix > together with default JTREG timeout and jtreg timeout factor option. > These test cases are randomly generated, so the more iterations, the > better, but in fact we need at least one iteration. > > As for "if (avgIterTime > 2 * remainTime)", I think 2 is enough. > > -Konstantin > > On 16.10.2014 13:30, Paul Sandoz wrote: >> On Oct 16, 2014, at 10:43 AM, Konstantin Shefov >> wrote: >> >>> Gently reminder >>> >>> On 14.10.2014 16:58, Konstantin Shefov wrote: >>>> Hello, >>>> >>>> Please review the test bug fix >>>> https://bugs.openjdk.java.net/browse/JDK-8059070 >>>> Webrev is http://cr.openjdk.java.net/~kshefov/8059070/webrev.00/ >>>> >> 45 private static final long TIMEOUT = 300000; >> >> Does jtreg define a system property for this value? and is 300s the >> same as what jtreg defines as the default? unfortunately, jtreg doesn't define a property for timeout, but I think it should do. we need to file an RFE against jtreg to add such a property and an RFE against these tests/testlibrary to use this property. could you please file them? >> >> The online documentation (jtreg -onlineHelp) says the default is 2 >> minutes, but that might be out of date. >> >> Might be more readable to use: >> >> TimeUnit.SECONDS.toMillis(300); >> >> >> 143 long passedTime = new Date().getTime() - startTime; >> >> Why don't you use System.currentTimeMillis() instead of "new >> Date().getTime()" ? >> >> >> 145 double timeoutFactor = new >> Double(System.getProperty("test.timeout.factor", "1.0")); >> >> You can that pull out into a static and perhaps merge with TIMEOUT. + you should use jdk.testlibrary.Utils::adjustTimeout instead of writing this code again. >> >> >> 147 if (avgIterTime > 2 * remainTime) { >> >> That seems sufficient but it will be interesting to see if >> intermittent failures still occur due to high variance. >> >> Paul. > Igor From peter.levart at gmail.com Thu Oct 16 14:05:26 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 16 Oct 2014 16:05:26 +0200 Subject: RFR: 8061244 Use of stack-less ClassNotFoundException thrown from (URL)ClassLoader.findClass() - was: Preview: JDK-8055854 Examine overhead in java.net.URLClassLoader (stack-less exceptions) In-Reply-To: <543F8558.2030401@gmail.com> References: <543EF592.3030409@gmail.com> <543F754B.4020001@gmail.com> <543F8558.2030401@gmail.com> Message-ID: <543FD0A6.3080207@gmail.com> I created an issue in Jira to track this investigation: https://bugs.openjdk.java.net/browse/JDK-8061244 The latest webrev of proposed patch is still: http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.02/ I invite the public to review it. Thanks. Peter On 10/16/2014 10:44 AM, Peter Levart wrote: > Hi, > > As for usage of SharedSecrets, they are not needed to access CNFE > package-private constructor from java.lang.ClassLoader, since they are > in the same package, and from java.net.URLClassLoader, the call to > super.findClass(name) does the job. So here's an updated webrev that > also includes more descriptive message: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.02/ > > > Regards, Peter > > On 10/16/2014 09:35 AM, Peter Levart wrote: >> On 10/16/2014 01:49 AM, Stanimir Simeonoff wrote: >>> First, really nice tests. >>> >>> As for hiding: missing the real classloader impl. might be quite a >>> bumper >>> for some middleware implementations. That would make pretty hard to >>> trace >>> dependency issues without explicit logging, the latter is usually >>> available >>> but still. Also it'd depend if the classloaders actually use >>> super.findClass() or not. >>> IMO, the option should be switchable via some system property. >> >> With a little tweak, the message of the stack-less exception thrown >> from findClass() methods can be extended to include the classloader's >> runtime class name and this message can be inherited by a replacement >> stack-full exception. So the stack-trace would look like: >> >> Exception in thread "main" java.lang.ClassNotFoundException: XXX >> (thrown by: sun.misc.Launcher$AppClassLoader) >> at java.lang.ClassLoader.loadClass(ClassLoader.java:366) >> at java.lang.Class.forName0(Native Method) >> at java.lang.Class.forName(Class.java:265) >> at Test.doIt(Test.java:7) >> at Test.main(Test.java:11) >> >> Instead of what we have now: >> >> Exception in thread "main" java.lang.ClassNotFoundException: XXX >> at java.net.URLClassLoader.findClass(URLClassLoader.java:381) >> at java.lang.ClassLoader.loadClass(ClassLoader.java:426) >> at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:317) >> at java.lang.ClassLoader.loadClass(ClassLoader.java:359) >> at java.lang.Class.forName0(Native Method) >> at java.lang.Class.forName(Class.java:265) >> at Test.doIt(Test.java:7) >> at Test.main(Test.java:11) >> >> >> Would this be enough to cover your concern? >> >> Regards, Peter >> >>> >>> I am not sure about the need to hide the stackless c-tor as the >>> effect can >>> be achieved by overriding fillInStackTrace(); w/o the extra baggage of >>> JavaLangAccess. >>> >>> Overall very decent improvement. >>> >>> Cheers >>> Stanimir >>> >>> > From kumar.x.srinivasan at oracle.com Fri Oct 17 00:53:13 2014 From: kumar.x.srinivasan at oracle.com (Kumar Srinivasan) Date: Thu, 16 Oct 2014 17:53:13 -0700 Subject: RFR 8060432: tools/pack200/TestNormal.java fails on Windows with java.io.FileNotFoundException after JDK-8058854 In-Reply-To: <543F7597.7060008@oracle.com> References: <543D30F1.2090505@oracle.com> <543D8B27.5090201@oracle.com> <543DDF21.7090402@oracle.com> <543F11CF.5060605@oracle.com> <543F7597.7060008@oracle.com> Message-ID: <54406879.9090300@oracle.com> Amy, I will take care of pushing this on Friday. Kumar On 10/16/2014 12:36 AM, Amy Lu wrote: > Thank you Kumar for your review. > > I need a sponsorfor push this fix. Alan, may I get your help? > > Thanks, > Amy > > On 10/16/14, 8:31 AM, Kumar Srinivasan wrote: >> Looks good! >> >> Kumar >> >> On 10/14/2014 7:42 PM, Amy Lu wrote: >>> On 10/15/14, 4:44 AM, Kumar Srinivasan wrote: >>>> Amy, >>>> >>>> The modifications you have made will not test pack200 compression >>>> and normalization correctly, as the test needs ".class" files. >>> >>> Sorry, I missed that. >>> Please review the updated version, test works on ".class" files >>> (Utils.TEST_CLS_DIR) >>> http://cr.openjdk.java.net/~weijun/8060432/webrev.01/ >>> >>>> Do you know >>>> why the test fails on windows ? >>> >>> extractJar(JarFile jf, File where) try to extract jar files to >>> folder "testdir", as the jar contains files of >>> C:/blabla >>> extractJar method run into issue on Windows as it try to extract it >>> to testdir\\C:\\blabla >>> >>> Anyway, as there already has some ".class" files to working on >>> (Utils.TEST_CLS_DIR), extractJar method is not needed. >>> >>> Thanks, >>> Amy >>>> >>>> Kumar >>>> >>>> >>>> On 10/14/2014 7:19 AM, Amy Lu wrote: >>>>> Please review the test fix. >>>>> >>>>> bug: https://bugs.openjdk.java.net/browse/JDK-8060432 >>>>> webrev: http://cr.openjdk.java.net/~weijun/8060432/webrev.00/ >>>>> >>>>> This test is to test >>>>> compareJars(new JarFile("normalized.jar"), new >>>>> JarFile("repacked.jar")); >>>>> where the jar files (normalized.jar repacked.jar and original.jar) >>>>> are created by "jar cnf" "jar cf" or "pack200 -r?. >>>>> >>>>> extractJar(JarFile jf, File where) is not really needed as this >>>>> method just try to provide some files for the test to do "jar >>>>> cnf?. Actually, "jar cnf" can work on any files, test just need >>>>> some files to jar with. >>>>> >>>>> Test can just simply created some files for that purpose. >>>>> >>>>> Thanks, >>>>> Amy >>>>> >>>> >>> >> > From staffan.friberg at oracle.com Fri Oct 17 01:42:02 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Thu, 16 Oct 2014 18:42:02 -0700 Subject: RFR JDK-6321472: Add CRC-32C API Message-ID: <544073EA.3060304@oracle.com> Hi, This RFE adds a CRC-32C class. It implements Checksum so it will have the same API CRC-32, but use a different polynomial when calculating the CRC checksum. CRC-32C implementation uses slicing-by-8 to achieve high performance when calculating the CRC value. A part from adding the new class, java.util.zip.CRC32C, I have also added two default methods to Checksum. These are methods that were added to Adler32 and CRC32 in JDK 8 but before default methods were added, which was why they were only added to the implementors and not the interface. Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 Webrev: http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 I have started a CCC request for the changes, but was asked to get feedback from the core libs group before finalizing the request in case there are any API or Javadoc changes suggested. Thanks, Staffan From peter.levart at gmail.com Fri Oct 17 08:46:16 2014 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 17 Oct 2014 10:46:16 +0200 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <544073EA.3060304@oracle.com> References: <544073EA.3060304@oracle.com> Message-ID: <5440D758.50703@gmail.com> On 10/17/2014 03:42 AM, Staffan Friberg wrote: > Hi, > > This RFE adds a CRC-32C class. It implements Checksum so it will have > the same API CRC-32, but use a different polynomial when calculating > the CRC checksum. > > CRC-32C implementation uses slicing-by-8 to achieve high performance > when calculating the CRC value. > > A part from adding the new class, java.util.zip.CRC32C, I have also > added two default methods to Checksum. These are methods that were > added to Adler32 and CRC32 in JDK 8 but before default methods were > added, which was why they were only added to the implementors and not > the interface. > > Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 > Webrev: http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 > > I have started a CCC request for the changes, but was asked to get > feedback from the core libs group before finalizing the request in > case there are any API or Javadoc changes suggested. > > Thanks, > Staffan Hi Staffan, I can see CRC32C.reflect(int) method reverses the bits in 32 bit int value. You could use Integer.reverse(int) instead. The CRC32C.swap32(int) method is (almost) exactly the same as Integer.reverseBytes(int) and equivalent. I wonder if handling ByteBuffer could be simplified. You could leverage it's own byte order manipulation by temporarily setting (and resetting afterwards) ByteBuffer.order() and then use ByteBuffer.getInt() to extract 32 bits at a time for your algorithm. This could get you the optimal variant of algorithm for both kinds of buffers (direct or byte[] based). Perhaps even the byte[] based variant of algorithm could be implemented by wrapping the array with ByteBuffer, passing it to common private method, and relying on the escape analysis of Hotspot to allocate the HeapByteBuffer wrapper object on stack. Regards, Peter From Alan.Bateman at oracle.com Fri Oct 17 09:00:15 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 17 Oct 2014 10:00:15 +0100 Subject: RFR 8023173: FileOutputStream(FileDescriptor) does not respect append flag on Windows In-Reply-To: <543271F1.8040505@oracle.com> References: <543271F1.8040505@oracle.com> Message-ID: <5440DA9F.9090304@oracle.com> On 06/10/2014 11:41, Ivan Gerasimov wrote: > Hello everybody! > > The append mode is emulated on Windows, therefore we have to keep a > flag indicating that. > > With the current implementation, the FileDescriptor does not know if > the file were opened with O_APPEND, and the flag is maintained at the > upper level. > This can cause inconsistency, when the FileDescriptor is reused to > construct a new FileOutputStream, as there is no information available > about the append/non-append mode. > > Even though the solution is quite straight-forward: moving the flag > from FileOutputStream, FileDispatcherImpl and FileChannelImpl to the > lower level of FileDescriptor, it touches 20 files across the > source-code base. > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8023173 > WEBREV: http://cr.openjdk.java.net/~igerasim/8023173/0/webrev/ > > With the fix, all the io/nio tests, including the new one, pass on all > available platforms. > > Would you please help review this fix? Martin prodded me a few times but I was busy with other things and only getting to this now. At a high level then moving the append down to FileDescriptor make sense but I have a few concerns. On Unix systems then it looks like getAppend is calling into the ioctl to get the file descriptor flags. If I read it correctly then it creates several problems for the usage in FileChannelImpl.position. I just wondering if you consider just leaving the append flag there and just retrieve the value once in the open method. I'm also wondering about the handleWrite implementation on Windows which changes to use additional JNI to retrieve the value of the append flag each time. We should try to avoid this (we want the native methods to be as simple as possible so that we can replace them in the future) so there may be an argument for passing that down as per the current implementation. -Alan. From paul.sandoz at oracle.com Fri Oct 17 09:37:08 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 17 Oct 2014 11:37:08 +0200 Subject: Covariant overrides on the Buffer Hierarchy redux In-Reply-To: <3D27B84B-20F1-486C-954F-E908DD443DA9@oracle.com> References: <3D27B84B-20F1-486C-954F-E908DD443DA9@oracle.com> Message-ID: <35FE2B2C-7BA2-4A11-AE9D-B5E12C7B5729@oracle.com> Hi, [Including compiler-dev, i am not on that list so please CC me if replying to just that list] I dropped this, then JVMLS got in the way... then J1 got in the way.... so i better get to this before Devoxx gets in the way... Richard, thanks for your continued patience. In the interim Richard made a slight tweak to the patch and some tests were updated to avoid casts: http://cr.openjdk.java.net/~rwarburton/buffer-overrides-3/ This looks good. Reviewed! BUT in the interim some warnings were enabled and now javac fails to compile: /Users/sandoz/Projects/jdk9/dev/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BaseFileManager.java:245: warning: [cast] redundant cast to CharBuffer return (CharBuffer)CharBuffer.allocate(1).flip(); ^ /Users/sandoz/Projects/jdk9/dev/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BaseFileManager.java:329: warning: [cast] redundant cast to ByteBuffer put((ByteBuffer)result.flip()); ^ /Users/sandoz/Projects/jdk9/dev/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BaseFileManager.java:336: warning: [cast] redundant cast to ByteBuffer return (ByteBuffer)result.flip(); ^ /Users/sandoz/Projects/jdk9/dev/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/BaseFileManager.java:352: warning: [cast] redundant cast to ByteBuffer ? (ByteBuffer)cached.clear() ^ /Users/sandoz/Projects/jdk9/dev/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java:81: warning: [cast] redundant cast to CharBuffer return ((CharBuffer)buffer.compact().flip()).array(); ^ error: warnings found and -Werror specified So Richard has a patch for that too: http://cr.openjdk.java.net/~rwarburton/buffer-overrides-langtools-0/langtools.patch This is required because in the bootstrap compilation phase a JDK without the co-variant overrides can be used. So the current solution is to suppress the warnings. Reviews from langtools gurus are very much appreciated. Ideally it would be nice to push all this under one issue, is that possible? If not i will have to create another issue and of course push to langtools before jdk. A internal CCC is also underway. Paul. From konstantin.shefov at oracle.com Fri Oct 17 09:38:36 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Fri, 17 Oct 2014 13:38:36 +0400 Subject: [9] Review request : JDK-8059070: [TESTBUG] java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java failed - timeout In-Reply-To: <543FC71F.8020504@oracle.com> References: <543D1DEE.8030206@oracle.com> <543F8520.9090408@oracle.com> <8F9DD322-1793-4739-8155-61CE7D2C5AAB@oracle.com> <543F9800.7040406@oracle.com> <543FC71F.8020504@oracle.com> Message-ID: <5440E39C.8070001@oracle.com> Hi, I have updated the webrev: http://cr.openjdk.java.net/~kshefov/8059070/webrev.01/ -Konstantin 16.10.2014 17:24, Igor Ignatyev ?????: > Konstantin, > > I haven't looked at code religiously, so I wouldn't say that I have > reviewed it. however I have some comments, please see them inline. > > On 10/16/2014 02:03 PM, Konstantin Shefov wrote: >> Paul, >> >> Thanks for reviewing >> >> In the jtreg scripts of the three existing LFCaching tests timeout is >> set explicitly to 300 seconds. The file currently being changed is not a >> test itself, it is parent class of tests. >> In fact we can unset this explicit timeout and use the current fix >> together with default JTREG timeout and jtreg timeout factor option. >> These test cases are randomly generated, so the more iterations, the >> better, but in fact we need at least one iteration. >> >> As for "if (avgIterTime > 2 * remainTime)", I think 2 is enough. >> >> -Konstantin >> >> On 16.10.2014 13:30, Paul Sandoz wrote: >>> On Oct 16, 2014, at 10:43 AM, Konstantin Shefov >>> wrote: >>> >>>> Gently reminder >>>> >>>> On 14.10.2014 16:58, Konstantin Shefov wrote: >>>>> Hello, >>>>> >>>>> Please review the test bug fix >>>>> https://bugs.openjdk.java.net/browse/JDK-8059070 >>>>> Webrev is http://cr.openjdk.java.net/~kshefov/8059070/webrev.00/ >>>>> >>> 45 private static final long TIMEOUT = 300000; >>> >>> Does jtreg define a system property for this value? and is 300s the >>> same as what jtreg defines as the default? > unfortunately, jtreg doesn't define a property for timeout, but I > think it should do. we need to file an RFE against jtreg to add such a > property and an RFE against these tests/testlibrary to use this > property. could you please file them? >>> >>> The online documentation (jtreg -onlineHelp) says the default is 2 >>> minutes, but that might be out of date. >>> >>> Might be more readable to use: >>> >>> TimeUnit.SECONDS.toMillis(300); >>> >>> >>> 143 long passedTime = new Date().getTime() - startTime; >>> >>> Why don't you use System.currentTimeMillis() instead of "new >>> Date().getTime()" ? >>> >>> >>> 145 double timeoutFactor = new >>> Double(System.getProperty("test.timeout.factor", "1.0")); >>> >>> You can that pull out into a static and perhaps merge with TIMEOUT. > + you should use jdk.testlibrary.Utils::adjustTimeout instead of > writing this code again. >>> >>> >>> 147 if (avgIterTime > 2 * remainTime) { >>> >>> That seems sufficient but it will be interesting to see if >>> intermittent failures still occur due to high variance. >>> >>> Paul. >> > > > Igor From Alan.Bateman at oracle.com Fri Oct 17 09:56:00 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 17 Oct 2014 10:56:00 +0100 Subject: Covariant overrides on the Buffer Hierarchy redux In-Reply-To: <35FE2B2C-7BA2-4A11-AE9D-B5E12C7B5729@oracle.com> References: <3D27B84B-20F1-486C-954F-E908DD443DA9@oracle.com> <35FE2B2C-7BA2-4A11-AE9D-B5E12C7B5729@oracle.com> Message-ID: <5440E7B0.6040706@oracle.com> On 17/10/2014 10:37, Paul Sandoz wrote: > Hi, > > [Including compiler-dev, i am not on that list so please CC me if replying to just that list] > > I dropped this, then JVMLS got in the way... then J1 got in the way.... so i better get to this before Devoxx gets in the way... Richard, thanks for your continued patience. > > In the interim Richard made a slight tweak to the patch and some tests were updated to avoid casts: > > http://cr.openjdk.java.net/~rwarburton/buffer-overrides-3/ > > This looks good. Reviewed! I've previously reviewed the changes the buffer changes and it looked good. The additional updates to drop casts in usages and tests also looks good. -Alan From Alan.Bateman at oracle.com Fri Oct 17 11:05:39 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 17 Oct 2014 12:05:39 +0100 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <544073EA.3060304@oracle.com> References: <544073EA.3060304@oracle.com> Message-ID: <5440F803.2000406@oracle.com> On 17/10/2014 02:42, Staffan Friberg wrote: > Hi, > > This RFE adds a CRC-32C class. It implements Checksum so it will have > the same API CRC-32, but use a different polynomial when calculating > the CRC checksum. > > CRC-32C implementation uses slicing-by-8 to achieve high performance > when calculating the CRC value. > > A part from adding the new class, java.util.zip.CRC32C, I have also > added two default methods to Checksum. These are methods that were > added to Adler32 and CRC32 in JDK 8 but before default methods were > added, which was why they were only added to the implementors and not > the interface. > > Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 > Webrev: http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 > I looked over the javadoc, I haven't found time to study the implementation in CRC32C closely yet. Hopefully Sherman will be able to review as he I think he has prototyped several CRC32C implementations. On Checksum#update(ByteBuffer) then a suggestion for: "The checksum is updated using buffer.remaining, starting a buffer.position" is to replace it with: "The checksum is updated with the remaining bytes in the buffer, starting at the buffer's position." In the @implNote then I wonder if it would be better to just leave out the note about when the invariants are broken, we don't do that in other places where breakage this is detected. Also I wonder if the note about "For best performance, ..." should be an @apiNote. Should CRC32C be final unless we have a good reason for it not to be final? In CRC32C then I assume you don't need the

/

for the first statement. The @see Checksum might not be too interesting here given that it will be linked to anyway by way of implement Checksum. I think it's more usual to list the @param tags before the @throws. For the bounds check then you might want to look at the wording in other areas (in java.lang or java.io for example) to get this better wording (as off+len can overflow). A minor comment on CRC32C is that you might want to keep the line lengths consistent with the rest of the code. I only mention is for future side-by-side reviews to make it a bit easier and avoid too much horizontal scrolling. -Alan. From vitalyd at gmail.com Fri Oct 17 13:06:29 2014 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Fri, 17 Oct 2014 09:06:29 -0400 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5440D758.50703@gmail.com> References: <544073EA.3060304@oracle.com> <5440D758.50703@gmail.com> Message-ID: In my experiments, ByteBuffer.wrap() with immediate use (e.g. BB.wrap (...).getInt (...)) does not trigger escape analysis (I.e. the BB is not eliminated). I suspect it's because wrap () is not trivial enough and compiler doesn't "see through" the noise there. Sent from my phone On Oct 17, 2014 4:46 AM, "Peter Levart" wrote: > > On 10/17/2014 03:42 AM, Staffan Friberg wrote: > >> Hi, >> >> This RFE adds a CRC-32C class. It implements Checksum so it will have the >> same API CRC-32, but use a different polynomial when calculating the CRC >> checksum. >> >> CRC-32C implementation uses slicing-by-8 to achieve high performance when >> calculating the CRC value. >> >> A part from adding the new class, java.util.zip.CRC32C, I have also added >> two default methods to Checksum. These are methods that were added to >> Adler32 and CRC32 in JDK 8 but before default methods were added, which was >> why they were only added to the implementors and not the interface. >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 >> Webrev: http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 >> >> I have started a CCC request for the changes, but was asked to get >> feedback from the core libs group before finalizing the request in case >> there are any API or Javadoc changes suggested. >> >> Thanks, >> Staffan >> > > Hi Staffan, > > I can see CRC32C.reflect(int) method reverses the bits in 32 bit int > value. You could use Integer.reverse(int) instead. > > The CRC32C.swap32(int) method is (almost) exactly the same as > Integer.reverseBytes(int) and equivalent. > > I wonder if handling ByteBuffer could be simplified. You could leverage > it's own byte order manipulation by temporarily setting (and resetting > afterwards) ByteBuffer.order() and then use ByteBuffer.getInt() to extract > 32 bits at a time for your algorithm. This could get you the optimal > variant of algorithm for both kinds of buffers (direct or byte[] based). > Perhaps even the byte[] based variant of algorithm could be implemented by > wrapping the array with ByteBuffer, passing it to common private method, > and relying on the escape analysis of Hotspot to allocate the > HeapByteBuffer wrapper object on stack. > > Regards, Peter > > From staffan.friberg at oracle.com Fri Oct 17 16:47:21 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Fri, 17 Oct 2014 09:47:21 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5440D758.50703@gmail.com> References: <544073EA.3060304@oracle.com> <5440D758.50703@gmail.com> Message-ID: <54414819.90803@oracle.com> On 10/17/2014 01:46 AM, Peter Levart wrote: > > On 10/17/2014 03:42 AM, Staffan Friberg wrote: >> Hi, >> >> This RFE adds a CRC-32C class. It implements Checksum so it will have >> the same API CRC-32, but use a different polynomial when calculating >> the CRC checksum. >> >> CRC-32C implementation uses slicing-by-8 to achieve high performance >> when calculating the CRC value. >> >> A part from adding the new class, java.util.zip.CRC32C, I have also >> added two default methods to Checksum. These are methods that were >> added to Adler32 and CRC32 in JDK 8 but before default methods were >> added, which was why they were only added to the implementors and not >> the interface. >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 >> Webrev: http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 >> >> I have started a CCC request for the changes, but was asked to get >> feedback from the core libs group before finalizing the request in >> case there are any API or Javadoc changes suggested. >> >> Thanks, >> Staffan > > Hi Staffan, > > I can see CRC32C.reflect(int) method reverses the bits in 32 bit int > value. You could use Integer.reverse(int) instead. > > The CRC32C.swap32(int) method is (almost) exactly the same as > Integer.reverseBytes(int) and equivalent. > > I wonder if handling ByteBuffer could be simplified. You could > leverage it's own byte order manipulation by temporarily setting (and > resetting afterwards) ByteBuffer.order() and then use > ByteBuffer.getInt() to extract 32 bits at a time for your algorithm. > This could get you the optimal variant of algorithm for both kinds of > buffers (direct or byte[] based). Perhaps even the byte[] based > variant of algorithm could be implemented by wrapping the array with > ByteBuffer, passing it to common private method, and relying on the > escape analysis of Hotspot to allocate the HeapByteBuffer wrapper > object on stack. > > Regards, Peter > Hi Peter, Thanks for reviewing. I have switched to the Integer methods. Was looking through that API but I was too stuck with the reflect and swap names so I missed the reverse methods... :) As Vitaly noted in his email the wrapped case runs much slower. Going through the generated code it looks like the getInt method actually read four bytes and then builds and int from them, unless we have some intrinsic replacing that code. Bits.java static int getIntL(long a) { return makeInt(_get(a + 3), _get(a + 2), _get(a + 1), _get(a )); } static private int makeInt(byte b3, byte b2, byte b1, byte b0) { return (((b3 ) << 24) | ((b2 & 0xff) << 16) | ((b1 & 0xff) << 8) | ((b0 & 0xff) )); } It looks like the same holds true for DirectByteBuffers unless you are on x86 which supports unaligned reads. So I think aligning and using Unsafe is the best option here for performance. DirectByteBuffer.java private int getInt(long a) { if (unaligned) { int x = unsafe.getInt(a); return (nativeByteOrder ? x : Bits.swap(x)); } return Bits.getInt(a, bigEndian); } Bits.java static boolean unaligned() { if (unalignedKnown) return unaligned; String arch = AccessController.doPrivileged( new sun.security.action.GetPropertyAction("os.arch")); unaligned = arch.equals("i386") || arch.equals("x86") || arch.equals("amd64") || arch.equals("x86_64"); unalignedKnown = true; return unaligned; } Regards, Staffan From peter.levart at gmail.com Fri Oct 17 18:36:54 2014 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 17 Oct 2014 20:36:54 +0200 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <54414819.90803@oracle.com> References: <544073EA.3060304@oracle.com> <5440D758.50703@gmail.com> <54414819.90803@oracle.com> Message-ID: <544161C6.5050004@gmail.com> Hi Staffan, You're right. I thought ByteBuffer was more optimal in this respect. Regards, Peter On 10/17/2014 06:47 PM, Staffan Friberg wrote: > Hi Peter, > > Thanks for reviewing. > > I have switched to the Integer methods. Was looking through that API > but I was too stuck with the reflect and swap names so I missed the > reverse methods... :) > > As Vitaly noted in his email the wrapped case runs much slower. Going > through the generated code it looks like the getInt method actually > read four bytes and then builds and int from them, unless we have some > intrinsic replacing that code. > > Bits.java > static int getIntL(long a) { > return makeInt(_get(a + 3), > _get(a + 2), > _get(a + 1), > _get(a )); > } > > static private int makeInt(byte b3, byte b2, byte b1, byte b0) { > return (((b3 ) << 24) | > ((b2 & 0xff) << 16) | > ((b1 & 0xff) << 8) | > ((b0 & 0xff) )); > } > > It looks like the same holds true for DirectByteBuffers unless you are > on x86 which supports unaligned reads. So I think aligning and using > Unsafe is the best option here for performance. > > DirectByteBuffer.java > private int getInt(long a) { > if (unaligned) { > int x = unsafe.getInt(a); > return (nativeByteOrder ? x : Bits.swap(x)); > } > return Bits.getInt(a, bigEndian); > } > > Bits.java > static boolean unaligned() { > if (unalignedKnown) > return unaligned; > String arch = AccessController.doPrivileged( > new sun.security.action.GetPropertyAction("os.arch")); > unaligned = arch.equals("i386") || arch.equals("x86") > || arch.equals("amd64") || arch.equals("x86_64"); > unalignedKnown = true; > return unaligned; > } > > Regards, > Staffan From stanimir at riflexo.com Fri Oct 17 18:44:49 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Fri, 17 Oct 2014 21:44:49 +0300 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <54415AA7.2030506@oracle.com> References: <544073EA.3060304@oracle.com> <5440D758.50703@gmail.com> <54414819.90803@oracle.com> <54415AA7.2030506@oracle.com> Message-ID: Actually I was under the impression I had included the list. Getting it done w now. Overall if you want speed you go unsafe (bit sad) as the JIT may not remove the bound checks off the ByteBuffer. Unsafe is pretty ugly overall, though and personally I try to avoid it giving up performance. On 64bit machines you might be better off with java.nio.LongBuffer instead. Stanimir On Fri, Oct 17, 2014 at 9:06 PM, Staffan Friberg wrote: > Hi Stanimir, > > Thanks for you idea, do you mind re-replying with reply all so it goes to > the list? Or I can simply reply to myself and include your comment. > > I forgot to add in my previous email that one of the follow up items for > this will be to implement intrinsics that uses available hardware > instructions, having a method that takes the buffer address will make that > much easier which is another reason to stay with the current implementation. > > Thanks, > Staffan > > > On 10/17/2014 10:06 AM, Stanimir Simeonoff wrote: > > Hi Staffan > > The actual "trick" is using ByteBuffer.asIntBuffer() while the address is > properly aligned. It's not the most intuitive approach but you get the read > stuff. > > Cheers > Stanimir > > > On Fri, Oct 17, 2014 at 7:47 PM, Staffan Friberg < > staffan.friberg at oracle.com> wrote: > >> On 10/17/2014 01:46 AM, Peter Levart wrote: >> >>> >>> On 10/17/2014 03:42 AM, Staffan Friberg wrote: >>> >>>> Hi, >>>> >>>> This RFE adds a CRC-32C class. It implements Checksum so it will have >>>> the same API CRC-32, but use a different polynomial when calculating the >>>> CRC checksum. >>>> >>>> CRC-32C implementation uses slicing-by-8 to achieve high performance >>>> when calculating the CRC value. >>>> >>>> A part from adding the new class, java.util.zip.CRC32C, I have also >>>> added two default methods to Checksum. These are methods that were added to >>>> Adler32 and CRC32 in JDK 8 but before default methods were added, which was >>>> why they were only added to the implementors and not the interface. >>>> >>>> Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 >>>> Webrev: http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 >>>> >>>> I have started a CCC request for the changes, but was asked to get >>>> feedback from the core libs group before finalizing the request in case >>>> there are any API or Javadoc changes suggested. >>>> >>>> Thanks, >>>> Staffan >>>> >>> >>> Hi Staffan, >>> >>> I can see CRC32C.reflect(int) method reverses the bits in 32 bit int >>> value. You could use Integer.reverse(int) instead. >>> >>> The CRC32C.swap32(int) method is (almost) exactly the same as >>> Integer.reverseBytes(int) and equivalent. >>> >>> I wonder if handling ByteBuffer could be simplified. You could leverage >>> it's own byte order manipulation by temporarily setting (and resetting >>> afterwards) ByteBuffer.order() and then use ByteBuffer.getInt() to extract >>> 32 bits at a time for your algorithm. This could get you the optimal >>> variant of algorithm for both kinds of buffers (direct or byte[] based). >>> Perhaps even the byte[] based variant of algorithm could be implemented by >>> wrapping the array with ByteBuffer, passing it to common private method, >>> and relying on the escape analysis of Hotspot to allocate the >>> HeapByteBuffer wrapper object on stack. >>> >>> Regards, Peter >>> >>> Hi Peter, >> >> Thanks for reviewing. >> >> I have switched to the Integer methods. Was looking through that API but >> I was too stuck with the reflect and swap names so I missed the reverse >> methods... :) >> >> As Vitaly noted in his email the wrapped case runs much slower. Going >> through the generated code it looks like the getInt method actually read >> four bytes and then builds and int from them, unless we have some intrinsic >> replacing that code. >> >> Bits.java >> static int getIntL(long a) { >> return makeInt(_get(a + 3), >> _get(a + 2), >> _get(a + 1), >> _get(a )); >> } >> >> static private int makeInt(byte b3, byte b2, byte b1, byte b0) { >> return (((b3 ) << 24) | >> ((b2 & 0xff) << 16) | >> ((b1 & 0xff) << 8) | >> ((b0 & 0xff) )); >> } >> >> It looks like the same holds true for DirectByteBuffers unless you are on >> x86 which supports unaligned reads. So I think aligning and using Unsafe is >> the best option here for performance. >> >> DirectByteBuffer.java >> private int getInt(long a) { >> if (unaligned) { >> int x = unsafe.getInt(a); >> return (nativeByteOrder ? x : Bits.swap(x)); >> } >> return Bits.getInt(a, bigEndian); >> } >> >> Bits.java >> static boolean unaligned() { >> if (unalignedKnown) >> return unaligned; >> String arch = AccessController.doPrivileged( >> new sun.security.action.GetPropertyAction("os.arch")); >> unaligned = arch.equals("i386") || arch.equals("x86") >> || arch.equals("amd64") || arch.equals("x86_64"); >> unalignedKnown = true; >> return unaligned; >> } >> >> Regards, >> Staffan >> > > > From staffan.friberg at oracle.com Fri Oct 17 18:53:42 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Fri, 17 Oct 2014 11:53:42 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: References: <544073EA.3060304@oracle.com> <5440D758.50703@gmail.com> <54414819.90803@oracle.com> <54415AA7.2030506@oracle.com> Message-ID: <544165B6.1020306@oracle.com> Fully agree that using Unsafe makes one sad. I'm just about to send out a new webrev with Alan's and Peter's comments, once I have that done I will give using the NIO-Buffer API a second try to see if using IntBuffer and LongBuffer is able to achieve similar performance. As I noted in my reply the second goal after adding this API will is to create intrinsics that make use of the crc32c instructions available on both x86 and SPARC which will bump the performance even further. So one thing I try to do is make sure the implementation makes it easy to do that without having to completely rewrite it again. Regards, Staffan On 10/17/2014 11:44 AM, Stanimir Simeonoff wrote: > Actually I was under the impression I had included the list. Getting > it done w now. > > Overall if you want speed you go unsafe (bit sad) as the JIT may not > remove the bound checks off the ByteBuffer. Unsafe is pretty ugly > overall, though and personally I try to avoid it giving up performance. > > On 64bit machines you might be better off with java.nio.LongBuffer > instead. > > Stanimir > > > On Fri, Oct 17, 2014 at 9:06 PM, Staffan Friberg > > wrote: > > Hi Stanimir, > > Thanks for you idea, do you mind re-replying with reply all so it > goes to the list? Or I can simply reply to myself and include your > comment. > > I forgot to add in my previous email that one of the follow up > items for this will be to implement intrinsics that uses available > hardware instructions, having a method that takes the buffer > address will make that much easier which is another reason to stay > with the current implementation. > > Thanks, > Staffan > > > On 10/17/2014 10:06 AM, Stanimir Simeonoff wrote: >> Hi Staffan >> >> The actual "trick" is using ByteBuffer.asIntBuffer() while the >> address is properly aligned. It's not the most intuitive approach >> but you get the read stuff. >> >> Cheers >> Stanimir >> >> >> On Fri, Oct 17, 2014 at 7:47 PM, Staffan Friberg >> > >> wrote: >> >> On 10/17/2014 01:46 AM, Peter Levart wrote: >> >> >> On 10/17/2014 03:42 AM, Staffan Friberg wrote: >> >> Hi, >> >> This RFE adds a CRC-32C class. It implements Checksum >> so it will have the same API CRC-32, but use a >> different polynomial when calculating the CRC checksum. >> >> CRC-32C implementation uses slicing-by-8 to achieve >> high performance when calculating the CRC value. >> >> A part from adding the new class, >> java.util.zip.CRC32C, I have also added two default >> methods to Checksum. These are methods that were >> added to Adler32 and CRC32 in JDK 8 but before >> default methods were added, which was why they were >> only added to the implementors and not the interface. >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 >> Webrev: >> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 >> >> >> I have started a CCC request for the changes, but was >> asked to get feedback from the core libs group before >> finalizing the request in case there are any API or >> Javadoc changes suggested. >> >> Thanks, >> Staffan >> >> >> Hi Staffan, >> >> I can see CRC32C.reflect(int) method reverses the bits in >> 32 bit int value. You could use Integer.reverse(int) instead. >> >> The CRC32C.swap32(int) method is (almost) exactly the >> same as Integer.reverseBytes(int) and equivalent. >> >> I wonder if handling ByteBuffer could be simplified. You >> could leverage it's own byte order manipulation by >> temporarily setting (and resetting afterwards) >> ByteBuffer.order() and then use ByteBuffer.getInt() to >> extract 32 bits at a time for your algorithm. This could >> get you the optimal variant of algorithm for both kinds >> of buffers (direct or byte[] based). Perhaps even the >> byte[] based variant of algorithm could be implemented by >> wrapping the array with ByteBuffer, passing it to common >> private method, and relying on the escape analysis of >> Hotspot to allocate the HeapByteBuffer wrapper object on >> stack. >> >> Regards, Peter >> >> Hi Peter, >> >> Thanks for reviewing. >> >> I have switched to the Integer methods. Was looking through >> that API but I was too stuck with the reflect and swap names >> so I missed the reverse methods... :) >> >> As Vitaly noted in his email the wrapped case runs much >> slower. Going through the generated code it looks like the >> getInt method actually read four bytes and then builds and >> int from them, unless we have some intrinsic replacing that code. >> >> Bits.java >> static int getIntL(long a) { >> return makeInt(_get(a + 3), >> _get(a + 2), >> _get(a + 1), >> _get(a )); >> } >> >> static private int makeInt(byte b3, byte b2, byte b1, >> byte b0) { >> return (((b3 ) << 24) | >> ((b2 & 0xff) << 16) | >> ((b1 & 0xff) << 8) | >> ((b0 & 0xff) )); >> } >> >> It looks like the same holds true for DirectByteBuffers >> unless you are on x86 which supports unaligned reads. So I >> think aligning and using Unsafe is the best option here for >> performance. >> >> DirectByteBuffer.java >> private int getInt(long a) { >> if (unaligned) { >> int x = unsafe.getInt(a); >> return (nativeByteOrder ? x : Bits.swap(x)); >> } >> return Bits.getInt(a, bigEndian); >> } >> >> Bits.java >> static boolean unaligned() { >> if (unalignedKnown) >> return unaligned; >> String arch = AccessController.doPrivileged( >> new >> sun.security.action.GetPropertyAction("os.arch")); >> unaligned = arch.equals("i386") || arch.equals("x86") >> || arch.equals("amd64") || arch.equals("x86_64"); >> unalignedKnown = true; >> return unaligned; >> } >> >> Regards, >> Staffan >> >> > > From staffan.friberg at oracle.com Fri Oct 17 18:58:00 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Fri, 17 Oct 2014 11:58:00 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5440F803.2000406@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> Message-ID: <544166B8.8090103@oracle.com> On 10/17/2014 04:05 AM, Alan Bateman wrote: > On 17/10/2014 02:42, Staffan Friberg wrote: >> Hi, >> >> This RFE adds a CRC-32C class. It implements Checksum so it will have >> the same API CRC-32, but use a different polynomial when calculating >> the CRC checksum. >> >> CRC-32C implementation uses slicing-by-8 to achieve high performance >> when calculating the CRC value. >> >> A part from adding the new class, java.util.zip.CRC32C, I have also >> added two default methods to Checksum. These are methods that were >> added to Adler32 and CRC32 in JDK 8 but before default methods were >> added, which was why they were only added to the implementors and not >> the interface. >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 >> Webrev: http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 >> > I looked over the javadoc, I haven't found time to study the > implementation in CRC32C closely yet. Hopefully Sherman will be able > to review as he I think he has prototyped several CRC32C implementations. > > On Checksum#update(ByteBuffer) then a suggestion for: > "The checksum is updated using buffer.remaining, starting a > buffer.position" > is to replace it with: > "The checksum is updated with the remaining bytes in the buffer, > starting at the buffer's position." Yes that reads much better. Updated CRC32 and Adler32 as well since they have the same text. > > In the @implNote then I wonder if it would be better to just leave out > the note about when the invariants are broken, we don't do that in > other places where breakage this is detected. Also I wonder if the > note about "For best performance, ..." should be an @apiNote. Done, removed the assert comment and changed the performance note to an @apiNote. > > Should CRC32C be final unless we have a good reason for it not to be > final? I simply followed what was used for CRC32 and Adler32, but I don't see a reason for not making it final. Guess it is too late to make those two classes final though? > > In CRC32C then I assume you don't need the

/

for the first > statement. The @see Checksum might not be too interesting here given > that it will be linked to anyway by way of implement Checksum. Removed @see in all three classes. > > I think it's more usual to list the @param tags before the @throws. I removed that @param tags as they are already described in the Checksum interface and will be picked up from there by Javadoc. Will do the same in CRC32 and Adler32 as well. > > For the bounds check then you might want to look at the wording in > other areas (in java.lang or java.io for example) to get this better > wording (as off+len can overflow). Done, I update CRC32 and Adler32 as well to make keep them as similar as possible. > > A minor comment on CRC32C is that you might want to keep the line > lengths consistent with the rest of the code. I only mention is for > future side-by-side reviews to make it a bit easier and avoid too much > horizontal scrolling. Done, lines are now <80 or very close in a few cases where breaking them made the code harder to read. > > -Alan Here is a new webrev with the updates from Alan's and Peter's suggestions. http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.01 Thanks, Staffan From stanimir at riflexo.com Fri Oct 17 19:45:31 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Fri, 17 Oct 2014 22:45:31 +0300 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <544166B8.8090103@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> Message-ID: Hi, I don't quite see the point of this line: private transient final static ByteOrder ENDIAN = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; should be just private static final ByteOrder ENDIAN = ByteOrder.nativeOrder(); Also you don't need equals for enums alikes, just reference comparison (==) as they are constants. Alternatively you can just replace it with a boolean as there are no more endianess options. Stanimir On Fri, Oct 17, 2014 at 9:58 PM, Staffan Friberg wrote: > On 10/17/2014 04:05 AM, Alan Bateman wrote: > >> On 17/10/2014 02:42, Staffan Friberg wrote: >> >>> Hi, >>> >>> This RFE adds a CRC-32C class. It implements Checksum so it will have >>> the same API CRC-32, but use a different polynomial when calculating the >>> CRC checksum. >>> >>> CRC-32C implementation uses slicing-by-8 to achieve high performance >>> when calculating the CRC value. >>> >>> A part from adding the new class, java.util.zip.CRC32C, I have also >>> added two default methods to Checksum. These are methods that were added to >>> Adler32 and CRC32 in JDK 8 but before default methods were added, which was >>> why they were only added to the implementors and not the interface. >>> >>> Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 >>> Webrev: http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 >>> >>> I looked over the javadoc, I haven't found time to study the >> implementation in CRC32C closely yet. Hopefully Sherman will be able to >> review as he I think he has prototyped several CRC32C implementations. >> >> On Checksum#update(ByteBuffer) then a suggestion for: >> "The checksum is updated using buffer.remaining, starting a >> buffer.position" >> is to replace it with: >> "The checksum is updated with the remaining bytes in the buffer, >> starting at the buffer's position." >> > > Yes that reads much better. Updated CRC32 and Adler32 as well since they > have the same text. > > >> In the @implNote then I wonder if it would be better to just leave out >> the note about when the invariants are broken, we don't do that in other >> places where breakage this is detected. Also I wonder if the note about >> "For best performance, ..." should be an @apiNote. >> > Done, removed the assert comment and changed the performance note to an > @apiNote. > > >> Should CRC32C be final unless we have a good reason for it not to be >> final? >> > I simply followed what was used for CRC32 and Adler32, but I don't see a > reason for not making it final. Guess it is too late to make those two > classes final though? > > >> In CRC32C then I assume you don't need the

/

for the first >> statement. The @see Checksum might not be too interesting here given that >> it will be linked to anyway by way of implement Checksum. >> > > Removed @see in all three classes. > > >> I think it's more usual to list the @param tags before the @throws. >> > I removed that @param tags as they are already described in the Checksum > interface and will be picked up from there by Javadoc. Will do the same in > CRC32 and Adler32 as well. > > >> For the bounds check then you might want to look at the wording in other >> areas (in java.lang or java.io for example) to get this better wording >> (as off+len can overflow). >> > Done, I update CRC32 and Adler32 as well to make keep them as similar as > possible. > > >> A minor comment on CRC32C is that you might want to keep the line lengths >> consistent with the rest of the code. I only mention is for future >> side-by-side reviews to make it a bit easier and avoid too much horizontal >> scrolling. >> > Done, lines are now <80 or very close in a few cases where breaking them > made the code harder to read. > >> >> -Alan >> > > Here is a new webrev with the updates from Alan's and Peter's suggestions. > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.01 > > Thanks, > Staffan > > From vitalyd at gmail.com Fri Oct 17 19:51:54 2014 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Fri, 17 Oct 2014 15:51:54 -0400 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> Message-ID: I wouldn't even bother with ENDIAN field; ByteOrder.nativeOrder(), which calls Bits.byteOrder(), which returns a static final field (modulo a null check) should get JIT compiled into just a read of Bits.byteOrder. If storing ByteOrder.nativeOrder() in a static final field actually makes a difference vs using ByteOrder.nativeOrder() in JIT compiled code, I'd be pretty sad :). On Fri, Oct 17, 2014 at 3:45 PM, Stanimir Simeonoff wrote: > Hi, > > I don't quite see the point of this line: > > private transient final static ByteOrder ENDIAN > = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN) > ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; > > should be just private static final ByteOrder ENDIAN = > ByteOrder.nativeOrder(); > > Also you don't need equals for enums alikes, just reference comparison (==) > as they are constants. > Alternatively you can just replace it with a boolean as there are no more > endianess options. > > Stanimir > > On Fri, Oct 17, 2014 at 9:58 PM, Staffan Friberg < > staffan.friberg at oracle.com > > wrote: > > > On 10/17/2014 04:05 AM, Alan Bateman wrote: > > > >> On 17/10/2014 02:42, Staffan Friberg wrote: > >> > >>> Hi, > >>> > >>> This RFE adds a CRC-32C class. It implements Checksum so it will have > >>> the same API CRC-32, but use a different polynomial when calculating > the > >>> CRC checksum. > >>> > >>> CRC-32C implementation uses slicing-by-8 to achieve high performance > >>> when calculating the CRC value. > >>> > >>> A part from adding the new class, java.util.zip.CRC32C, I have also > >>> added two default methods to Checksum. These are methods that were > added to > >>> Adler32 and CRC32 in JDK 8 but before default methods were added, > which was > >>> why they were only added to the implementors and not the interface. > >>> > >>> Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 > >>> Webrev: http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 > >>> > >>> I looked over the javadoc, I haven't found time to study the > >> implementation in CRC32C closely yet. Hopefully Sherman will be able to > >> review as he I think he has prototyped several CRC32C implementations. > >> > >> On Checksum#update(ByteBuffer) then a suggestion for: > >> "The checksum is updated using buffer.remaining, starting a > >> buffer.position" > >> is to replace it with: > >> "The checksum is updated with the remaining bytes in the buffer, > >> starting at the buffer's position." > >> > > > > Yes that reads much better. Updated CRC32 and Adler32 as well since they > > have the same text. > > > > > >> In the @implNote then I wonder if it would be better to just leave out > >> the note about when the invariants are broken, we don't do that in other > >> places where breakage this is detected. Also I wonder if the note about > >> "For best performance, ..." should be an @apiNote. > >> > > Done, removed the assert comment and changed the performance note to an > > @apiNote. > > > > > >> Should CRC32C be final unless we have a good reason for it not to be > >> final? > >> > > I simply followed what was used for CRC32 and Adler32, but I don't see a > > reason for not making it final. Guess it is too late to make those two > > classes final though? > > > > > >> In CRC32C then I assume you don't need the

/

for the first > >> statement. The @see Checksum might not be too interesting here given > that > >> it will be linked to anyway by way of implement Checksum. > >> > > > > Removed @see in all three classes. > > > > > >> I think it's more usual to list the @param tags before the @throws. > >> > > I removed that @param tags as they are already described in the Checksum > > interface and will be picked up from there by Javadoc. Will do the same > in > > CRC32 and Adler32 as well. > > > > > >> For the bounds check then you might want to look at the wording in other > >> areas (in java.lang or java.io for example) to get this better wording > >> (as off+len can overflow). > >> > > Done, I update CRC32 and Adler32 as well to make keep them as similar as > > possible. > > > > > >> A minor comment on CRC32C is that you might want to keep the line > lengths > >> consistent with the rest of the code. I only mention is for future > >> side-by-side reviews to make it a bit easier and avoid too much > horizontal > >> scrolling. > >> > > Done, lines are now <80 or very close in a few cases where breaking them > > made the code harder to read. > > > >> > >> -Alan > >> > > > > Here is a new webrev with the updates from Alan's and Peter's > suggestions. > > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.01 > > > > Thanks, > > Staffan > > > > > From stanimir at riflexo.com Fri Oct 17 19:54:58 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Fri, 17 Oct 2014 22:54:58 +0300 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <544166B8.8090103@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> Message-ID: Also, ede Unsafe.ADDRESS_SIZE == 4 That doesn't imply 32bit systems as with less than 32GiB (on 64bit) the default is using compressed options and the address size is still only 4bytes. I usually use something like this (in user space code) to detect the architecture private static final boolean is64Bit; static{ final String p = java.security.AccessController.doPrivileged(new PrivilegedAction() { @Override public String run() { return System.getProperty("os.arch", "x64")+System.getProperty("sun.arch.data.model"", "); } }); is64Bit = p.indexOf("64")>=0; }; Stanimir On Fri, Oct 17, 2014 at 9:58 PM, Staffan Friberg wrote: > On 10/17/2014 04:05 AM, Alan Bateman wrote: > >> On 17/10/2014 02:42, Staffan Friberg wrote: >> >>> Hi, >>> >>> This RFE adds a CRC-32C class. It implements Checksum so it will have >>> the same API CRC-32, but use a different polynomial when calculating the >>> CRC checksum. >>> >>> CRC-32C implementation uses slicing-by-8 to achieve high performance >>> when calculating the CRC value. >>> >>> A part from adding the new class, java.util.zip.CRC32C, I have also >>> added two default methods to Checksum. These are methods that were added to >>> Adler32 and CRC32 in JDK 8 but before default methods were added, which was >>> why they were only added to the implementors and not the interface. >>> >>> Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 >>> Webrev: http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 >>> >>> I looked over the javadoc, I haven't found time to study the >> implementation in CRC32C closely yet. Hopefully Sherman will be able to >> review as he I think he has prototyped several CRC32C implementations. >> >> On Checksum#update(ByteBuffer) then a suggestion for: >> "The checksum is updated using buffer.remaining, starting a >> buffer.position" >> is to replace it with: >> "The checksum is updated with the remaining bytes in the buffer, >> starting at the buffer's position." >> > > Yes that reads much better. Updated CRC32 and Adler32 as well since they > have the same text. > > >> In the @implNote then I wonder if it would be better to just leave out >> the note about when the invariants are broken, we don't do that in other >> places where breakage this is detected. Also I wonder if the note about >> "For best performance, ..." should be an @apiNote. >> > Done, removed the assert comment and changed the performance note to an > @apiNote. > > >> Should CRC32C be final unless we have a good reason for it not to be >> final? >> > I simply followed what was used for CRC32 and Adler32, but I don't see a > reason for not making it final. Guess it is too late to make those two > classes final though? > > >> In CRC32C then I assume you don't need the

/

for the first >> statement. The @see Checksum might not be too interesting here given that >> it will be linked to anyway by way of implement Checksum. >> > > Removed @see in all three classes. > > >> I think it's more usual to list the @param tags before the @throws. >> > I removed that @param tags as they are already described in the Checksum > interface and will be picked up from there by Javadoc. Will do the same in > CRC32 and Adler32 as well. > > >> For the bounds check then you might want to look at the wording in other >> areas (in java.lang or java.io for example) to get this better wording >> (as off+len can overflow). >> > Done, I update CRC32 and Adler32 as well to make keep them as similar as > possible. > > >> A minor comment on CRC32C is that you might want to keep the line lengths >> consistent with the rest of the code. I only mention is for future >> side-by-side reviews to make it a bit easier and avoid too much horizontal >> scrolling. >> > Done, lines are now <80 or very close in a few cases where breaking them > made the code harder to read. > >> >> -Alan >> > > Here is a new webrev with the updates from Alan's and Peter's suggestions. > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.01 > > Thanks, > Staffan > > From Ulf.Zibis at CoSoCo.de Fri Oct 17 19:56:17 2014 From: Ulf.Zibis at CoSoCo.de (Ulf Zibis) Date: Fri, 17 Oct 2014 21:56:17 +0200 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <544166B8.8090103@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> Message-ID: <54417461.2000600@CoSoCo.de> Am 17.10.2014 um 20:58 schrieb Staffan Friberg: > Here is a new webrev with the updates from Alan's and Peter's suggestions. > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.01 I would not remove: 86 public void update(byte[] b) { 87 adler = updateBytes(adler, b, 0, b.length); 88 } The interfaces default method invokes update(b, 0, b.length), which unnecessarily wastes performance with superfluous bound checks, but 86a if (b == null) { 86b throw new NullPointerException(); 86c } should be added, to behave same as 71 public void update(byte[] b, int off, int len) { in case of null array. My 2cc. -Ulf From david.r.chase at oracle.com Fri Oct 17 20:50:17 2014 From: david.r.chase at oracle.com (David Chase) Date: Fri, 17 Oct 2014 16:50:17 -0400 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <544165B6.1020306@oracle.com> References: <544073EA.3060304@oracle.com> <5440D758.50703@gmail.com> <54414819.90803@oracle.com> <54415AA7.2030506@oracle.com> <544165B6.1020306@oracle.com> Message-ID: <418E202F-2192-4B2A-828A-05BAF6305C8C@oracle.com> On 2014-10-17, at 2:53 PM, Staffan Friberg wrote: > Fully agree that using Unsafe makes one sad. > > I'm just about to send out a new webrev with Alan's and Peter's comments, once I have that done I will give using the NIO-Buffer API a second try to see if using IntBuffer and LongBuffer is able to achieve similar performance. > > As I noted in my reply the second goal after adding this API will is to create intrinsics that make use of the crc32c instructions available on both x86 and SPARC which will bump the performance even further. So one thing I try to do is make sure the implementation makes it easy to do that without having to completely rewrite it again. I?d like to review this, but it will take me a little bit of time. Recall that I did a lot of work on CRC for Intel to take advantage of the carryless multiply instructions for CRC32. Reading the comments, if I understand this properly, the difference between CRC32 and CRC32C is that CRC32C is just the bit or byte flip of CRC32 as we currently compute it. If so, wouldn?t it make more sense to not reinvent that rather tricky wheel? The code you have carefully written will run substantially slower than CRC32 on recent Intel hardware (Haswell and newer in particular) because there an intrinsic is already substituted. Can you verify whether this bit/byte flipping equivalence holds, or not? If we were interested in true peak performance, we?d also investigate fork/join parallelism; I did this once and it worked just fine if you made the block sizes large enough. David From staffan.friberg at oracle.com Fri Oct 17 21:00:39 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Fri, 17 Oct 2014 14:00:39 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> Message-ID: <54418377.9040200@oracle.com> Hi Stanimir, Unsafe.ADDRESS_SIZE is the size of a native pointer, and is not affected by how the JVM handles Java references on the heap. -------------- import sun.misc.Unsafe; public class AddressSize { public static void main(String[] args) { System.out.println("Address Size: " + Unsafe.ADDRESS_SIZE); } } -------------- $ java -showversion -XX:-UseCompressedOops AddressSize java version "1.8.0_25" Java(TM) SE Runtime Environment (build 1.8.0_25-b17) Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode) Address Size: 8 $ java -showversion -XX:+UseCompressedOops AddressSize java version "1.8.0_25" Java(TM) SE Runtime Environment (build 1.8.0_25-b17) Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode) Address Size: 8 $ ./jdk1.8.0_20-b26_32bit/bin/java -showversion AddressSize java version "1.8.0_20" Java(TM) SE Runtime Environment (build 1.8.0_20-b26) Java HotSpot(TM) Server VM (build 25.20-b23, mixed mode) Address Size: 4 //Staffan On 10/17/2014 12:54 PM, Stanimir Simeonoff wrote: > Also, ede > Unsafe.ADDRESS_SIZE == 4 > That doesn't imply 32bit systems as with less than 32GiB (on 64bit) > the default is using compressed options and the address size is still > only 4bytes. > I usually use something like this (in user space code) to detect the > architecture > private static final boolean is64Bit; > static{ > final String p = > java.security.AccessController.doPrivileged(new > PrivilegedAction() { > @Override > public String run() { > return System.getProperty("os.arch", > "x64")+System.getProperty("sun.arch.data.model"", "); > } > }); > is64Bit = p.indexOf("64")>=0; > }; > > Stanimir > > On Fri, Oct 17, 2014 at 9:58 PM, Staffan Friberg > > wrote: > > On 10/17/2014 04:05 AM, Alan Bateman wrote: > > On 17/10/2014 02:42, Staffan Friberg wrote: > > Hi, > > This RFE adds a CRC-32C class. It implements Checksum so > it will have the same API CRC-32, but use a different > polynomial when calculating the CRC checksum. > > CRC-32C implementation uses slicing-by-8 to achieve high > performance when calculating the CRC value. > > A part from adding the new class, java.util.zip.CRC32C, I > have also added two default methods to Checksum. These are > methods that were added to Adler32 and CRC32 in JDK 8 but > before default methods were added, which was why they were > only added to the implementors and not the interface. > > Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 > Webrev: > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 > > > I looked over the javadoc, I haven't found time to study the > implementation in CRC32C closely yet. Hopefully Sherman will > be able to review as he I think he has prototyped several > CRC32C implementations. > > On Checksum#update(ByteBuffer) then a suggestion for: > "The checksum is updated using buffer.remaining, starting a > buffer.position" > is to replace it with: > "The checksum is updated with the remaining bytes in the > buffer, starting at the buffer's position." > > > Yes that reads much better. Updated CRC32 and Adler32 as well > since they have the same text. > > > In the @implNote then I wonder if it would be better to just > leave out the note about when the invariants are broken, we > don't do that in other places where breakage this is > detected. Also I wonder if the note about "For best > performance, ..." should be an @apiNote. > > Done, removed the assert comment and changed the performance note > to an @apiNote. > > > Should CRC32C be final unless we have a good reason for it not > to be final? > > I simply followed what was used for CRC32 and Adler32, but I don't > see a reason for not making it final. Guess it is too late to make > those two classes final though? > > > In CRC32C then I assume you don't need the

/

for the > first statement. The @see Checksum might not be too > interesting here given that it will be linked to anyway by way > of implement Checksum. > > > Removed @see in all three classes. > > > I think it's more usual to list the @param tags before the > @throws. > > I removed that @param tags as they are already described in the > Checksum interface and will be picked up from there by Javadoc. > Will do the same in CRC32 and Adler32 as well. > > > For the bounds check then you might want to look at the > wording in other areas (in java.lang or java.io > for example) to get this better wording (as > off+len can overflow). > > Done, I update CRC32 and Adler32 as well to make keep them as > similar as possible. > > > A minor comment on CRC32C is that you might want to keep the > line lengths consistent with the rest of the code. I only > mention is for future side-by-side reviews to make it a bit > easier and avoid too much horizontal scrolling. > > Done, lines are now <80 or very close in a few cases where > breaking them made the code harder to read. > > > -Alan > > > Here is a new webrev with the updates from Alan's and Peter's > suggestions. > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.01 > > > Thanks, > Staffan > > From david.r.chase at oracle.com Fri Oct 17 21:06:36 2014 From: david.r.chase at oracle.com (David Chase) Date: Fri, 17 Oct 2014 17:06:36 -0400 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <418E202F-2192-4B2A-828A-05BAF6305C8C@oracle.com> References: <544073EA.3060304@oracle.com> <5440D758.50703@gmail.com> <54414819.90803@oracle.com> <54415AA7.2030506@oracle.com> <544165B6.1020306@oracle.com> <418E202F-2192-4B2A-828A-05BAF6305C8C@oracle.com> Message-ID: <5C922BF9-16DA-43E9-B090-86B1C9A5DF79@oracle.com> See also: http://cr.openjdk.java.net/~drchase/7088419/webrev.01/ This is the version that was not coded as an intrinsic, that also included fork/join. The crazy Intel instructions are accessed from native code, so you can get a feel for what the code looks like before it is converted to an intrinsic. There?s a certain amount of brain-hurt involved in the fork/join code, but it works. I?m still trying to figure out if the whole thing is just bit-flipped. David On 2014-10-17, at 4:50 PM, David Chase wrote: > > On 2014-10-17, at 2:53 PM, Staffan Friberg wrote: > >> Fully agree that using Unsafe makes one sad. >> >> I'm just about to send out a new webrev with Alan's and Peter's comments, once I have that done I will give using the NIO-Buffer API a second try to see if using IntBuffer and LongBuffer is able to achieve similar performance. >> >> As I noted in my reply the second goal after adding this API will is to create intrinsics that make use of the crc32c instructions available on both x86 and SPARC which will bump the performance even further. So one thing I try to do is make sure the implementation makes it easy to do that without having to completely rewrite it again. > > I?d like to review this, but it will take me a little bit of time. > Recall that I did a lot of work on CRC for Intel to take advantage > of the carryless multiply instructions for CRC32. > > Reading the comments, if I understand this properly, the difference between > CRC32 and CRC32C is that CRC32C is just the bit or byte flip of CRC32 as > we currently compute it. If so, wouldn?t it make more sense to not reinvent > that rather tricky wheel? The code you have carefully written will run substantially > slower than CRC32 on recent Intel hardware (Haswell and newer in particular) > because there an intrinsic is already substituted. > > Can you verify whether this bit/byte flipping equivalence holds, or not? > > If we were interested in true peak performance, we?d also investigate > fork/join parallelism; I did this once and it worked just fine if you made the > block sizes large enough. > > David > From staffan.friberg at oracle.com Fri Oct 17 21:22:22 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Fri, 17 Oct 2014 14:22:22 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5C922BF9-16DA-43E9-B090-86B1C9A5DF79@oracle.com> References: <544073EA.3060304@oracle.com> <5440D758.50703@gmail.com> <54414819.90803@oracle.com> <54415AA7.2030506@oracle.com> <544165B6.1020306@oracle.com> <418E202F-2192-4B2A-828A-05BAF6305C8C@oracle.com> <5C922BF9-16DA-43E9-B090-86B1C9A5DF79@oracle.com> Message-ID: <5441888E.8040402@oracle.com> Hi David, Not sure what you mean with a bit flip. Calculating CRC32 and then flipping the result in some way? The polynomial used for multiplication is different so while, as with all CRCs, the algorithm is similar, but a different polynomial is used and the final checksum will be different. The intrinsic that can be implemented for CRC32C will probably be even faster as it can make use of the specific crc32c instruction instead of using carry less multiplication. I have also been thinking that using fork-join to help for large arrays. I decided to not go after it for this first implementation of the new API. The other question is if that should be something that is more explicit, similar to parallel streams, as not everyone might want/expect that the API to suddenly start using multiple threads to calculate the result. Cheers, Staffan On 10/17/2014 02:06 PM, David Chase wrote: > See also: http://cr.openjdk.java.net/~drchase/7088419/webrev.01/ > > This is the version that was not coded as an intrinsic, that also included > fork/join. The crazy Intel instructions are accessed from native code, > so you can get a feel for what the code looks like before it is converted > to an intrinsic. There?s a certain amount of brain-hurt involved in the > fork/join code, but it works. > > I?m still trying to figure out if the whole thing is just bit-flipped. > > David > > On 2014-10-17, at 4:50 PM, David Chase wrote: > >> On 2014-10-17, at 2:53 PM, Staffan Friberg wrote: >> >>> Fully agree that using Unsafe makes one sad. >>> >>> I'm just about to send out a new webrev with Alan's and Peter's comments, once I have that done I will give using the NIO-Buffer API a second try to see if using IntBuffer and LongBuffer is able to achieve similar performance. >>> >>> As I noted in my reply the second goal after adding this API will is to create intrinsics that make use of the crc32c instructions available on both x86 and SPARC which will bump the performance even further. So one thing I try to do is make sure the implementation makes it easy to do that without having to completely rewrite it again. >> I?d like to review this, but it will take me a little bit of time. >> Recall that I did a lot of work on CRC for Intel to take advantage >> of the carryless multiply instructions for CRC32. >> >> Reading the comments, if I understand this properly, the difference between >> CRC32 and CRC32C is that CRC32C is just the bit or byte flip of CRC32 as >> we currently compute it. If so, wouldn?t it make more sense to not reinvent >> that rather tricky wheel? The code you have carefully written will run substantially >> slower than CRC32 on recent Intel hardware (Haswell and newer in particular) >> because there an intrinsic is already substituted. >> >> Can you verify whether this bit/byte flipping equivalence holds, or not? >> >> If we were interested in true peak performance, we?d also investigate >> fork/join parallelism; I did this once and it worked just fine if you made the >> block sizes large enough. >> >> David >> From stanimir at riflexo.com Fri Oct 17 22:03:51 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Sat, 18 Oct 2014 01:03:51 +0300 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <54418377.9040200@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <54418377.9040200@oracle.com> Message-ID: Thanks Staffan, You're absolutely right. Funny enough I was absolutely sure compressed ops affected it. Thanks Stanimir On Sat, Oct 18, 2014 at 12:00 AM, Staffan Friberg < staffan.friberg at oracle.com> wrote: > Hi Stanimir, > > Unsafe.ADDRESS_SIZE is the size of a native pointer, and is not affected > by how the JVM handles Java references on the heap. > > -------------- > > import sun.misc.Unsafe; > > public class AddressSize { > > public static void main(String[] args) { > System.out.println("Address Size: " + Unsafe.ADDRESS_SIZE); > } > } > > -------------- > > > $ java -showversion -XX:-UseCompressedOops AddressSize > java version "1.8.0_25" > Java(TM) SE Runtime Environment (build 1.8.0_25-b17) > Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode) > > Address Size: 8 > > > $ java -showversion -XX:+UseCompressedOops AddressSize > java version "1.8.0_25" > Java(TM) SE Runtime Environment (build 1.8.0_25-b17) > Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode) > > Address Size: 8 > > > $ ./jdk1.8.0_20-b26_32bit/bin/java -showversion AddressSize > java version "1.8.0_20" > Java(TM) SE Runtime Environment (build 1.8.0_20-b26) > Java HotSpot(TM) Server VM (build 25.20-b23, mixed mode) > > Address Size: 4 > > //Staffan > > > On 10/17/2014 12:54 PM, Stanimir Simeonoff wrote: > > Also, ede > > Unsafe.ADDRESS_SIZE == 4 > > That doesn't imply 32bit systems as with less than 32GiB (on 64bit) the > default is using compressed options and the address size is still only > 4bytes. > I usually use something like this (in user space code) to detect the > architecture > private static final boolean is64Bit; > static{ > final String p = java.security.AccessController.doPrivileged(new > PrivilegedAction() { > @Override > public String run() { > return System.getProperty("os.arch", > "x64")+System.getProperty("sun.arch.data.model"", "); > } > }); > is64Bit = p.indexOf("64")>=0; > }; > > Stanimir > > On Fri, Oct 17, 2014 at 9:58 PM, Staffan Friberg < > staffan.friberg at oracle.com> wrote: > >> On 10/17/2014 04:05 AM, Alan Bateman wrote: >> >>> On 17/10/2014 02:42, Staffan Friberg wrote: >>> >>>> Hi, >>>> >>>> This RFE adds a CRC-32C class. It implements Checksum so it will have >>>> the same API CRC-32, but use a different polynomial when calculating the >>>> CRC checksum. >>>> >>>> CRC-32C implementation uses slicing-by-8 to achieve high performance >>>> when calculating the CRC value. >>>> >>>> A part from adding the new class, java.util.zip.CRC32C, I have also >>>> added two default methods to Checksum. These are methods that were added to >>>> Adler32 and CRC32 in JDK 8 but before default methods were added, which was >>>> why they were only added to the implementors and not the interface. >>>> >>>> Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 >>>> Webrev: http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 >>>> >>>> I looked over the javadoc, I haven't found time to study the >>> implementation in CRC32C closely yet. Hopefully Sherman will be able to >>> review as he I think he has prototyped several CRC32C implementations. >>> >>> On Checksum#update(ByteBuffer) then a suggestion for: >>> "The checksum is updated using buffer.remaining, starting a >>> buffer.position" >>> is to replace it with: >>> "The checksum is updated with the remaining bytes in the buffer, >>> starting at the buffer's position." >>> >> >> Yes that reads much better. Updated CRC32 and Adler32 as well since they >> have the same text. >> >> >>> In the @implNote then I wonder if it would be better to just leave out >>> the note about when the invariants are broken, we don't do that in other >>> places where breakage this is detected. Also I wonder if the note about >>> "For best performance, ..." should be an @apiNote. >>> >> Done, removed the assert comment and changed the performance note to an >> @apiNote. >> >> >>> Should CRC32C be final unless we have a good reason for it not to be >>> final? >>> >> I simply followed what was used for CRC32 and Adler32, but I don't see a >> reason for not making it final. Guess it is too late to make those two >> classes final though? >> >> >>> In CRC32C then I assume you don't need the

/

for the first >>> statement. The @see Checksum might not be too interesting here given that >>> it will be linked to anyway by way of implement Checksum. >>> >> >> Removed @see in all three classes. >> >> >>> I think it's more usual to list the @param tags before the @throws. >>> >> I removed that @param tags as they are already described in the Checksum >> interface and will be picked up from there by Javadoc. Will do the same in >> CRC32 and Adler32 as well. >> >> >>> For the bounds check then you might want to look at the wording in other >>> areas (in java.lang or java.io for example) to get this better wording >>> (as off+len can overflow). >>> >> Done, I update CRC32 and Adler32 as well to make keep them as similar as >> possible. >> >> >>> A minor comment on CRC32C is that you might want to keep the line >>> lengths consistent with the rest of the code. I only mention is for future >>> side-by-side reviews to make it a bit easier and avoid too much horizontal >>> scrolling. >>> >> Done, lines are now <80 or very close in a few cases where breaking them >> made the code harder to read. >> >>> >>> -Alan >>> >> >> Here is a new webrev with the updates from Alan's and Peter's suggestions. >> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.01 >> >> Thanks, >> Staffan >> >> > > From staffan.friberg at oracle.com Fri Oct 17 22:38:03 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Fri, 17 Oct 2014 15:38:03 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <54417461.2000600@CoSoCo.de> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <54417461.2000600@CoSoCo.de> Message-ID: <54419A4B.1060008@oracle.com> Hi Ulf, Since the default method only calls a single method it will most likely be inlined. After inlining the check will be if (0 < 0 || b.length < 0 || 0 > b.length - b.length) { throw new ArrayIndexOutOfBoundsException(); } Which will be optimized away so only the null check will remain. My microbenchmark shows no difference between implementing the method or relying on the default method. Thanks, Staffan On 10/17/2014 12:56 PM, Ulf Zibis wrote: > Am 17.10.2014 um 20:58 schrieb Staffan Friberg: >> Here is a new webrev with the updates from Alan's and Peter's >> suggestions. >> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.01 > > I would not remove: > 86 public void update(byte[] b) { > 87 adler = updateBytes(adler, b, 0, b.length); > 88 } > > The interfaces default method invokes update(b, 0, b.length), which > unnecessarily wastes performance with superfluous bound checks, but > 86a if (b == null) { > 86b throw new NullPointerException(); > 86c } > should be added, to behave same as > 71 public void update(byte[] b, int off, int len) { > in case of null array. > > My 2cc. > > -Ulf > From staffan.friberg at oracle.com Fri Oct 17 22:46:53 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Fri, 17 Oct 2014 15:46:53 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> Message-ID: <54419C5D.7020101@oracle.com> Good point, looks like I was overly concerned about the null check and inlining of that method. I had to manually inline the slicing-by-8 loop to guarantee good performance. Removed the ENDIAN field and use ByteOrder.nativeOrder() directly instead. New webrev - http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.02 Thanks, Staffan On 10/17/2014 12:51 PM, Vitaly Davidovich wrote: > I wouldn't even bother with ENDIAN field; ByteOrder.nativeOrder(), > which calls Bits.byteOrder(), which returns a static final field > (modulo a null check) should get JIT compiled into just a read of > Bits.byteOrder. If storing ByteOrder.nativeOrder() in a static final > field actually makes a difference vs using ByteOrder.nativeOrder() in > JIT compiled code, I'd be pretty sad :). > > On Fri, Oct 17, 2014 at 3:45 PM, Stanimir Simeonoff > > wrote: > > Hi, > > I don't quite see the point of this line: > > private transient final static ByteOrder ENDIAN > = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN) > ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; > > should be just private static final ByteOrder ENDIAN = > ByteOrder.nativeOrder(); > > Also you don't need equals for enums alikes, just reference > comparison (==) > as they are constants. > Alternatively you can just replace it with a boolean as there are > no more > endianess options. > > Stanimir > > On Fri, Oct 17, 2014 at 9:58 PM, Staffan Friberg > > > wrote: > > > On 10/17/2014 04:05 AM, Alan Bateman wrote: > > > >> On 17/10/2014 02:42, Staffan Friberg wrote: > >> > >>> Hi, > >>> > >>> This RFE adds a CRC-32C class. It implements Checksum so it > will have > >>> the same API CRC-32, but use a different polynomial when > calculating the > >>> CRC checksum. > >>> > >>> CRC-32C implementation uses slicing-by-8 to achieve high > performance > >>> when calculating the CRC value. > >>> > >>> A part from adding the new class, java.util.zip.CRC32C, I have > also > >>> added two default methods to Checksum. These are methods that > were added to > >>> Adler32 and CRC32 in JDK 8 but before default methods were > added, which was > >>> why they were only added to the implementors and not the > interface. > >>> > >>> Bug: https://bugs.openjdk.java.net/browse/JDK-6321472 > >>> Webrev: > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.00 > > >>> > >>> I looked over the javadoc, I haven't found time to study the > >> implementation in CRC32C closely yet. Hopefully Sherman will be > able to > >> review as he I think he has prototyped several CRC32C > implementations. > >> > >> On Checksum#update(ByteBuffer) then a suggestion for: > >> "The checksum is updated using buffer.remaining, starting a > >> buffer.position" > >> is to replace it with: > >> "The checksum is updated with the remaining bytes in the buffer, > >> starting at the buffer's position." > >> > > > > Yes that reads much better. Updated CRC32 and Adler32 as well > since they > > have the same text. > > > > > >> In the @implNote then I wonder if it would be better to just > leave out > >> the note about when the invariants are broken, we don't do that > in other > >> places where breakage this is detected. Also I wonder if the > note about > >> "For best performance, ..." should be an @apiNote. > >> > > Done, removed the assert comment and changed the performance > note to an > > @apiNote. > > > > > >> Should CRC32C be final unless we have a good reason for it not > to be > >> final? > >> > > I simply followed what was used for CRC32 and Adler32, but I > don't see a > > reason for not making it final. Guess it is too late to make > those two > > classes final though? > > > > > >> In CRC32C then I assume you don't need the

/

for the first > >> statement. The @see Checksum might not be too interesting here > given that > >> it will be linked to anyway by way of implement Checksum. > >> > > > > Removed @see in all three classes. > > > > > >> I think it's more usual to list the @param tags before the @throws. > >> > > I removed that @param tags as they are already described in the > Checksum > > interface and will be picked up from there by Javadoc. Will do > the same in > > CRC32 and Adler32 as well. > > > > > >> For the bounds check then you might want to look at the wording > in other > >> areas (in java.lang or java.io for example) to > get this better wording > >> (as off+len can overflow). > >> > > Done, I update CRC32 and Adler32 as well to make keep them as > similar as > > possible. > > > > > >> A minor comment on CRC32C is that you might want to keep the > line lengths > >> consistent with the rest of the code. I only mention is for future > >> side-by-side reviews to make it a bit easier and avoid too much > horizontal > >> scrolling. > >> > > Done, lines are now <80 or very close in a few cases where > breaking them > > made the code harder to read. > > > >> > >> -Alan > >> > > > > Here is a new webrev with the updates from Alan's and Peter's > suggestions. > > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.01 > > > > > Thanks, > > Staffan > > > > > > From peter.levart at gmail.com Fri Oct 17 23:09:06 2014 From: peter.levart at gmail.com (Peter Levart) Date: Sat, 18 Oct 2014 01:09:06 +0200 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <544166B8.8090103@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> Message-ID: <5441A192.8090602@gmail.com> On 10/17/2014 08:58 PM, Staffan Friberg wrote: > Here is a new webrev with the updates from Alan's and Peter's > suggestions. > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.01 Hi Staffan, A few more comments... 217 if (Unsafe.ADDRESS_SIZE == 4) { 218 // On 32 bit platforms read two ints instead of a single 64bit long When you're reading from byte[] using Unsafe (updateBytes), you have the option of reading 64bit values on 64bit platforms. When you're reading from DirectByteBuffer memory (updateDirectByteBuffer), you're only using 32bit reads. Also, in updateBytes, the usage of Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a byte array sounds a little scary. To be ultra portable you could check that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use Unsafe for byte arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to manipulate 'offsets' instead. In updateDirectByteBuffer it would be more appropriate to use Integer.BYTES/Long.BYTES too. 225 firstHalf = (int) (value & 0xFFFFFFFF); 226 secondHalf = (int) (value >>> 32); 227 } else { // ByteOrder.BIG_ENDIAN 228 firstHalf = (int) (value >>> 32); 229 secondHalf = (int) (value & 0xFFFFFFFF); firstHalf = (int) value; // this is equivalent for line 225 secondHalf = (int) value; // this is equivalent for line 229 Regards, Peter From Ulf.Zibis at CoSoCo.de Fri Oct 17 23:26:05 2014 From: Ulf.Zibis at CoSoCo.de (Ulf Zibis) Date: Sat, 18 Oct 2014 01:26:05 +0200 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <54419A4B.1060008@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <54417461.2000600@CoSoCo.de> <54419A4B.1060008@oracle.com> Message-ID: <5441A58D.5040605@CoSoCo.de> Am 18.10.2014 um 00:38 schrieb Staffan Friberg: > Hi Ulf, > > Since the default method only calls a single method it will most likely be inlined. > > After inlining the check will be > > if (0 < 0 || b.length < 0 || 0 > b.length - b.length) { > throw new ArrayIndexOutOfBoundsException(); > } > > Which will be optimized away so only the null check will remain. > > My microbenchmark shows no difference between implementing the method or relying on the default > method. Thanks for the clarification. -Ulf From david.r.chase at oracle.com Sat Oct 18 02:52:55 2014 From: david.r.chase at oracle.com (David Chase) Date: Fri, 17 Oct 2014 22:52:55 -0400 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5441888E.8040402@oracle.com> References: <544073EA.3060304@oracle.com> <5440D758.50703@gmail.com> <54414819.90803@oracle.com> <54415AA7.2030506@oracle.com> <544165B6.1020306@oracle.com> <418E202F-2192-4B2A-828A-05BAF6305C8C@oracle.com> <5C922BF9-16DA-43E9-B090-86B1C9A5DF79@oracle.com> <5441888E.8040402@oracle.com> Message-ID: <4E1FA81E-7D08-4BD1-A3AF-25950596F5D1@oracle.com> On 2014-10-17, at 5:22 PM, Staffan Friberg wrote: > > The polynomial used for multiplication is different so while, as with all CRCs, the algorithm is similar, but a different polynomial is used and the final checksum will be different. Yes, I was misled by the comments. Wikipedia makes all clear. I thought maybe the polynomial itself was just bitflipped and the whole thing was computed with a different endianness, depending on whether you shift off the top or the bottom. > The intrinsic that can be implemented for CRC32C will probably be even faster as it can make use of the specific crc32c instruction instead of using carry less multiplication. It might not hurt to mock up a quick benchmark using the CRC32C instruction against jdk8?s java.util.zip.CRC32 intrinsic. CRC32 seems to consume 64 bits per instruction, and I think each instruction depends on its predecessor (naively coded, at least; there?s probably a hack to run them in parallel, just as there is a hack that allows fork/join. So maybe we should think about that hack, too; simply computing the two half-CRCs in parallel, then combining them as if fork/join, might break the data dependence and allow higher speed). The carryless multiply inner loop also consumes 64 bits per carryless multiply, but the instructions are not data dependent among themselves, so it might go faster. Haswell chips execute clmul especially quickly. The assembly language I wrote to make that go fast is agnostic about P; it is parameterized by a structure that contains a small number of constants that make it all go (6 64-bit numbers) based on powers of x (regarded as a polynomial) modulo the CRC polynomial P. If the endianness conventions match, and if zip CRC runs faster than the CRC32 instruction, I could revive it, and modern tools might let us avoid coding in hex. > I have also been thinking that using fork-join to help for large arrays. I decided to not go after it for this first implementation of the new API. The other question is if that should be something that is more explicit, similar to parallel streams, as not everyone might want/expect that the API to suddenly start using multiple threads to calculate the result. That?s why we have a system fork/join pool; if you don?t want lots of concurrency, limit the number of threads in that pool. Soon enough people are going to yell at us for not using concurrency when it is available, and forcing them to use a different API just to get concurrency will hinder the ability to write portable code. David From richard.warburton at gmail.com Sun Oct 19 22:13:14 2014 From: richard.warburton at gmail.com (Richard Warburton) Date: Sun, 19 Oct 2014 23:13:14 +0100 Subject: Lower overhead String encoding/decoding In-Reply-To: <542441BB.600@oracle.com> References: <54200F07.4070604@oracle.com> <542441BB.600@oracle.com> Message-ID: Hi, Hi Richard, couple comments after a quick scan. > Thanks for your comments - only just had a post Javaone chance to look at this stuff. I've pushed an update to: *http://cr.openjdk.java.net/~rwarburton/string-patch-webrev-7 * (1) #474, the IOBE probably is no longer needed in case of ByteBuffer. > parameter. > Fixed in new push. (2) for methods that have the ByteBuffer as input, it would be desirable to > specify clearly that > the bytes are read from "position" to "limit", and whether or not the > "position" will be advanced > after decoding/encoding (important). > Added Javadoc in new push. (3) getBytes(byte[], offset, charset) > while I understand it might be useful to have such a method in > certain circumstance, it is > usually complicated to make it right/easy for user to actually use > it. Consider the fact that > the returned number of bytes encoded has no straightforward > connection to how many > underlying chars have been encoded (so the user of this method really > have no idea how > many underlying "chars" have been encoded into the dest buffer, is > that enough? how big > the buffer need to be to encode the whole string? ....) especially > the possibility that the last > couple byte space might be short of encoding a "char". Not like the > getChars(), which has > a easy, clear and direct link between the out going chars and > underlying chars. I would > suggest it might be better to leave it out. > I think you raise some good points here. In my mind this is how it works, let me know what you think. The client code of this API call should be able to infer the state of the byte[] - the offset parameters is in terms of bytes and refers to the destination buffer. If you want to know how many bytes have been used by the encoding, the method returns an int that shows the length. You can query the length of the String, which gives you the number of outbound chars. (4) StringCoding.decode() #239 "remaining()" should be used to return > limit - position? > Fixed in new push. (5) in case of "untrusted", it might be more straightforward to get all > "bytes" out of the buffer > first (you are allocating a byte buffer here anyway, I don;t see > obvious benefit to get a > direct buffer, btw) and then pass it to the original/existing > byte[]->char[] decoding > implementation. We probably will take a deep look at the > implementation later when > the public api settled. > Yes - I was hoping to remove the additional bytebuffer allocation within the method. I'm still not sure of the security implications around removing this code though. regards, Richard Warburton http://insightfullogic.com @RichardWarburto From ecki at zusammenkunft.net Mon Oct 20 02:42:13 2014 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Mon, 20 Oct 2014 04:42:13 +0200 Subject: FilterOutputStream.close() throws exception from flush() In-Reply-To: <5367A48C.9010303@oracle.com> References: <20140503020432.0000230d.ecki@zusammenkunft.net> <53675A8B.7060107@oracle.com> <5367A2DE.8090100@gmail.com> <5367A48C.9010303@oracle.com> Message-ID: <20141020044213.00000808.ecki@zusammenkunft.net> Hello, sorry for coming up with that thread again, but I see that JDK-8042377 is hanging around with no action, and there was not yet any discussion I have seen about why it would be robust to call this IAE. I know there was quite some work done in 2013 to make this self-supression IAE a bit less painfull (8012044: Give more information about self-suppression from Throwable.addSuppressed) but it was never really discussed why it is needed at all? Gruss Bernd Am Mon, 05 May 2014 15:47:40 +0100 schrieb Alan Bateman : > On 05/05/2014 15:40, Peter Levart wrote: > > > > Hi Alan, > > > > There has been a discussion about a year ago on this list: > > > > http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-April/015947.html > > > Yes, I remember this and also reviewed it for Joe. My point about it > not coming up before was in the context of BufferedWriter/etc where > close needs to flush. In that case then I think it would be more > typically to throw a new IOException each time. > > I'll leave to Joe to comment on suggestion to drop self suppression. > > -Alan From Alan.Bateman at oracle.com Mon Oct 20 07:34:47 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 20 Oct 2014 08:34:47 +0100 Subject: Lower overhead String encoding/decoding In-Reply-To: References: <54200F07.4070604@oracle.com> <542441BB.600@oracle.com> Message-ID: <5444BB17.8080708@oracle.com> On 19/10/2014 23:13, Richard Warburton wrote: > Hi, > > Hi Richard, couple comments after a quick scan. > Thanks for your comments - only just had a post Javaone chance to look at > this stuff. I've pushed an update to: > > *http://cr.openjdk.java.net/~rwarburton/string-patch-webrev-7 > * > I think this looks better but I have a few comments on the API. For String(ByteBuffer, Charset) then it's still inconsistent to read from the buffer position but not advance it. I think the constructor needs to work like a regular decode in that respect. Related to this is the underflow case where there are insufficient remaining bytes to complete. If you don't advance the position then there is no way to detect this. The statement about the length of the String ".. may not be equal to the length of the subarray" might be there from a previous iteration. There isn't any array in the method signature so I think this statement needs to be make a bit clearer. For getBytes(byte[], int, int, Charset) then I think the javadoc could say a bit more. It will encode to a maximum of destBuffer.length - destOffset for example. The @return should probably say that it's the number of bytes written to the array rather than "copied". Minor nits is that you probably don't want the starting

. Also the finals in the signature seem noisy/not needed. The getBytes(ByteBuffer, Charset) method needs a bit more javadoc. You should be able to borrow from text from the CharsetEncoder#encode methods to help with that. -Alan. From konstantin.shefov at oracle.com Mon Oct 20 08:21:13 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Mon, 20 Oct 2014 12:21:13 +0400 Subject: [9] Review request : JDK-8059070: [TESTBUG] java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java failed - timeout In-Reply-To: <5440E39C.8070001@oracle.com> References: <543D1DEE.8030206@oracle.com> <543F8520.9090408@oracle.com> <8F9DD322-1793-4739-8155-61CE7D2C5AAB@oracle.com> <543F9800.7040406@oracle.com> <543FC71F.8020504@oracle.com> <5440E39C.8070001@oracle.com> Message-ID: <5444C5F9.4040005@oracle.com> Gently reminder On 17.10.2014 13:38, Konstantin Shefov wrote: > Hi, > > I have updated the webrev: > http://cr.openjdk.java.net/~kshefov/8059070/webrev.01/ > > -Konstantin > > 16.10.2014 17:24, Igor Ignatyev ?????: >> Konstantin, >> >> I haven't looked at code religiously, so I wouldn't say that I have >> reviewed it. however I have some comments, please see them inline. >> >> On 10/16/2014 02:03 PM, Konstantin Shefov wrote: >>> Paul, >>> >>> Thanks for reviewing >>> >>> In the jtreg scripts of the three existing LFCaching tests timeout is >>> set explicitly to 300 seconds. The file currently being changed is >>> not a >>> test itself, it is parent class of tests. >>> In fact we can unset this explicit timeout and use the current fix >>> together with default JTREG timeout and jtreg timeout factor option. >>> These test cases are randomly generated, so the more iterations, the >>> better, but in fact we need at least one iteration. >>> >>> As for "if (avgIterTime > 2 * remainTime)", I think 2 is enough. >>> >>> -Konstantin >>> >>> On 16.10.2014 13:30, Paul Sandoz wrote: >>>> On Oct 16, 2014, at 10:43 AM, Konstantin Shefov >>>> wrote: >>>> >>>>> Gently reminder >>>>> >>>>> On 14.10.2014 16:58, Konstantin Shefov wrote: >>>>>> Hello, >>>>>> >>>>>> Please review the test bug fix >>>>>> https://bugs.openjdk.java.net/browse/JDK-8059070 >>>>>> Webrev is http://cr.openjdk.java.net/~kshefov/8059070/webrev.00/ >>>>>> >>>> 45 private static final long TIMEOUT = 300000; >>>> >>>> Does jtreg define a system property for this value? and is 300s the >>>> same as what jtreg defines as the default? >> unfortunately, jtreg doesn't define a property for timeout, but I >> think it should do. we need to file an RFE against jtreg to add such >> a property and an RFE against these tests/testlibrary to use this >> property. could you please file them? >>>> >>>> The online documentation (jtreg -onlineHelp) says the default is 2 >>>> minutes, but that might be out of date. >>>> >>>> Might be more readable to use: >>>> >>>> TimeUnit.SECONDS.toMillis(300); >>>> >>>> >>>> 143 long passedTime = new Date().getTime() - startTime; >>>> >>>> Why don't you use System.currentTimeMillis() instead of "new >>>> Date().getTime()" ? >>>> >>>> >>>> 145 double timeoutFactor = new >>>> Double(System.getProperty("test.timeout.factor", "1.0")); >>>> >>>> You can that pull out into a static and perhaps merge with TIMEOUT. >> + you should use jdk.testlibrary.Utils::adjustTimeout instead of >> writing this code again. >>>> >>>> >>>> 147 if (avgIterTime > 2 * remainTime) { >>>> >>>> That seems sufficient but it will be interesting to see if >>>> intermittent failures still occur due to high variance. >>>> >>>> Paul. >>> >> >> >> Igor > From ivan.gerasimov at oracle.com Mon Oct 20 12:34:10 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Mon, 20 Oct 2014 16:34:10 +0400 Subject: RFR 8023173: FileOutputStream(FileDescriptor) does not respect append flag on Windows In-Reply-To: <5440DA9F.9090304@oracle.com> References: <543271F1.8040505@oracle.com> <5440DA9F.9090304@oracle.com> Message-ID: <54450142.4040207@oracle.com> Thank you Alan for the review! On 17.10.2014 13:00, Alan Bateman wrote: > On 06/10/2014 11:41, Ivan Gerasimov wrote: >> Hello everybody! >> >> The append mode is emulated on Windows, therefore we have to keep a >> flag indicating that. >> >> With the current implementation, the FileDescriptor does not know if >> the file were opened with O_APPEND, and the flag is maintained at the >> upper level. >> This can cause inconsistency, when the FileDescriptor is reused to >> construct a new FileOutputStream, as there is no information >> available about the append/non-append mode. >> >> Even though the solution is quite straight-forward: moving the flag >> from FileOutputStream, FileDispatcherImpl and FileChannelImpl to the >> lower level of FileDescriptor, it touches 20 files across the >> source-code base. >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8023173 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8023173/0/webrev/ >> >> With the fix, all the io/nio tests, including the new one, pass on >> all available platforms. >> >> Would you please help review this fix? > Martin prodded me a few times but I was busy with other things and > only getting to this now. > > At a high level then moving the append down to FileDescriptor make > sense but I have a few concerns. > > On Unix systems then it looks like getAppend is calling into the ioctl > to get the file descriptor flags. > If I read it correctly then it creates several problems for the usage > in FileChannelImpl.position. I thought it might look like a data duplication, if we store the append flag both in FileChannelImpl and FileDescriptor. Though, we surely can retrieve the append flag only once and cache it. I updated the webrev with this change. > I just wondering if you consider just leaving the append flag there > and just retrieve the value once in the open method. > > I'm also wondering about the handleWrite implementation on Windows > which changes to use additional JNI to retrieve the value of the > append flag each time. We should try to avoid this (we want the native > methods to be as simple as possible so that we can replace them in the > future) so there may be an argument for passing that down as per the > current implementation. > We would still need to retrieve the flag from native code. For example, the platform specific handleWrite() is called from the native FileOutputStream.writeBytes(), which is called from FileOutputStream.writt(), which is common for all the platforms. Thus, we should either retrieve the append flag from the Java code for any platform, and ignore it later on Unix, or read the flag in the native Windows-only code. Alternatively, we could separate implementations of FileOutputStream.java for different platforms, but that would complicate everything. Hopefully, in the future we could find a way to use FILE_APPEND_DATA, so FileDescriptor.append can be removed altogether with that corresponding JNI code. Here's the updated webrev: http://cr.openjdk.java.net/~igerasim/8023173/1/webrev/ I've also included a few typo fixes left after JDK-8059840. Sincerely yours, Ivan From roger.riggs at oracle.com Mon Oct 20 13:20:20 2014 From: roger.riggs at oracle.com (roger riggs) Date: Mon, 20 Oct 2014 09:20:20 -0400 Subject: RFR 8023173: FileOutputStream(FileDescriptor) does not respect append flag on Windows In-Reply-To: <54450142.4040207@oracle.com> References: <543271F1.8040505@oracle.com> <5440DA9F.9090304@oracle.com> <54450142.4040207@oracle.com> Message-ID: <54450C14.1000308@oracle.com> Hi Ivan, This webrev appears removes the ability to interpose on various method using byte-code injection. For example, FileOutputStream.write(byte). Do *not *replace delete the Java method calls that call native. It looks like an optimization but disables some functions that allow monitoring of I/O activities such as JFR. Thanks, Roger On 10/20/2014 8:34 AM, Ivan Gerasimov wrote: > Thank you Alan for the review! > > On 17.10.2014 13:00, Alan Bateman wrote: >> On 06/10/2014 11:41, Ivan Gerasimov wrote: >>> Hello everybody! >>> >>> The append mode is emulated on Windows, therefore we have to keep a >>> flag indicating that. >>> >>> With the current implementation, the FileDescriptor does not know if >>> the file were opened with O_APPEND, and the flag is maintained at >>> the upper level. >>> This can cause inconsistency, when the FileDescriptor is reused to >>> construct a new FileOutputStream, as there is no information >>> available about the append/non-append mode. >>> >>> Even though the solution is quite straight-forward: moving the flag >>> from FileOutputStream, FileDispatcherImpl and FileChannelImpl to >>> the lower level of FileDescriptor, it touches 20 files across the >>> source-code base. >>> >>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8023173 >>> WEBREV: http://cr.openjdk.java.net/~igerasim/8023173/0/webrev/ >>> >>> With the fix, all the io/nio tests, including the new one, pass on >>> all available platforms. >>> >>> Would you please help review this fix? >> Martin prodded me a few times but I was busy with other things and >> only getting to this now. >> >> At a high level then moving the append down to FileDescriptor make >> sense but I have a few concerns. >> >> On Unix systems then it looks like getAppend is calling into the >> ioctl to get the file descriptor flags. >> If I read it correctly then it creates several problems for the usage >> in FileChannelImpl.position. > > I thought it might look like a data duplication, if we store the > append flag both in FileChannelImpl and FileDescriptor. > Though, we surely can retrieve the append flag only once and cache it. > > I updated the webrev with this change. > >> I just wondering if you consider just leaving the append flag there >> and just retrieve the value once in the open method. >> > >> I'm also wondering about the handleWrite implementation on Windows >> which changes to use additional JNI to retrieve the value of the >> append flag each time. We should try to avoid this (we want the >> native methods to be as simple as possible so that we can replace >> them in the future) so there may be an argument for passing that down >> as per the current implementation. >> > > We would still need to retrieve the flag from native code. > For example, the platform specific handleWrite() is called from the > native FileOutputStream.writeBytes(), which is called from > FileOutputStream.writt(), which is common for all the platforms. > Thus, we should either retrieve the append flag from the Java code for > any platform, and ignore it later on Unix, or read the flag in the > native Windows-only code. > > Alternatively, we could separate implementations of > FileOutputStream.java for different platforms, but that would > complicate everything. > > Hopefully, in the future we could find a way to use FILE_APPEND_DATA, > so FileDescriptor.append can be removed altogether with that > corresponding JNI code. > > Here's the updated webrev: > http://cr.openjdk.java.net/~igerasim/8023173/1/webrev/ > > I've also included a few typo fixes left after JDK-8059840. > > Sincerely yours, > Ivan > From roger.riggs at oracle.com Mon Oct 20 14:53:25 2014 From: roger.riggs at oracle.com (roger riggs) Date: Mon, 20 Oct 2014 10:53:25 -0400 Subject: RFR 9: 8048124 Read hijrah-config-umalqura.properties as a resource Message-ID: <544521E5.5060300@oracle.com> Please review for JDK 9 only. To aid the modularization effort, the configuration of the Hijrah calendar should move the Hijrah calendar data to a resource. At this point, it does not look like there will be other Hijrah calendar variants; the function of calendar.properties to configure variants is unnecessary and is proposed to be removed. Since the other uses of calendars.properties have been eliminated the calendars.properties is removed. Webrev: http://cr.openjdk.java.net/~rriggs/webrev-hijrah-config-8049376/ Issue: https://bugs.openjdk.java.net/browse/JDK-8048124 Thanks, Roger From Alan.Bateman at oracle.com Mon Oct 20 15:07:56 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 20 Oct 2014 16:07:56 +0100 Subject: RFR 9: 8048124 Read hijrah-config-umalqura.properties as a resource In-Reply-To: <544521E5.5060300@oracle.com> References: <544521E5.5060300@oracle.com> Message-ID: <5445254C.7070408@oracle.com> On 20/10/2014 15:53, roger riggs wrote: > Please review for JDK 9 only. > > To aid the modularization effort, the configuration of the Hijrah > calendar > should move the Hijrah calendar data to a resource. > > At this point, it does not look like there will be other Hijrah calendar > variants; the function of calendar.properties to configure variants > is unnecessary and is proposed to be removed. > > Since the other uses of calendars.properties have been eliminated > the calendars.properties is removed. > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-hijrah-config-8049376/ > Issue: > https://bugs.openjdk.java.net/browse/JDK-8048124 This mostly looks good to me. I just wonder about the removal of the doPrivileged in readConfigProperties where you will get null if there is something on the stack with restricted permissions. A minor comment on the @implNote in HijrahChronology is that it has more than I would expect, it might be simpler to just say that hijrah-config-.properties is loaded as a resource file. Also the import of java.lang.String looks unnecessary. -Alan. From roger.riggs at oracle.com Mon Oct 20 15:11:48 2014 From: roger.riggs at oracle.com (roger riggs) Date: Mon, 20 Oct 2014 11:11:48 -0400 Subject: RFR 9: 8048124 Read hijrah-config-umalqura.properties as a resource In-Reply-To: <5445254C.7070408@oracle.com> References: <544521E5.5060300@oracle.com> <5445254C.7070408@oracle.com> Message-ID: <54452634.2020703@oracle.com> Hi Alan, Thanks for the review... On 10/20/2014 11:07 AM, Alan Bateman wrote: > On 20/10/2014 15:53, roger riggs wrote: >> Please review for JDK 9 only. >> >> To aid the modularization effort, the configuration of the Hijrah >> calendar >> should move the Hijrah calendar data to a resource. >> >> At this point, it does not look like there will be other Hijrah calendar >> variants; the function of calendar.properties to configure variants >> is unnecessary and is proposed to be removed. >> >> Since the other uses of calendars.properties have been eliminated >> the calendars.properties is removed. >> >> Webrev: >> http://cr.openjdk.java.net/~rriggs/webrev-hijrah-config-8049376/ >> Issue: >> https://bugs.openjdk.java.net/browse/JDK-8048124 > This mostly looks good to me. I just wonder about the removal of the > doPrivileged in readConfigProperties where you will get null if there > is something on the stack with restricted permissions. What permission would be needed to read the resource? The limited doPrivileged should include the minimum permission. > > A minor comment on the @implNote in HijrahChronology is that it has > more than I would expect, it might be simpler to just say that > hijrah-config-.properties is loaded as a resource file. > Also the import of java.lang.String looks unnecessary. ok, will correct. Roger > > -Alan. > > From Alan.Bateman at oracle.com Mon Oct 20 15:25:47 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 20 Oct 2014 16:25:47 +0100 Subject: RFR 9: 8048124 Read hijrah-config-umalqura.properties as a resource In-Reply-To: <54452634.2020703@oracle.com> References: <544521E5.5060300@oracle.com> <5445254C.7070408@oracle.com> <54452634.2020703@oracle.com> Message-ID: <5445297B.5020609@oracle.com> On 20/10/2014 16:11, roger riggs wrote: > What permission would be needed to read the resource? > The limited doPrivileged should include the minimum permission. The resources will be be resources.jar so I think read access to that should be sufficient. If you run a small test with -Djava.security.manager that triggers the config file to load then it would help verify that. When we move to the modular image then the resources will be elsewhere in the runtime image so if you really want to use limited doPrivileged here then access to ${java.home}/** should do it. Of course not using limited doPrivileged is a possibility too. -Alan From alexandre.bartel at cased.de Tue Oct 14 11:17:46 2014 From: alexandre.bartel at cased.de (Alexandre Bartel) Date: Tue, 14 Oct 2014 13:17:46 +0200 Subject: Precision for JDK-8060012 Class.isAnonymousClass() returns false when class major number is 48. Message-ID: <1413285466.14760.2.camel@cased.de> Hi, Regarding issue JDK-8060012 https://bugs.openjdk.java.net/browse/JDK-8060012 I have tried to run the code using the following IBM JVM: java version "1.7.0" Java(TM) SE Runtime Environment (build pxa6470_27-20131115_04) IBM J9 VM (build 2.7, JRE 1.7.0 Linux amd64-64 Compressed References 20131114_175264 (JIT enabled, AOT enabled) J9VM - R27_Java727_GA_20131114_0833_B175264 JIT - tr.r13.java_20131113_50523 GC - R27_Java727_GA_20131114_0833_B175264_CMPRSS J9CL - 20131114_175264) JCL - 20131113_01 based on Oracle 7u45-b18 And the result is always the expected result: isAnonymousClass() always returns true, as expected, even when the major version of the A$1 class is 48. This suggests that there is enough information in classes with version 48 to know if the class is anonymous and that OpenJDK is potentially not analyzing the class correctly. Thanks, /Alexandre From roger.riggs at oracle.com Mon Oct 20 18:17:20 2014 From: roger.riggs at oracle.com (roger riggs) Date: Mon, 20 Oct 2014 14:17:20 -0400 Subject: RFR 9: 8048124 Read hijrah-config-umalqura.properties as a resource In-Reply-To: <5445297B.5020609@oracle.com> References: <544521E5.5060300@oracle.com> <5445254C.7070408@oracle.com> <54452634.2020703@oracle.com> <5445297B.5020609@oracle.com> Message-ID: <544551B0.1020609@oracle.com> Hi, Updated with recommendations. Webrev: http://cr.openjdk.java.net/~rriggs/webrev-hijrah-config-8049376/ Issue: https://bugs.openjdk.java.net/browse/JDK-8048124 Thanks, Roger On 10/20/2014 11:25 AM, Alan Bateman wrote: > On 20/10/2014 16:11, roger riggs wrote: >> What permission would be needed to read the resource? >> The limited doPrivileged should include the minimum permission. > The resources will be be resources.jar so I think read access to that > should be sufficient. If you run a small test with > -Djava.security.manager that triggers the config file to load then it > would help verify that. When we move to the modular image then the > resources will be elsewhere in the runtime image so if you really want > to use limited doPrivileged here then access to ${java.home}/** should > do it. Of course not using limited doPrivileged is a possibility too. > > -Alan > From stanimir at riflexo.com Mon Oct 20 18:33:13 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Mon, 20 Oct 2014 21:33:13 +0300 Subject: RFR 9: 8048124 Read hijrah-config-umalqura.properties as a resource In-Reply-To: <544551B0.1020609@oracle.com> References: <544521E5.5060300@oracle.com> <5445254C.7070408@oracle.com> <54452634.2020703@oracle.com> <5445297B.5020609@oracle.com> <544551B0.1020609@oracle.com> Message-ID: Hi, A minor issue: there are quite a few instances of parsing integers via Integer.valueOf(String) instead just Integer.parseInt(String): HijrahChronology.java: 864 int year = Integer.valueOf(key); 972 months[i] = Integer.valueOf(numbers[i]); Those should be optimized not to create substrings either 994 ymd[0] = Integer.valueOf(string.substring(0, 4)); 995 ymd[1] = Integer.valueOf(string.substring(5, 7)); 996 ymd[2] = Integer.valueOf(string.substring(8, 10)); Stanimir On Mon, Oct 20, 2014 at 9:17 PM, roger riggs wrote: > Hi, > > Updated with recommendations. > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-hijrah-config-8049376/ > Issue: > https://bugs.openjdk.java.net/browse/JDK-8048124 > > Thanks, Roger > > > On 10/20/2014 11:25 AM, Alan Bateman wrote: > >> On 20/10/2014 16:11, roger riggs wrote: >> >>> What permission would be needed to read the resource? >>> The limited doPrivileged should include the minimum permission. >>> >> The resources will be be resources.jar so I think read access to that >> should be sufficient. If you run a small test with -Djava.security.manager >> that triggers the config file to load then it would help verify that. When >> we move to the modular image then the resources will be elsewhere in the >> runtime image so if you really want to use limited doPrivileged here then >> access to ${java.home}/** should do it. Of course not using limited >> doPrivileged is a possibility too. >> >> -Alan >> >> > From Alan.Bateman at oracle.com Mon Oct 20 18:53:30 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 20 Oct 2014 19:53:30 +0100 Subject: RFR 9: 8048124 Read hijrah-config-umalqura.properties as a resource In-Reply-To: <544551B0.1020609@oracle.com> References: <544521E5.5060300@oracle.com> <5445254C.7070408@oracle.com> <54452634.2020703@oracle.com> <5445297B.5020609@oracle.com> <544551B0.1020609@oracle.com> Message-ID: <54455A2A.90408@oracle.com> On 20/10/2014 19:17, roger riggs wrote: > Hi, > > Updated with recommendations. > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-hijrah-config-8049376/ > Issue: > https://bugs.openjdk.java.net/browse/JDK-8048124 > "<>" seems excessive when I think you only need ${java.home}/- but still better than all. A minor comment is that expression for the try-with-resources uses AccessController with parameters over 4 lines isn't easy to read. It might be a bit clearer with multiple statements, as in: PrivilegedAction action = () -> HijrahChronology .class.getResourceAsStream(resourceName); Permission permission = new FilePermission("<>", "read"); try (InputStream in = AccessController.doPrivileged(action, null, permission)) { : } From roger.riggs at oracle.com Mon Oct 20 19:11:20 2014 From: roger.riggs at oracle.com (roger riggs) Date: Mon, 20 Oct 2014 15:11:20 -0400 Subject: RFR 9: 8048124 Read hijrah-config-umalqura.properties as a resource In-Reply-To: <54455A2A.90408@oracle.com> References: <544521E5.5060300@oracle.com> <5445254C.7070408@oracle.com> <54452634.2020703@oracle.com> <5445297B.5020609@oracle.com> <544551B0.1020609@oracle.com> <54455A2A.90408@oracle.com> Message-ID: <54455E58.2050108@oracle.com> Hi, Updated with recommendations to make the code more readable and to use the more appropriate Integer.parseInt instead of valueOf. Webrev: http://cr.openjdk.java.net/~rriggs/webrev-hijrah-config-8049376/ Issue: https://bugs.openjdk.java.net/browse/JDK-8048124 Roger On 10/20/2014 2:53 PM, Alan Bateman wrote: > On 20/10/2014 19:17, roger riggs wrote: >> Hi, >> >> Updated with recommendations. >> >> Webrev: >> http://cr.openjdk.java.net/~rriggs/webrev-hijrah-config-8049376/ >> Issue: >> https://bugs.openjdk.java.net/browse/JDK-8048124 >> > "<>" seems excessive when I think you only need > ${java.home}/- but still better than all. yes, reading the java.home property required a doPriv and then a nested doPriv with the properly constructed FilePermission. The code was getting unwieldy. > > A minor comment is that expression for the try-with-resources uses > AccessController with parameters over 4 lines isn't easy to read. It > might be a bit clearer with multiple statements, as in: > > PrivilegedAction action = () -> HijrahChronology > .class.getResourceAsStream(resourceName); > Permission permission = new FilePermission("<>", "read"); > try (InputStream in = AccessController.doPrivileged(action, null, > permission)) { > : > } Yes, easier to read and parse. Thanks, Roger From Alan.Bateman at oracle.com Mon Oct 20 20:20:52 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 20 Oct 2014 21:20:52 +0100 Subject: RFR 9: 8048124 Read hijrah-config-umalqura.properties as a resource In-Reply-To: <54455E58.2050108@oracle.com> References: <544521E5.5060300@oracle.com> <5445254C.7070408@oracle.com> <54452634.2020703@oracle.com> <5445297B.5020609@oracle.com> <544551B0.1020609@oracle.com> <54455A2A.90408@oracle.com> <54455E58.2050108@oracle.com> Message-ID: <54456EA4.2000705@oracle.com> On 20/10/2014 20:11, roger riggs wrote: > Hi, > > Updated with recommendations to make the code more readable and > to use the more appropriate Integer.parseInt instead of valueOf. > > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-hijrah-config-8049376/ > Issue: > https://bugs.openjdk.java.net/browse/JDK-8048124 This looks okay now although I guess the other clean-ups are really something for a different issue. You want to want to check Integer.java in the webrev, I assumed that isn't meant to be there. -Alan. From ivan.gerasimov at oracle.com Mon Oct 20 20:25:20 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 21 Oct 2014 00:25:20 +0400 Subject: RFR 8023173: FileOutputStream(FileDescriptor) does not respect append flag on Windows In-Reply-To: <54450C14.1000308@oracle.com> References: <543271F1.8040505@oracle.com> <5440DA9F.9090304@oracle.com> <54450142.4040207@oracle.com> <54450C14.1000308@oracle.com> Message-ID: <54456FB0.2010702@oracle.com> Thank you Roger! Yes, you're right. Please find the updated webrev here: http://cr.openjdk.java.net/~igerasim/8023173/2/webrev/ Sincerely yours, Ivan On 20.10.2014 17:20, roger riggs wrote: > Hi Ivan, > > This webrev appears removes the ability to interpose on various method > using byte-code injection. For example, FileOutputStream.write(byte). > Do *not *replace delete the Java method calls that call native. > It looks like an optimization but disables some functions that allow > monitoring > of I/O activities such as JFR. > > Thanks, Roger > > > On 10/20/2014 8:34 AM, Ivan Gerasimov wrote: >> Thank you Alan for the review! >> >> On 17.10.2014 13:00, Alan Bateman wrote: >>> On 06/10/2014 11:41, Ivan Gerasimov wrote: >>>> Hello everybody! >>>> >>>> The append mode is emulated on Windows, therefore we have to keep a >>>> flag indicating that. >>>> >>>> With the current implementation, the FileDescriptor does not know >>>> if the file were opened with O_APPEND, and the flag is maintained >>>> at the upper level. >>>> This can cause inconsistency, when the FileDescriptor is reused to >>>> construct a new FileOutputStream, as there is no information >>>> available about the append/non-append mode. >>>> >>>> Even though the solution is quite straight-forward: moving the flag >>>> from FileOutputStream, FileDispatcherImpl and FileChannelImpl to >>>> the lower level of FileDescriptor, it touches 20 files across the >>>> source-code base. >>>> >>>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8023173 >>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8023173/0/webrev/ >>>> >>>> With the fix, all the io/nio tests, including the new one, pass on >>>> all available platforms. >>>> >>>> Would you please help review this fix? >>> Martin prodded me a few times but I was busy with other things and >>> only getting to this now. >>> >>> At a high level then moving the append down to FileDescriptor make >>> sense but I have a few concerns. >>> >>> On Unix systems then it looks like getAppend is calling into the >>> ioctl to get the file descriptor flags. >>> If I read it correctly then it creates several problems for the >>> usage in FileChannelImpl.position. >> >> I thought it might look like a data duplication, if we store the >> append flag both in FileChannelImpl and FileDescriptor. >> Though, we surely can retrieve the append flag only once and cache it. >> >> I updated the webrev with this change. >> >>> I just wondering if you consider just leaving the append flag there >>> and just retrieve the value once in the open method. >>> >> >>> I'm also wondering about the handleWrite implementation on Windows >>> which changes to use additional JNI to retrieve the value of the >>> append flag each time. We should try to avoid this (we want the >>> native methods to be as simple as possible so that we can replace >>> them in the future) so there may be an argument for passing that >>> down as per the current implementation. >>> >> >> We would still need to retrieve the flag from native code. >> For example, the platform specific handleWrite() is called from the >> native FileOutputStream.writeBytes(), which is called from >> FileOutputStream.writt(), which is common for all the platforms. >> Thus, we should either retrieve the append flag from the Java code >> for any platform, and ignore it later on Unix, or read the flag in >> the native Windows-only code. >> >> Alternatively, we could separate implementations of >> FileOutputStream.java for different platforms, but that would >> complicate everything. >> >> Hopefully, in the future we could find a way to use FILE_APPEND_DATA, >> so FileDescriptor.append can be removed altogether with that >> corresponding JNI code. >> >> Here's the updated webrev: >> http://cr.openjdk.java.net/~igerasim/8023173/1/webrev/ >> >> I've also included a few typo fixes left after JDK-8059840. >> >> Sincerely yours, >> Ivan >> > > > From roger.riggs at oracle.com Mon Oct 20 20:33:00 2014 From: roger.riggs at oracle.com (roger riggs) Date: Mon, 20 Oct 2014 16:33:00 -0400 Subject: RFR 8023173: FileOutputStream(FileDescriptor) does not respect append flag on Windows In-Reply-To: <54456FB0.2010702@oracle.com> References: <543271F1.8040505@oracle.com> <5440DA9F.9090304@oracle.com> <54450142.4040207@oracle.com> <54450C14.1000308@oracle.com> <54456FB0.2010702@oracle.com> Message-ID: <5445717C.80908@oracle.com> Looks fine. Thanks, Roger On 10/20/2014 4:25 PM, Ivan Gerasimov wrote: > Thank you Roger! > > Yes, you're right. > Please find the updated webrev here: > http://cr.openjdk.java.net/~igerasim/8023173/2/webrev/ > > Sincerely yours, > Ivan > > > On 20.10.2014 17:20, roger riggs wrote: >> Hi Ivan, >> >> This webrev appears removes the ability to interpose on various method >> using byte-code injection. For example, FileOutputStream.write(byte). >> Do *not *replace delete the Java method calls that call native. >> It looks like an optimization but disables some functions that allow >> monitoring >> of I/O activities such as JFR. >> >> Thanks, Roger >> >> >> On 10/20/2014 8:34 AM, Ivan Gerasimov wrote: >>> Thank you Alan for the review! >>> >>> On 17.10.2014 13:00, Alan Bateman wrote: >>>> On 06/10/2014 11:41, Ivan Gerasimov wrote: >>>>> Hello everybody! >>>>> >>>>> The append mode is emulated on Windows, therefore we have to keep >>>>> a flag indicating that. >>>>> >>>>> With the current implementation, the FileDescriptor does not know >>>>> if the file were opened with O_APPEND, and the flag is maintained >>>>> at the upper level. >>>>> This can cause inconsistency, when the FileDescriptor is reused to >>>>> construct a new FileOutputStream, as there is no information >>>>> available about the append/non-append mode. >>>>> >>>>> Even though the solution is quite straight-forward: moving the >>>>> flag from FileOutputStream, FileDispatcherImpl and >>>>> FileChannelImpl to the lower level of FileDescriptor, it touches >>>>> 20 files across the source-code base. >>>>> >>>>> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8023173 >>>>> WEBREV: http://cr.openjdk.java.net/~igerasim/8023173/0/webrev/ >>>>> >>>>> With the fix, all the io/nio tests, including the new one, pass on >>>>> all available platforms. >>>>> >>>>> Would you please help review this fix? >>>> Martin prodded me a few times but I was busy with other things and >>>> only getting to this now. >>>> >>>> At a high level then moving the append down to FileDescriptor make >>>> sense but I have a few concerns. >>>> >>>> On Unix systems then it looks like getAppend is calling into the >>>> ioctl to get the file descriptor flags. >>>> If I read it correctly then it creates several problems for the >>>> usage in FileChannelImpl.position. >>> >>> I thought it might look like a data duplication, if we store the >>> append flag both in FileChannelImpl and FileDescriptor. >>> Though, we surely can retrieve the append flag only once and cache it. >>> >>> I updated the webrev with this change. >>> >>>> I just wondering if you consider just leaving the append flag there >>>> and just retrieve the value once in the open method. >>>> >>> >>>> I'm also wondering about the handleWrite implementation on Windows >>>> which changes to use additional JNI to retrieve the value of the >>>> append flag each time. We should try to avoid this (we want the >>>> native methods to be as simple as possible so that we can replace >>>> them in the future) so there may be an argument for passing that >>>> down as per the current implementation. >>>> >>> >>> We would still need to retrieve the flag from native code. >>> For example, the platform specific handleWrite() is called from the >>> native FileOutputStream.writeBytes(), which is called from >>> FileOutputStream.writt(), which is common for all the platforms. >>> Thus, we should either retrieve the append flag from the Java code >>> for any platform, and ignore it later on Unix, or read the flag in >>> the native Windows-only code. >>> >>> Alternatively, we could separate implementations of >>> FileOutputStream.java for different platforms, but that would >>> complicate everything. >>> >>> Hopefully, in the future we could find a way to use >>> FILE_APPEND_DATA, so FileDescriptor.append can be removed altogether >>> with that corresponding JNI code. >>> >>> Here's the updated webrev: >>> http://cr.openjdk.java.net/~igerasim/8023173/1/webrev/ >>> >>> I've also included a few typo fixes left after JDK-8059840. >>> >>> Sincerely yours, >>> Ivan >>> >> >> >> > From staffan.friberg at oracle.com Mon Oct 20 20:59:31 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Mon, 20 Oct 2014 13:59:31 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <4E1FA81E-7D08-4BD1-A3AF-25950596F5D1@oracle.com> References: <544073EA.3060304@oracle.com> <5440D758.50703@gmail.com> <54414819.90803@oracle.com> <54415AA7.2030506@oracle.com> <544165B6.1020306@oracle.com> <418E202F-2192-4B2A-828A-05BAF6305C8C@oracle.com> <5C922BF9-16DA-43E9-B090-86B1C9A5DF79@oracle.com> <5441888E.8040402@oracle.com> <4E1FA81E-7D08-4BD1-A3AF-25950596F5D1@oracle.com> Message-ID: <544577B3.7010809@oracle.com> Hi David, >> The intrinsic that can be implemented for CRC32C will probably be even faster as it can make use of the specific crc32c instruction instead of using carry less multiplication. > It might not hurt to mock up a quick benchmark using the CRC32C > instruction against jdk8?s java.util.zip.CRC32 intrinsic. CRC32 > seems to consume 64 bits per instruction, and I think each instruction > depends on its predecessor (naively coded, at least; there?s probably > a hack to run them in parallel, just as there is a hack that allows fork/join. > So maybe we should think about that hack, too; simply computing the > two half-CRCs in parallel, then combining them as if fork/join, might > break the data dependence and allow higher speed). > > The carryless multiply inner loop also consumes 64 bits per carryless > multiply, but the instructions are not data dependent among themselves, > so it might go faster. Haswell chips execute clmul especially quickly. > > The assembly language I wrote to make that go fast is agnostic about P; > it is parameterized by a structure that contains a small number of constants > that make it all go (6 64-bit numbers) based on powers of x (regarded as a > polynomial) modulo the CRC polynomial P. If the endianness conventions > match, and if zip CRC runs faster than the CRC32 instruction, I could > revive it, and modern tools might let us avoid coding in hex. Yes, when an intrinsic is added it will definitely need to be compared the the current crc32. The calculation speed of the two should at least be the same, and hopefully we will be able to get crc32c even faster. Here is a paper describing a algorithm that uses the Intel crc32 instruction, http://dl.acm.org/citation.cfm?id=2108885, and utilizes the fact that it is a 3 cycle instruction to execute 3 independent crc32 instructions. (Presume it is using a similar algorithm to merge the results as you do in your fork/join implementation.) >> I have also been thinking that using fork-join to help for large arrays. I decided to not go after it for this first implementation of the new API. The other question is if that should be something that is more explicit, similar to parallel streams, as not everyone might want/expect that the API to suddenly start using multiple threads to calculate the result. > That?s why we have a system fork/join pool; if you don?t want lots of concurrency, > limit the number of threads in that pool. Soon enough people are going to > yell at us for not using concurrency when it is available, and forcing them to > use a different API just to get concurrency will hinder the ability to write portable > code. We definiately should try to do a parallel version that can further speed up Checksum's on very large arrays/buffers, but we probably need to discuss further and get input on how it should be enabled. Do we need to add an optional parallel method or do we simply make the current method parallel? I believe that is what needs to be discussed and decided on a more general level, as we might want to parallelize other APIs as well when possible and preferably should follow the same principle across the whole Java standard library. //Staffan From otaviojava at java.net Mon Oct 20 23:02:48 2014 From: otaviojava at java.net (=?UTF-8?Q?Ot=C3=A1vio_Gon=C3=A7alves_de_Santana?=) Date: Mon, 20 Oct 2014 21:02:48 -0200 Subject: Review request: JDK-8055723 Replace concat String to append in StringBuilder parameters Message-ID: BUGURL: https://bugs.openjdk.java.net/browse/JDK-8055723 WEBREV: http://cr.openjdk.java.net/~weijun/8055723/client/webrev.02/ WEBREV: http://cr.openjdk.java.net/~weijun/8055723/core/webrev.03/ -- Ot?vio Gon?alves de Santana blog: http://otaviosantana.blogspot.com.br/ twitter: http://twitter.com/otaviojava 55 (11) 98255-3513 From Ulf.Zibis at CoSoCo.de Tue Oct 21 00:26:30 2014 From: Ulf.Zibis at CoSoCo.de (Ulf Zibis) Date: Tue, 21 Oct 2014 02:26:30 +0200 Subject: Review request: JDK-8055723 Replace concat String to append in StringBuilder parameters In-Reply-To: References: Message-ID: <5445A836.8090005@CoSoCo.de> Am 21.10.2014 um 01:02 schrieb Ot?vio Gon?alves de Santana: > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8055723 > > > WEBREV: http://cr.openjdk.java.net/~weijun/8055723/client/webrev.02/ > WEBREV: http://cr.openjdk.java.net/~weijun/8055723/core/webrev.03/ I did not look through all sources. In Scanner.java I discovered: 1307 sb.append("[delimiters=").append(delimPattern).append(']'); 1308 sb.append("[position=").append(position).append(']'); ... Maybe better: 1307 sb.append("[delimiters=").append(delimPattern); 1308 sb.append("][position=").append(position); ... -Ulf From sunxiaoguang at gmail.com Tue Oct 21 01:31:34 2014 From: sunxiaoguang at gmail.com (Xiaoguang Sun) Date: Tue, 21 Oct 2014 09:31:34 +0800 Subject: [PATCH] Return -1 after throwing internal error Message-ID: Hi All, I recently discovered some inconsistency in UnixOperatingSystem_md.c that do now return -1 after throwing internal error. It usually shouldn't be a problem, but making it more consistent to other code within the same file shouldn't be a bad idea. Xiaoguang -------------- next part -------------- A non-text attachment was scrubbed... Name: Return -1 after throwing internal error.patch Type: text/x-patch Size: 1471 bytes Desc: not available URL: From mandy.chung at oracle.com Tue Oct 21 02:21:17 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Mon, 20 Oct 2014 19:21:17 -0700 Subject: [PATCH] Return -1 after throwing internal error In-Reply-To: References: Message-ID: <5445C31D.7030106@oracle.com> Hi Xiaoguang, On 10/20/2014 6:31 PM, Xiaoguang Sun wrote: > Hi All, > > I recently discovered some inconsistency in UnixOperatingSystem_md.c > that do now return -1 after throwing internal error. It usually > shouldn't be a problem, but making it more consistent to other code > within the same file shouldn't be a bad idea. I'm including serviceability-dev for your patch as UnixOperatingSystem_md.c belongs to serviceability. Are you working on a clone of jdk9/dev repo? src/solaris/native/com/sun/management/UnixOperatingSystem_md.c looks like jdk7 source. It has been renamed to src/java.management/unix/native/libmanagement/OperatingSystemImpl.c [1]. Can you rebase your patch to the latest jdk9 source and send it to serviceability-dev? Mandy [1] http://hg.openjdk.java.net/jdk9/dev/jdk/ From joe.darcy at oracle.com Tue Oct 21 04:07:39 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Mon, 20 Oct 2014 21:07:39 -0700 Subject: Precision for JDK-8060012 Class.isAnonymousClass() returns false when class major number is 48. In-Reply-To: <1413285466.14760.2.camel@cased.de> References: <1413285466.14760.2.camel@cased.de> Message-ID: <5445DC0B.3060506@oracle.com> Hello, I don't know if IBM's implementation uses any VM hooks not found in OpenJDK. If their JDK only uses common reflection machinery, a patch for this functionality for OpenJDK would be welcome for evaluation. Cheers, -Joe On 10/14/2014 4:17 AM, Alexandre Bartel wrote: > Hi, > > Regarding issue JDK-8060012 > https://bugs.openjdk.java.net/browse/JDK-8060012 > > I have tried to run the code using the following IBM JVM: > > java version "1.7.0" > Java(TM) SE Runtime Environment (build pxa6470_27-20131115_04) > IBM J9 VM (build 2.7, JRE 1.7.0 Linux amd64-64 Compressed References > 20131114_175264 (JIT enabled, AOT enabled) > J9VM - R27_Java727_GA_20131114_0833_B175264 > JIT - tr.r13.java_20131113_50523 > GC - R27_Java727_GA_20131114_0833_B175264_CMPRSS > J9CL - 20131114_175264) > JCL - 20131113_01 based on Oracle 7u45-b18 > > And the result is always the expected result: > > isAnonymousClass() always returns true, as expected, even when the > major version of the A$1 class is 48. This suggests that there is > enough information in classes with version 48 to know if the class is > anonymous and that OpenJDK is potentially not analyzing the class > correctly. > > Thanks, > /Alexandre > > > From ivan.gerasimov at oracle.com Tue Oct 21 06:36:44 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 21 Oct 2014 10:36:44 +0400 Subject: [7u-dev ONLY] RFR: [8057530] (process) Runtime.exec throws garbled message in jp locale Message-ID: <5445FEFC.9040406@oracle.com> Hello everybody! This is a request for review of a fix which is applicable to 7u only. The issue has already been addressed in 8 and later releases. The fix is a combined backport of https://bugs.openjdk.java.net/browse/JDK-8016579 , which addresses the problem with the encoding in windows console and partial backport of https://bugs.openjdk.java.net/browse/JDK-8001334 , which reorganizes the code at the files of our interest. BUGURL: https://bugs.openjdk.java.net/browse/JDK-8057530 WEBREV: http://cr.openjdk.java.net/~igerasim/8057530/0/webrev/ The fix has been verified on the localized versions of Windows (jp, rus). Thanks in advance, Ivan From peter.levart at gmail.com Tue Oct 21 10:37:20 2014 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 21 Oct 2014 12:37:20 +0200 Subject: RFR: 8061244 Use of stack-less ClassNotFoundException thrown from (URL)ClassLoader.findClass() In-Reply-To: <543FD0A6.3080207@gmail.com> References: <543EF592.3030409@gmail.com> <543F754B.4020001@gmail.com> <543F8558.2030401@gmail.com> <543FD0A6.3080207@gmail.com> Message-ID: <54463760.6090809@gmail.com> Hi, I guess we are not happy with stack-traces that only reveal call stack up to the public ClassLoader.loadClass() method and hide everything happening after that even if paired with a more descriptive message. So I improved the strategy of throwing stack-less exception. New strategy throws full-stack exception from findClass() if findClass() is invoked on the "initiating" class loader and stack-less exception otherwise. How can we know if a particular ClassLoader instance is the initiating class loader for a particular class loading request? VM knows that when invoking Class.forName() or when VM triggers class loading, because such calls are wired through VM or initiate from VM. On the Java side, we can establish a similar thread-local context at the entry point of Class.loadClass() public method. This strategy gives normal stack traces for exceptions that escape the ClassLoader.loadClass() public method and avoids creating stack-full exceptions that are later swallowed. That's not all. I have another optimization at hand. Parallel capable class loaders maintain a ConcurrentHashMap of Objects used as locks to synchronize on when executing class loading request for a particular class name. These seem like a waste of resource and can be used for more than just locks. My 1st attempt at (ab)using these objects is the following: http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.03/ Here a boolean flag is added to such Lock object that indicates whether a class loading attempt has already been performed for a particular class name. The 1st attempt at loading a particular class can therefore skip calling findLoadedClass() native method. This has a measurable performance impact as indicated in the following benchmark: http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/CLBench2.java This is a variant of previous benchmark - only the part that measures successful attempts at loading a class with a child of extension class loader, but does that at different call-stack depths (10, 20, 40, 80, 160 frames). Original JDK 9 code gives these results: Benchmark Mode Samples Score Error Units j.t.CLBench2.loadNewClassSuccessSS010 ss 5 3.947 ? 0.080 s j.t.CLBench2.loadNewClassSuccessSS020 ss 5 4.001 ? 0.119 s j.t.CLBench2.loadNewClassSuccessSS040 ss 5 4.068 ? 0.115 s j.t.CLBench2.loadNewClassSuccessSS080 ss 5 4.323 ? 0.061 s j.t.CLBench2.loadNewClassSuccessSS160 ss 5 4.633 ? 0.118 s Doing stack-less CNF exceptions shows that call-stack depth does not have an impact any more: Benchmark Mode Samples Score Error Units j.t.CLBench2.loadNewClassSuccessSS010 ss 5 3.753 ? 0.155 s j.t.CLBench2.loadNewClassSuccessSS020 ss 5 3.755 ? 0.160 s j.t.CLBench2.loadNewClassSuccessSS040 ss 5 3.767 ? 0.124 s j.t.CLBench2.loadNewClassSuccessSS080 ss 5 3.762 ? 0.148 s j.t.CLBench2.loadNewClassSuccessSS160 ss 5 3.781 ? 0.146 s Adding findLoadedClass() avoidance on top of that gives even better results: Benchmark Mode Samples Score Error Units j.t.CLBench2.loadNewClassSuccessSS010 ss 5 3.539 ? 0.185 s j.t.CLBench2.loadNewClassSuccessSS020 ss 5 3.548 ? 0.165 s j.t.CLBench2.loadNewClassSuccessSS040 ss 5 3.586 ? 0.226 s j.t.CLBench2.loadNewClassSuccessSS080 ss 5 3.541 ? 0.053 s j.t.CLBench2.loadNewClassSuccessSS160 ss 5 3.570 ? 0.113 s Regards, Peter On 10/16/2014 04:05 PM, Peter Levart wrote: > I created an issue in Jira to track this investigation: > > https://bugs.openjdk.java.net/browse/JDK-8061244 > > The latest webrev of proposed patch is still: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.02/ > > I invite the public to review it. > > Thanks. > > Peter > > On 10/16/2014 10:44 AM, Peter Levart wrote: >> Hi, >> >> As for usage of SharedSecrets, they are not needed to access CNFE >> package-private constructor from java.lang.ClassLoader, since they >> are in the same package, and from java.net.URLClassLoader, the call >> to super.findClass(name) does the job. So here's an updated webrev >> that also includes more descriptive message: >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.02/ >> >> >> Regards, Peter >> >> On 10/16/2014 09:35 AM, Peter Levart wrote: >>> On 10/16/2014 01:49 AM, Stanimir Simeonoff wrote: >>>> First, really nice tests. >>>> >>>> As for hiding: missing the real classloader impl. might be quite a >>>> bumper >>>> for some middleware implementations. That would make pretty hard to >>>> trace >>>> dependency issues without explicit logging, the latter is usually >>>> available >>>> but still. Also it'd depend if the classloaders actually use >>>> super.findClass() or not. >>>> IMO, the option should be switchable via some system property. >>> >>> With a little tweak, the message of the stack-less exception thrown >>> from findClass() methods can be extended to include the >>> classloader's runtime class name and this message can be inherited >>> by a replacement stack-full exception. So the stack-trace would look >>> like: >>> >>> Exception in thread "main" java.lang.ClassNotFoundException: XXX >>> (thrown by: sun.misc.Launcher$AppClassLoader) >>> at java.lang.ClassLoader.loadClass(ClassLoader.java:366) >>> at java.lang.Class.forName0(Native Method) >>> at java.lang.Class.forName(Class.java:265) >>> at Test.doIt(Test.java:7) >>> at Test.main(Test.java:11) >>> >>> Instead of what we have now: >>> >>> Exception in thread "main" java.lang.ClassNotFoundException: XXX >>> at java.net.URLClassLoader.findClass(URLClassLoader.java:381) >>> at java.lang.ClassLoader.loadClass(ClassLoader.java:426) >>> at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:317) >>> at java.lang.ClassLoader.loadClass(ClassLoader.java:359) >>> at java.lang.Class.forName0(Native Method) >>> at java.lang.Class.forName(Class.java:265) >>> at Test.doIt(Test.java:7) >>> at Test.main(Test.java:11) >>> >>> >>> Would this be enough to cover your concern? >>> >>> Regards, Peter >>> >>>> >>>> I am not sure about the need to hide the stackless c-tor as the >>>> effect can >>>> be achieved by overriding fillInStackTrace(); w/o the extra baggage of >>>> JavaLangAccess. >>>> >>>> Overall very decent improvement. >>>> >>>> Cheers >>>> Stanimir >>>> >>>> >> > From stanimir at riflexo.com Tue Oct 21 11:03:56 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Tue, 21 Oct 2014 14:03:56 +0300 Subject: RFR: 8061244 Use of stack-less ClassNotFoundException thrown from (URL)ClassLoader.findClass() In-Reply-To: <54463760.6090809@gmail.com> References: <543EF592.3030409@gmail.com> <543F754B.4020001@gmail.com> <543F8558.2030401@gmail.com> <543FD0A6.3080207@gmail.com> <54463760.6090809@gmail.com> Message-ID: I like the changes, esp the black listing which is long overdue in JDK (middleware containers have been doing that for over a decade). Not sure if there is any specification governing if two consecutive attempts to load the same class name may respectively fail and succeed - if the black listing passes, I believe that should go to classloading spec. Adding the initiating classloader in the Thread doesn't pose security risks the way it's implemented, so it's fine imo. Stanimir On Tue, Oct 21, 2014 at 1:37 PM, Peter Levart wrote: > Hi, > > I guess we are not happy with stack-traces that only reveal call stack up > to the public ClassLoader.loadClass() method and hide everything happening > after that even if paired with a more descriptive message. So I improved > the strategy of throwing stack-less exception. New strategy throws > full-stack exception from findClass() if findClass() is invoked on the > "initiating" class loader and stack-less exception otherwise. How can we > know if a particular ClassLoader instance is the initiating class loader > for a particular class loading request? VM knows that when invoking > Class.forName() or when VM triggers class loading, because such calls are > wired through VM or initiate from VM. On the Java side, we can establish a > similar thread-local context at the entry point of Class.loadClass() public > method. > > This strategy gives normal stack traces for exceptions that escape the > ClassLoader.loadClass() public method and avoids creating stack-full > exceptions that are later swallowed. > > That's not all. I have another optimization at hand. Parallel capable > class loaders maintain a ConcurrentHashMap of Objects used as locks to > synchronize on when executing class loading request for a particular class > name. These seem like a waste of resource and can be used for more than > just locks. My 1st attempt at (ab)using these objects is the following: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.03/ > > Here a boolean flag is added to such Lock object that indicates whether a > class loading attempt has already been performed for a particular class > name. The 1st attempt at loading a particular class can therefore skip > calling findLoadedClass() native method. This has a measurable performance > impact as indicated in the following benchmark: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader. > CNFE/CLBench2.java > > This is a variant of previous benchmark - only the part that measures > successful attempts at loading a class with a child of extension class > loader, but does that at different call-stack depths (10, 20, 40, 80, 160 > frames). Original JDK 9 code gives these results: > > Benchmark Mode Samples Score Error > Units > j.t.CLBench2.loadNewClassSuccessSS010 ss 5 3.947 ? > 0.080 s > j.t.CLBench2.loadNewClassSuccessSS020 ss 5 4.001 ? > 0.119 s > j.t.CLBench2.loadNewClassSuccessSS040 ss 5 4.068 ? > 0.115 s > j.t.CLBench2.loadNewClassSuccessSS080 ss 5 4.323 ? > 0.061 s > j.t.CLBench2.loadNewClassSuccessSS160 ss 5 4.633 ? > 0.118 s > > > Doing stack-less CNF exceptions shows that call-stack depth does not have > an impact any more: > > Benchmark Mode Samples Score Error > Units > j.t.CLBench2.loadNewClassSuccessSS010 ss 5 3.753 ? > 0.155 s > j.t.CLBench2.loadNewClassSuccessSS020 ss 5 3.755 ? > 0.160 s > j.t.CLBench2.loadNewClassSuccessSS040 ss 5 3.767 ? > 0.124 s > j.t.CLBench2.loadNewClassSuccessSS080 ss 5 3.762 ? > 0.148 s > j.t.CLBench2.loadNewClassSuccessSS160 ss 5 3.781 ? > 0.146 s > > > Adding findLoadedClass() avoidance on top of that gives even better > results: > > Benchmark Mode Samples Score Error > Units > j.t.CLBench2.loadNewClassSuccessSS010 ss 5 3.539 ? > 0.185 s > j.t.CLBench2.loadNewClassSuccessSS020 ss 5 3.548 ? > 0.165 s > j.t.CLBench2.loadNewClassSuccessSS040 ss 5 3.586 ? > 0.226 s > j.t.CLBench2.loadNewClassSuccessSS080 ss 5 3.541 ? > 0.053 s > j.t.CLBench2.loadNewClassSuccessSS160 ss 5 3.570 ? > 0.113 s > > > > > Regards, Peter > > > On 10/16/2014 04:05 PM, Peter Levart wrote: > >> I created an issue in Jira to track this investigation: >> >> https://bugs.openjdk.java.net/browse/JDK-8061244 >> >> The latest webrev of proposed patch is still: >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.02/ >> >> I invite the public to review it. >> >> Thanks. >> >> Peter >> >> On 10/16/2014 10:44 AM, Peter Levart wrote: >> >>> Hi, >>> >>> As for usage of SharedSecrets, they are not needed to access CNFE >>> package-private constructor from java.lang.ClassLoader, since they are in >>> the same package, and from java.net.URLClassLoader, the call to >>> super.findClass(name) does the job. So here's an updated webrev that also >>> includes more descriptive message: >>> >>> http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.02/ >>> >>> >>> Regards, Peter >>> >>> On 10/16/2014 09:35 AM, Peter Levart wrote: >>> >>>> On 10/16/2014 01:49 AM, Stanimir Simeonoff wrote: >>>> >>>>> First, really nice tests. >>>>> >>>>> As for hiding: missing the real classloader impl. might be quite a >>>>> bumper >>>>> for some middleware implementations. That would make pretty hard to >>>>> trace >>>>> dependency issues without explicit logging, the latter is usually >>>>> available >>>>> but still. Also it'd depend if the classloaders actually use >>>>> super.findClass() or not. >>>>> IMO, the option should be switchable via some system property. >>>>> >>>> >>>> With a little tweak, the message of the stack-less exception thrown >>>> from findClass() methods can be extended to include the classloader's >>>> runtime class name and this message can be inherited by a replacement >>>> stack-full exception. So the stack-trace would look like: >>>> >>>> Exception in thread "main" java.lang.ClassNotFoundException: XXX >>>> (thrown by: sun.misc.Launcher$AppClassLoader) >>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:366) >>>> at java.lang.Class.forName0(Native Method) >>>> at java.lang.Class.forName(Class.java:265) >>>> at Test.doIt(Test.java:7) >>>> at Test.main(Test.java:11) >>>> >>>> Instead of what we have now: >>>> >>>> Exception in thread "main" java.lang.ClassNotFoundException: XXX >>>> at java.net.URLClassLoader.findClass(URLClassLoader.java:381) >>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:426) >>>> at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:317) >>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:359) >>>> at java.lang.Class.forName0(Native Method) >>>> at java.lang.Class.forName(Class.java:265) >>>> at Test.doIt(Test.java:7) >>>> at Test.main(Test.java:11) >>>> >>>> >>>> Would this be enough to cover your concern? >>>> >>>> Regards, Peter >>>> >>>> >>>>> I am not sure about the need to hide the stackless c-tor as the effect >>>>> can >>>>> be achieved by overriding fillInStackTrace(); w/o the extra baggage of >>>>> JavaLangAccess. >>>>> >>>>> Overall very decent improvement. >>>>> >>>>> Cheers >>>>> Stanimir >>>>> >>>>> >>>>> >>> >> > From peter.levart at gmail.com Tue Oct 21 13:19:07 2014 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 21 Oct 2014 15:19:07 +0200 Subject: RFR: 8061244 Use of stack-less ClassNotFoundException thrown from (URL)ClassLoader.findClass() In-Reply-To: References: <543EF592.3030409@gmail.com> <543F754B.4020001@gmail.com> <543F8558.2030401@gmail.com> <543FD0A6.3080207@gmail.com> <54463760.6090809@gmail.com> Message-ID: <54465D4B.6080804@gmail.com> On 10/21/2014 01:03 PM, Stanimir Simeonoff wrote: > I like the changes, esp the black listing which is long overdue in JDK > (middleware containers have been doing that for over a decade). > > Not sure if there is any specification governing if two consecutive > attempts to load the same class name may respectively fail and succeed - if > the black listing passes, I believe that should go to classloading spec. I don't think this is black listing what I do here. My only assumptions are the following: - if loadClass(name, resolve) has not been called for a particular name before, then findLoadedClass(name) returns null - if all calls to (parent.loadClass(name, resolve) / findBootstrapClassOrNull()) and findClass(name) for particular name have thrown ClassNotFoundException or returned null, then findLoadedClass(name) returns null That does not preclude the possibility of "transiently" failing and then suddenly succeeding in loading a particular class. It only avoids calling findLoadedClass(name) in situations when it would always return null - and that are all 1st attempts at successful loading of a particular class - the majority of requests. > > Adding the initiating classloader in the Thread doesn't pose security risks > the way it's implemented, so it's fine imo. As long as it's used only for optimization, I guess not. But if Thread.initiatingClassLoader could be trusted, then we could have a reference to the Class object in each Lock object and entirely eliminate the need for calling findLoadedClass() in parallel capable class-loaders. Regards, Peter > > Stanimir > > On Tue, Oct 21, 2014 at 1:37 PM, Peter Levart > wrote: > >> Hi, >> >> I guess we are not happy with stack-traces that only reveal call stack up >> to the public ClassLoader.loadClass() method and hide everything happening >> after that even if paired with a more descriptive message. So I improved >> the strategy of throwing stack-less exception. New strategy throws >> full-stack exception from findClass() if findClass() is invoked on the >> "initiating" class loader and stack-less exception otherwise. How can we >> know if a particular ClassLoader instance is the initiating class loader >> for a particular class loading request? VM knows that when invoking >> Class.forName() or when VM triggers class loading, because such calls are >> wired through VM or initiate from VM. On the Java side, we can establish a >> similar thread-local context at the entry point of Class.loadClass() public >> method. >> >> This strategy gives normal stack traces for exceptions that escape the >> ClassLoader.loadClass() public method and avoids creating stack-full >> exceptions that are later swallowed. >> >> That's not all. I have another optimization at hand. Parallel capable >> class loaders maintain a ConcurrentHashMap of Objects used as locks to >> synchronize on when executing class loading request for a particular class >> name. These seem like a waste of resource and can be used for more than >> just locks. My 1st attempt at (ab)using these objects is the following: >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.03/ >> >> Here a boolean flag is added to such Lock object that indicates whether a >> class loading attempt has already been performed for a particular class >> name. The 1st attempt at loading a particular class can therefore skip >> calling findLoadedClass() native method. This has a measurable performance >> impact as indicated in the following benchmark: >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader. >> CNFE/CLBench2.java >> >> This is a variant of previous benchmark - only the part that measures >> successful attempts at loading a class with a child of extension class >> loader, but does that at different call-stack depths (10, 20, 40, 80, 160 >> frames). Original JDK 9 code gives these results: >> >> Benchmark Mode Samples Score Error >> Units >> j.t.CLBench2.loadNewClassSuccessSS010 ss 5 3.947 ? >> 0.080 s >> j.t.CLBench2.loadNewClassSuccessSS020 ss 5 4.001 ? >> 0.119 s >> j.t.CLBench2.loadNewClassSuccessSS040 ss 5 4.068 ? >> 0.115 s >> j.t.CLBench2.loadNewClassSuccessSS080 ss 5 4.323 ? >> 0.061 s >> j.t.CLBench2.loadNewClassSuccessSS160 ss 5 4.633 ? >> 0.118 s >> >> >> Doing stack-less CNF exceptions shows that call-stack depth does not have >> an impact any more: >> >> Benchmark Mode Samples Score Error >> Units >> j.t.CLBench2.loadNewClassSuccessSS010 ss 5 3.753 ? >> 0.155 s >> j.t.CLBench2.loadNewClassSuccessSS020 ss 5 3.755 ? >> 0.160 s >> j.t.CLBench2.loadNewClassSuccessSS040 ss 5 3.767 ? >> 0.124 s >> j.t.CLBench2.loadNewClassSuccessSS080 ss 5 3.762 ? >> 0.148 s >> j.t.CLBench2.loadNewClassSuccessSS160 ss 5 3.781 ? >> 0.146 s >> >> >> Adding findLoadedClass() avoidance on top of that gives even better >> results: >> >> Benchmark Mode Samples Score Error >> Units >> j.t.CLBench2.loadNewClassSuccessSS010 ss 5 3.539 ? >> 0.185 s >> j.t.CLBench2.loadNewClassSuccessSS020 ss 5 3.548 ? >> 0.165 s >> j.t.CLBench2.loadNewClassSuccessSS040 ss 5 3.586 ? >> 0.226 s >> j.t.CLBench2.loadNewClassSuccessSS080 ss 5 3.541 ? >> 0.053 s >> j.t.CLBench2.loadNewClassSuccessSS160 ss 5 3.570 ? >> 0.113 s >> >> >> >> >> Regards, Peter >> >> >> On 10/16/2014 04:05 PM, Peter Levart wrote: >> >>> I created an issue in Jira to track this investigation: >>> >>> https://bugs.openjdk.java.net/browse/JDK-8061244 >>> >>> The latest webrev of proposed patch is still: >>> >>> http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.02/ >>> >>> I invite the public to review it. >>> >>> Thanks. >>> >>> Peter >>> >>> On 10/16/2014 10:44 AM, Peter Levart wrote: >>> >>>> Hi, >>>> >>>> As for usage of SharedSecrets, they are not needed to access CNFE >>>> package-private constructor from java.lang.ClassLoader, since they are in >>>> the same package, and from java.net.URLClassLoader, the call to >>>> super.findClass(name) does the job. So here's an updated webrev that also >>>> includes more descriptive message: >>>> >>>> http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.02/ >>>> >>>> >>>> Regards, Peter >>>> >>>> On 10/16/2014 09:35 AM, Peter Levart wrote: >>>> >>>>> On 10/16/2014 01:49 AM, Stanimir Simeonoff wrote: >>>>> >>>>>> First, really nice tests. >>>>>> >>>>>> As for hiding: missing the real classloader impl. might be quite a >>>>>> bumper >>>>>> for some middleware implementations. That would make pretty hard to >>>>>> trace >>>>>> dependency issues without explicit logging, the latter is usually >>>>>> available >>>>>> but still. Also it'd depend if the classloaders actually use >>>>>> super.findClass() or not. >>>>>> IMO, the option should be switchable via some system property. >>>>>> >>>>> With a little tweak, the message of the stack-less exception thrown >>>>> from findClass() methods can be extended to include the classloader's >>>>> runtime class name and this message can be inherited by a replacement >>>>> stack-full exception. So the stack-trace would look like: >>>>> >>>>> Exception in thread "main" java.lang.ClassNotFoundException: XXX >>>>> (thrown by: sun.misc.Launcher$AppClassLoader) >>>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:366) >>>>> at java.lang.Class.forName0(Native Method) >>>>> at java.lang.Class.forName(Class.java:265) >>>>> at Test.doIt(Test.java:7) >>>>> at Test.main(Test.java:11) >>>>> >>>>> Instead of what we have now: >>>>> >>>>> Exception in thread "main" java.lang.ClassNotFoundException: XXX >>>>> at java.net.URLClassLoader.findClass(URLClassLoader.java:381) >>>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:426) >>>>> at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:317) >>>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:359) >>>>> at java.lang.Class.forName0(Native Method) >>>>> at java.lang.Class.forName(Class.java:265) >>>>> at Test.doIt(Test.java:7) >>>>> at Test.main(Test.java:11) >>>>> >>>>> >>>>> Would this be enough to cover your concern? >>>>> >>>>> Regards, Peter >>>>> >>>>> >>>>>> I am not sure about the need to hide the stackless c-tor as the effect >>>>>> can >>>>>> be achieved by overriding fillInStackTrace(); w/o the extra baggage of >>>>>> JavaLangAccess. >>>>>> >>>>>> Overall very decent improvement. >>>>>> >>>>>> Cheers >>>>>> Stanimir >>>>>> >>>>>> >>>>>> From claes.redestad at oracle.com Tue Oct 21 13:43:07 2014 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 21 Oct 2014 15:43:07 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <543DC8D9.8010709@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> Message-ID: <544662EB.2040907@oracle.com> Hi Mandy, thanks for the review! On 10/15/2014 03:07 AM, Mandy Chung wrote: > Claes, Peter, > > Thanks for the revised webrev and Peter's thorough review. webrev.05 > looks much better. My comment is mostly minor. > > > ClassLoader.java > > line 1582-1586 - I suggest to get rid of the "oldpkg" variable > (it's really the package to be used and not an old pkg). > > pkg = new Package(name, specTitle, specVersion, specVendor, > implTitle, implVersion, implVendor, > sealBase, this); > if (packages.putIfAbsent(name, pkg) != null) { > throw new IllegalArgumentException(name + " already defined"); > } > return pkg; > > line 1634-1635: nit: the pkgName variable is not really needed. > it's in the existing code and probably good to remove it. > Package.java > > line 473: maybe better to leave the ClassLoader parameter in the > constructor. > I thought about adding a comment saying that this private constructor > is only used for system package but keeping the loader parameter makes > it more explicit. > > line 569: nit: formatting - indent to the right to align the first > parameter > to new Package(...) Fixed. > > line 621-623: is this really needed? Uncontended case seems to be > the common case. It seems the synchronized overhead would be > insignificant. I'd prefer sticking to the double-checked idiom here, unless you insist. I've cleaned up the code to avoid assignment in if-clauses, which according to anonymous sources makes the code more readable. Perhaps this addresses some of your concerns? > > line 624: a space is missing between synchronized and "(" Fixed. > > Looks like there is one test > jdk/test/java/lang/ClassLoader/GetPackage.java > about packages. Can you add a new test to verify the system packages > as that > is one major change in your patch? http://cr.openjdk.java.net/~redestad/8060130/webrev.06 Since I don't want to add binary JAR files, I opted to add a test which creates two JAR files, each with a single class (with/without manifest) and then proceeds to spawn processes to verify that: - when the JAR with manifest is on bootclasspath, the package can be found via Package.getSystemPackage and the package object reflects values added to the manifest - when the JAR without manifest is on bootclaspath, the package can be found via Package.getSystemPackage but is empty apart from name - adding the test.classes directory to bootclasspath behaves the same as adding the JAR without manifest - for any case where the class/package is not on the bootclasspath, the package information can not be found via Package.getSystemPackage(). Does this cover everything? I guess there might be a way to make @run main/othervm or main/bootclasspath pick up a dynamically generated JAR file, but I've failed to find a way that would make this work without pregenerating the JARs. Suggestions on how this can be simplified are welcome. /Claes > > Thanks > Mandy > From peter.levart at gmail.com Tue Oct 21 14:47:49 2014 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 21 Oct 2014 16:47:49 +0200 Subject: RFR: 8061244 Use of stack-less ClassNotFoundException thrown from (URL)ClassLoader.findClass() In-Reply-To: <54463760.6090809@gmail.com> References: <543EF592.3030409@gmail.com> <543F754B.4020001@gmail.com> <543F8558.2030401@gmail.com> <543FD0A6.3080207@gmail.com> <54463760.6090809@gmail.com> Message-ID: <54467215.3030105@gmail.com> On 10/21/2014 12:37 PM, Peter Levart wrote: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/CLBench2.java > > Just an observation... Running this benchmark for about a minute in sampling profiler for small call-stack depth (calling loadClass() public method on XLoader directly from main method), using original JDK code reveals that: 22.9% of CPU time is spent in findLoadedClass0[native] method called on XLoader 33.0% of CPU time is spent in defineClass1[native] method called on XLoader 16.7% of CPU time is spent in findLoadedClass0[native] method called on ExtClassLoader 23.6% of CPU time is spent in findBootstrapClass[native] static method called from ExtClassLoader 3.8% of CPU time is spent elsewhere (1.6% of that in Throwable.fillInStackTrace - not much because of minimal call-stack depth) Profiling patched code (stack-less CNFE + findLoadedClass() avoidance) reveals the following distribution of CPU time: 65.9% of CPU time is spent in defineClass1[native] method called on XLoader 32.2% of CPU time is spent in findBootstrapClass[native] static method called from ExtClassLoader 1.9 % of CPU time is spent elsewhere (1.7% of that for doPrivileged calls) Since findLoadedClass0[native] calls are non-existent in this benchmark on patched code and since they consume about 39.6% CPU time on original code, one could conclude that patched code benchmark results should show about 40% improvement in execution speed compared to original code benchmark. They show only 10% improvement (with minimal call-stack depth). The reason seems to be that defineClass1[native] method and findBootstrapClass[native] method consume absolutely more time when findLoadedClass() is not called - there seems to be some kind of "slot-reservation" in system dictionary going on in findLoadedClass() that prepares the sceen for findBootstrapClass/defineClass so that they can execute faster afterwards. But the overall effect still seems to be improvement in execution speed when findLoadedClass is skipped. Peter From ioi.lam at oracle.com Tue Oct 21 17:27:20 2014 From: ioi.lam at oracle.com (Ioi Lam) Date: Tue, 21 Oct 2014 10:27:20 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time Message-ID: <54469778.8090008@oracle.com> Please review this fix: http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v1/ Bug: Add an interface to the JVM's Class/Resource Lookup Index Cache for improving sun.misc.URLClassPath search time https://bugs.openjdk.java.net/browse/JDK-8061651 Summary of fix: Some J2EE environments have lots of JAR files in the classpath. However, during run-time, most classes are loaded by custom classloaders which delegate to the system loader. As a result, each class loaded by a custom classloader will cause many JAR search failures (in sun.misc.URLClassPath). To limit the number of searches in URLClassPath, the 8uX HotSpot VM is going to include a Class/Resource Lookup Index Cache that records information about the class/resource entries in the JAR files in the classpath. This can be used to improve sun.misc.URLClassPath search time. This is part 1 of the REF -- we are adding appropriate interfaces in both the JDK code and the HotSpot code to access this cache. URLClassPath.java is modified to use JNI to call into the HotSpot JVM_XXX APIs to access the cache. The implementation of this cache is done in part 2 of this RFE. Note that this enhancement is for JDK 8uX only. In JDK9 and beyond, we are considering an alternative implementation where the cache is maintained in the core libs code, outside of HotSpot. Tests: JPRT Adhoc SQE tests Thanks - Ioi From staffan.friberg at oracle.com Tue Oct 21 17:28:50 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Tue, 21 Oct 2014 10:28:50 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5441A192.8090602@gmail.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> Message-ID: <544697D2.6080301@oracle.com> Hi Peter, Thanks for the comments.. > > 217 if (Unsafe.ADDRESS_SIZE == 4) { > 218 // On 32 bit platforms read two ints instead of a single 64bit long > > When you're reading from byte[] using Unsafe (updateBytes), you have > the option of reading 64bit values on 64bit platforms. When you're > reading from DirectByteBuffer memory (updateDirectByteBuffer), you're > only using 32bit reads. I will add a comment in the code for this decision. The reason is that read a long results in slightly worse performance in this case, in updateBytes it is faster. I was able to get it to run slightly faster by working directly with the address instead of always adding address + off, but this makes things worse in the 32bit case since all calculation will now be using long variables. So using the getInt as in the current code feels like the best solution as it strikes the best balance between 32 and 64bit. Below is how updateByteBuffer looked with the rewrite I mentioned. ong address = ((DirectBuffer) buffer).address(); crc = updateDirectByteBuffer(crc, address + pos, address + limit); private static int updateDirectByteBuffer(int crc, long adr, long end) { // Do only byte reads for arrays so short they can't be aligned if (end - adr >= 8) { // align on 8 bytes int alignLength = (8 - (int) (adr & 0x7)) & 0x7; for (long alignEnd = adr + alignLength; adr < alignEnd; adr++) { crc = (crc >>> 8) ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; } if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { crc = Integer.reverseBytes(crc); } // slicing-by-8 for (; adr < (end - Long.BYTES); adr += Long.BYTES) { int firstHalf; int secondHalf; if (Unsafe.ADDRESS_SIZE == 4) { // On 32 bit platforms read two ints instead of a single 64bit long firstHalf = UNSAFE.getInt(adr); secondHalf = UNSAFE.getInt(adr + Integer.BYTES); } else { long value = UNSAFE.getLong(adr); if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) { firstHalf = (int) value; secondHalf = (int) (value >>> 32); } else { // ByteOrder.BIG_ENDIAN firstHalf = (int) (value >>> 32); secondHalf = (int) value; } } crc ^= firstHalf; if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) { crc = byteTable7[crc & 0xFF] ^ byteTable6[(crc >>> 8) & 0xFF] ^ byteTable5[(crc >>> 16) & 0xFF] ^ byteTable4[crc >>> 24] ^ byteTable3[secondHalf & 0xFF] ^ byteTable2[(secondHalf >>> 8) & 0xFF] ^ byteTable1[(secondHalf >>> 16) & 0xFF] ^ byteTable0[secondHalf >>> 24]; } else { // ByteOrder.BIG_ENDIAN crc = byteTable0[secondHalf & 0xFF] ^ byteTable1[(secondHalf >>> 8) & 0xFF] ^ byteTable2[(secondHalf >>> 16) & 0xFF] ^ byteTable3[secondHalf >>> 24] ^ byteTable4[crc & 0xFF] ^ byteTable5[(crc >>> 8) & 0xFF] ^ byteTable6[(crc >>> 16) & 0xFF] ^ byteTable7[crc >>> 24]; } } if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { crc = Integer.reverseBytes(crc); } } // Tail for (; adr < end; adr++) { crc = (crc >>> 8) ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; } return crc; } > > Also, in updateBytes, the usage of > Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a byte > array sounds a little scary. To be ultra portable you could check that > ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use Unsafe for byte > arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to manipulate > 'offsets' instead. In updateDirectByteBuffer it would be more > appropriate to use Integer.BYTES/Long.BYTES too. Good idea. Added a check in the initial if statement and it will get automatically optimized away. > 225 firstHalf = (int) (value & 0xFFFFFFFF); > 226 secondHalf = (int) (value >>> 32); > 227 } else { // ByteOrder.BIG_ENDIAN > 228 firstHalf = (int) (value >>> 32); > 229 secondHalf = (int) (value & 0xFFFFFFFF); > > firstHalf = (int) value; // this is equivalent for line 225 > secondHalf = (int) value; // this is equivalent for line 229 Done. Here is the latest webrev, http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 Cheers, Staffan From staffan.friberg at oracle.com Tue Oct 21 18:49:20 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Tue, 21 Oct 2014 11:49:20 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <544697D2.6080301@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> Message-ID: <5446AAB0.3090304@oracle.com> Hi, Got an offline comment that the package.html should be update as well to cover CRC-32C. Otherwise there are no code changes in this new webrev. http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.04 //Staffan On 10/21/2014 10:28 AM, Staffan Friberg wrote: > Hi Peter, > > Thanks for the comments.. >> >> 217 if (Unsafe.ADDRESS_SIZE == 4) { >> 218 // On 32 bit platforms read two ints >> instead of a single 64bit long >> >> When you're reading from byte[] using Unsafe (updateBytes), you have >> the option of reading 64bit values on 64bit platforms. When you're >> reading from DirectByteBuffer memory (updateDirectByteBuffer), you're >> only using 32bit reads. > I will add a comment in the code for this decision. The reason is that > read a long results in slightly worse performance in this case, in > updateBytes it is faster. I was able to get it to run slightly faster > by working directly with the address instead of always adding address > + off, but this makes things worse in the 32bit case since all > calculation will now be using long variables. So using the getInt as > in the current code feels like the best solution as it strikes the > best balance between 32 and 64bit. Below is how updateByteBuffer > looked with the rewrite I mentioned. > > > ong address = ((DirectBuffer) buffer).address(); > crc = updateDirectByteBuffer(crc, address + pos, address + limit); > > > private static int updateDirectByteBuffer(int crc, long adr, long > end) { > > // Do only byte reads for arrays so short they can't be aligned > if (end - adr >= 8) { > > // align on 8 bytes > int alignLength = (8 - (int) (adr & 0x7)) & 0x7; > for (long alignEnd = adr + alignLength; adr < alignEnd; > adr++) { > crc = (crc >>> 8) > ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; > } > > if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { > crc = Integer.reverseBytes(crc); > } > > // slicing-by-8 > for (; adr < (end - Long.BYTES); adr += Long.BYTES) { > int firstHalf; > int secondHalf; > if (Unsafe.ADDRESS_SIZE == 4) { > // On 32 bit platforms read two ints instead of a > single 64bit long > firstHalf = UNSAFE.getInt(adr); > secondHalf = UNSAFE.getInt(adr + Integer.BYTES); > } else { > long value = UNSAFE.getLong(adr); > if (ByteOrder.nativeOrder() == > ByteOrder.LITTLE_ENDIAN) { > firstHalf = (int) value; > secondHalf = (int) (value >>> 32); > } else { // ByteOrder.BIG_ENDIAN > firstHalf = (int) (value >>> 32); > secondHalf = (int) value; > } > } > crc ^= firstHalf; > if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) { > crc = byteTable7[crc & 0xFF] > ^ byteTable6[(crc >>> 8) & 0xFF] > ^ byteTable5[(crc >>> 16) & 0xFF] > ^ byteTable4[crc >>> 24] > ^ byteTable3[secondHalf & 0xFF] > ^ byteTable2[(secondHalf >>> 8) & 0xFF] > ^ byteTable1[(secondHalf >>> 16) & 0xFF] > ^ byteTable0[secondHalf >>> 24]; > } else { // ByteOrder.BIG_ENDIAN > crc = byteTable0[secondHalf & 0xFF] > ^ byteTable1[(secondHalf >>> 8) & 0xFF] > ^ byteTable2[(secondHalf >>> 16) & 0xFF] > ^ byteTable3[secondHalf >>> 24] > ^ byteTable4[crc & 0xFF] > ^ byteTable5[(crc >>> 8) & 0xFF] > ^ byteTable6[(crc >>> 16) & 0xFF] > ^ byteTable7[crc >>> 24]; > } > } > > if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { > crc = Integer.reverseBytes(crc); > } > } > > // Tail > for (; adr < end; adr++) { > crc = (crc >>> 8) > ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; > } > > return crc; > } > > >> >> Also, in updateBytes, the usage of >> Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a byte >> array sounds a little scary. To be ultra portable you could check >> that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use Unsafe for >> byte arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to >> manipulate 'offsets' instead. In updateDirectByteBuffer it would be >> more appropriate to use Integer.BYTES/Long.BYTES too. > Good idea. Added a check in the initial if statement and it will get > automatically optimized away. > >> 225 firstHalf = (int) (value & 0xFFFFFFFF); >> 226 secondHalf = (int) (value >>> 32); >> 227 } else { // ByteOrder.BIG_ENDIAN >> 228 firstHalf = (int) (value >>> 32); >> 229 secondHalf = (int) (value & 0xFFFFFFFF); >> >> firstHalf = (int) value; // this is equivalent for line 225 >> secondHalf = (int) value; // this is equivalent for line 229 > Done. > > Here is the latest webrev, > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 > > Cheers, > Staffan From huizhe.wang at oracle.com Tue Oct 21 19:09:39 2014 From: huizhe.wang at oracle.com (huizhe wang) Date: Tue, 21 Oct 2014 12:09:39 -0700 Subject: RFR (JAXP): 8061686: Size limits in BufferAllocator should have been final Message-ID: <5446AF73.2000009@oracle.com> Hi, The three fields in com.sun.xml.internal.stream.util.BufferAllocator are used internally only, should have been private and final. https://bugs.openjdk.java.net/browse/JDK-8061686 http://cr.openjdk.java.net/~joehw/jdk9/8061686/webrev/ Tests passed. Thanks, Joe From lance.andersen at oracle.com Tue Oct 21 19:27:18 2014 From: lance.andersen at oracle.com (Lance Andersen) Date: Tue, 21 Oct 2014 15:27:18 -0400 Subject: RFR (JAXP): 8061686: Size limits in BufferAllocator should have been final In-Reply-To: <5446AF73.2000009@oracle.com> References: <5446AF73.2000009@oracle.com> Message-ID: <882536BA-149E-495D-98F0-7A97129EE67B@oracle.com> +1 On Oct 21, 2014, at 3:09 PM, huizhe wang wrote: > Hi, > > The three fields in com.sun.xml.internal.stream.util.BufferAllocator are used internally only, should have been private and final. > > https://bugs.openjdk.java.net/browse/JDK-8061686 > http://cr.openjdk.java.net/~joehw/jdk9/8061686/webrev/ > > Tests passed. > > Thanks, > Joe Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From joe.darcy at oracle.com Tue Oct 21 19:34:41 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Tue, 21 Oct 2014 12:34:41 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5446AAB0.3090304@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <5446AAB0.3090304@oracle.com> Message-ID: <5446B551.7050605@oracle.com> Hi Staffan, If you are updating package.html, please also hg mv the file to be a package-info.java file with the equivalent javadoc. Thanks, -Joe On 10/21/2014 11:49 AM, Staffan Friberg wrote: > Hi, > > Got an offline comment that the package.html should be update as well > to cover CRC-32C. > > Otherwise there are no code changes in this new webrev. > > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.04 > > //Staffan > > On 10/21/2014 10:28 AM, Staffan Friberg wrote: >> Hi Peter, >> >> Thanks for the comments.. >>> >>> 217 if (Unsafe.ADDRESS_SIZE == 4) { >>> 218 // On 32 bit platforms read two ints >>> instead of a single 64bit long >>> >>> When you're reading from byte[] using Unsafe (updateBytes), you have >>> the option of reading 64bit values on 64bit platforms. When you're >>> reading from DirectByteBuffer memory (updateDirectByteBuffer), >>> you're only using 32bit reads. >> I will add a comment in the code for this decision. The reason is >> that read a long results in slightly worse performance in this case, >> in updateBytes it is faster. I was able to get it to run slightly >> faster by working directly with the address instead of always adding >> address + off, but this makes things worse in the 32bit case since >> all calculation will now be using long variables. So using the getInt >> as in the current code feels like the best solution as it strikes the >> best balance between 32 and 64bit. Below is how updateByteBuffer >> looked with the rewrite I mentioned. >> >> >> ong address = ((DirectBuffer) buffer).address(); >> crc = updateDirectByteBuffer(crc, address + pos, address + limit); >> >> >> private static int updateDirectByteBuffer(int crc, long adr, >> long end) { >> >> // Do only byte reads for arrays so short they can't be aligned >> if (end - adr >= 8) { >> >> // align on 8 bytes >> int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >> for (long alignEnd = adr + alignLength; adr < alignEnd; >> adr++) { >> crc = (crc >>> 8) >> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >> } >> >> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >> crc = Integer.reverseBytes(crc); >> } >> >> // slicing-by-8 >> for (; adr < (end - Long.BYTES); adr += Long.BYTES) { >> int firstHalf; >> int secondHalf; >> if (Unsafe.ADDRESS_SIZE == 4) { >> // On 32 bit platforms read two ints instead of a >> single 64bit long >> firstHalf = UNSAFE.getInt(adr); >> secondHalf = UNSAFE.getInt(adr + Integer.BYTES); >> } else { >> long value = UNSAFE.getLong(adr); >> if (ByteOrder.nativeOrder() == >> ByteOrder.LITTLE_ENDIAN) { >> firstHalf = (int) value; >> secondHalf = (int) (value >>> 32); >> } else { // ByteOrder.BIG_ENDIAN >> firstHalf = (int) (value >>> 32); >> secondHalf = (int) value; >> } >> } >> crc ^= firstHalf; >> if (ByteOrder.nativeOrder() == >> ByteOrder.LITTLE_ENDIAN) { >> crc = byteTable7[crc & 0xFF] >> ^ byteTable6[(crc >>> 8) & 0xFF] >> ^ byteTable5[(crc >>> 16) & 0xFF] >> ^ byteTable4[crc >>> 24] >> ^ byteTable3[secondHalf & 0xFF] >> ^ byteTable2[(secondHalf >>> 8) & 0xFF] >> ^ byteTable1[(secondHalf >>> 16) & 0xFF] >> ^ byteTable0[secondHalf >>> 24]; >> } else { // ByteOrder.BIG_ENDIAN >> crc = byteTable0[secondHalf & 0xFF] >> ^ byteTable1[(secondHalf >>> 8) & 0xFF] >> ^ byteTable2[(secondHalf >>> 16) & 0xFF] >> ^ byteTable3[secondHalf >>> 24] >> ^ byteTable4[crc & 0xFF] >> ^ byteTable5[(crc >>> 8) & 0xFF] >> ^ byteTable6[(crc >>> 16) & 0xFF] >> ^ byteTable7[crc >>> 24]; >> } >> } >> >> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >> crc = Integer.reverseBytes(crc); >> } >> } >> >> // Tail >> for (; adr < end; adr++) { >> crc = (crc >>> 8) >> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >> } >> >> return crc; >> } >> >> >>> >>> Also, in updateBytes, the usage of >>> Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a byte >>> array sounds a little scary. To be ultra portable you could check >>> that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use Unsafe for >>> byte arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to >>> manipulate 'offsets' instead. In updateDirectByteBuffer it would be >>> more appropriate to use Integer.BYTES/Long.BYTES too. >> Good idea. Added a check in the initial if statement and it will get >> automatically optimized away. >> >>> 225 firstHalf = (int) (value & 0xFFFFFFFF); >>> 226 secondHalf = (int) (value >>> 32); >>> 227 } else { // ByteOrder.BIG_ENDIAN >>> 228 firstHalf = (int) (value >>> 32); >>> 229 secondHalf = (int) (value & 0xFFFFFFFF); >>> >>> firstHalf = (int) value; // this is equivalent for line 225 >>> secondHalf = (int) value; // this is equivalent for line 229 >> Done. >> >> Here is the latest webrev, >> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >> >> Cheers, >> Staffan > From mandy.chung at oracle.com Tue Oct 21 19:56:27 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 21 Oct 2014 12:56:27 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time In-Reply-To: <54469778.8090008@oracle.com> References: <54469778.8090008@oracle.com> Message-ID: <5446BA6B.5030803@oracle.com> Hi Ioi, On 10/21/14 10:27 AM, Ioi Lam wrote: > Please review this fix: > http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v1/ This looks better than the preliminary webrev you sent me offline earlier. I only review the jdk repo change. Launcher.java line 290: it can be made a final field. line 297: this.ucp = .... line 317-319: I think they are meant to be two sentences. I have the following suggested text: // The class of the given name is not found in the parent // class loader as well as its local URLClassPath. // Check if this class has already been defined dynamically; // if so, return the loaded class; otherwise, skip the parent // delegation and findClass. URLClassPath.java line 76: this long line should be broken into multiple line. Maybe you can addsun.security.action.GetPropertyAction in the import and update line 72, 74, 76, 78. line 319-326: Is this LoaderType enum necessary? I think it can simply pass the ClassLoader instance to VM rather than having this enum type just for this purpose. I suggest to get rid of the LoaderType enum type. line 398: what happens if loaders.size() > maxindex? Shouldn't it return null? 404 if (getNextLoader(null, maxindex) == null || 405 !lookupCacheEnabled) { line 405 should indent to the right for better readability. The comment helps as I was initially confused why lookupCacheEnabled is not checked first. Am I right to say line 398-415 is equivalent to (excluding the debugging statements): if (loaders.size() <= maxindex &&getLoader(maxindex) != null) { returnlookupCacheEnabled ? cache : null; } return null; I think that is easier to understand. 432 urlNoFragString.equals( 433 URLUtil.urlNoFragString(lookupCacheURLs[index]))) { Should you store URLUtil.urlNoFragString form of URL in lookupCacheURLs such that they can be compared with equals? line 423-426: formatting nit: these lines look a little long and would be good to rewrap them. jvm.h 1394: typo s/Retruns/Returns As suggested above, pass the classloader instance instead of defining a new loader_type interface URLClassPath.c line 42: nit: align the parameters There are several lines calling 49JNU_ThrowNullPointerException(env, 0). 55 JNU_ThrowOutOfMemoryError(env, NULL); The msg argument probably better to be consistent and pass NULL. ClassLoader.c is a bit inconsistent. Can you add regression tests in the jdk repo? Sanity tests like with the lookup cache enabled but invalidated at startup or due to addURL call. Mandy From staffan.friberg at oracle.com Tue Oct 21 20:11:13 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Tue, 21 Oct 2014 13:11:13 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5446B551.7050605@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <5446AAB0.3090304@oracle.com> <5446B551.7050605@oracle.com> Message-ID: <5446BDE1.9090709@oracle.com> Converted. http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.05 //Staffan On 10/21/2014 12:34 PM, Joe Darcy wrote: > Hi Staffan, > > If you are updating package.html, please also hg mv the file to be a > package-info.java file with the equivalent javadoc. > > Thanks, > > -Joe > > On 10/21/2014 11:49 AM, Staffan Friberg wrote: >> Hi, >> >> Got an offline comment that the package.html should be update as well >> to cover CRC-32C. >> >> Otherwise there are no code changes in this new webrev. >> >> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.04 >> >> //Staffan >> >> On 10/21/2014 10:28 AM, Staffan Friberg wrote: >>> Hi Peter, >>> >>> Thanks for the comments.. >>>> >>>> 217 if (Unsafe.ADDRESS_SIZE == 4) { >>>> 218 // On 32 bit platforms read two ints >>>> instead of a single 64bit long >>>> >>>> When you're reading from byte[] using Unsafe (updateBytes), you >>>> have the option of reading 64bit values on 64bit platforms. When >>>> you're reading from DirectByteBuffer memory >>>> (updateDirectByteBuffer), you're only using 32bit reads. >>> I will add a comment in the code for this decision. The reason is >>> that read a long results in slightly worse performance in this case, >>> in updateBytes it is faster. I was able to get it to run slightly >>> faster by working directly with the address instead of always adding >>> address + off, but this makes things worse in the 32bit case since >>> all calculation will now be using long variables. So using the >>> getInt as in the current code feels like the best solution as it >>> strikes the best balance between 32 and 64bit. Below is how >>> updateByteBuffer looked with the rewrite I mentioned. >>> >>> >>> ong address = ((DirectBuffer) buffer).address(); >>> crc = updateDirectByteBuffer(crc, address + pos, address + limit); >>> >>> >>> private static int updateDirectByteBuffer(int crc, long adr, >>> long end) { >>> >>> // Do only byte reads for arrays so short they can't be aligned >>> if (end - adr >= 8) { >>> >>> // align on 8 bytes >>> int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >>> for (long alignEnd = adr + alignLength; adr < alignEnd; >>> adr++) { >>> crc = (crc >>> 8) >>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & >>> 0xFF]; >>> } >>> >>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>> crc = Integer.reverseBytes(crc); >>> } >>> >>> // slicing-by-8 >>> for (; adr < (end - Long.BYTES); adr += Long.BYTES) { >>> int firstHalf; >>> int secondHalf; >>> if (Unsafe.ADDRESS_SIZE == 4) { >>> // On 32 bit platforms read two ints instead of >>> a single 64bit long >>> firstHalf = UNSAFE.getInt(adr); >>> secondHalf = UNSAFE.getInt(adr + Integer.BYTES); >>> } else { >>> long value = UNSAFE.getLong(adr); >>> if (ByteOrder.nativeOrder() == >>> ByteOrder.LITTLE_ENDIAN) { >>> firstHalf = (int) value; >>> secondHalf = (int) (value >>> 32); >>> } else { // ByteOrder.BIG_ENDIAN >>> firstHalf = (int) (value >>> 32); >>> secondHalf = (int) value; >>> } >>> } >>> crc ^= firstHalf; >>> if (ByteOrder.nativeOrder() == >>> ByteOrder.LITTLE_ENDIAN) { >>> crc = byteTable7[crc & 0xFF] >>> ^ byteTable6[(crc >>> 8) & 0xFF] >>> ^ byteTable5[(crc >>> 16) & 0xFF] >>> ^ byteTable4[crc >>> 24] >>> ^ byteTable3[secondHalf & 0xFF] >>> ^ byteTable2[(secondHalf >>> 8) & 0xFF] >>> ^ byteTable1[(secondHalf >>> 16) & 0xFF] >>> ^ byteTable0[secondHalf >>> 24]; >>> } else { // ByteOrder.BIG_ENDIAN >>> crc = byteTable0[secondHalf & 0xFF] >>> ^ byteTable1[(secondHalf >>> 8) & 0xFF] >>> ^ byteTable2[(secondHalf >>> 16) & 0xFF] >>> ^ byteTable3[secondHalf >>> 24] >>> ^ byteTable4[crc & 0xFF] >>> ^ byteTable5[(crc >>> 8) & 0xFF] >>> ^ byteTable6[(crc >>> 16) & 0xFF] >>> ^ byteTable7[crc >>> 24]; >>> } >>> } >>> >>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>> crc = Integer.reverseBytes(crc); >>> } >>> } >>> >>> // Tail >>> for (; adr < end; adr++) { >>> crc = (crc >>> 8) >>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >>> } >>> >>> return crc; >>> } >>> >>> >>>> >>>> Also, in updateBytes, the usage of >>>> Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a byte >>>> array sounds a little scary. To be ultra portable you could check >>>> that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use Unsafe for >>>> byte arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to >>>> manipulate 'offsets' instead. In updateDirectByteBuffer it would be >>>> more appropriate to use Integer.BYTES/Long.BYTES too. >>> Good idea. Added a check in the initial if statement and it will get >>> automatically optimized away. >>> >>>> 225 firstHalf = (int) (value & 0xFFFFFFFF); >>>> 226 secondHalf = (int) (value >>> 32); >>>> 227 } else { // ByteOrder.BIG_ENDIAN >>>> 228 firstHalf = (int) (value >>> 32); >>>> 229 secondHalf = (int) (value & 0xFFFFFFFF); >>>> >>>> firstHalf = (int) value; // this is equivalent for line 225 >>>> secondHalf = (int) value; // this is equivalent for line 229 >>> Done. >>> >>> Here is the latest webrev, >>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>> >>> Cheers, >>> Staffan >> > From huizhe.wang at oracle.com Tue Oct 21 20:12:10 2014 From: huizhe.wang at oracle.com (huizhe wang) Date: Tue, 21 Oct 2014 13:12:10 -0700 Subject: RFR (JAXP): 8061686: Size limits in BufferAllocator should have been final In-Reply-To: <882536BA-149E-495D-98F0-7A97129EE67B@oracle.com> References: <5446AF73.2000009@oracle.com> <882536BA-149E-495D-98F0-7A97129EE67B@oracle.com> Message-ID: <5446BE1A.4020700@oracle.com> Thanks! Joe On 10/21/2014 12:27 PM, Lance Andersen wrote: > +1 > On Oct 21, 2014, at 3:09 PM, huizhe wang > wrote: > >> Hi, >> >> The three fields in com.sun.xml.internal.stream.util.BufferAllocator >> are used internally only, should have been private and final. >> >> https://bugs.openjdk.java.net/browse/JDK-8061686 >> http://cr.openjdk.java.net/~joehw/jdk9/8061686/webrev/ >> >> Tests passed. >> >> Thanks, >> Joe > > > > Lance > Andersen| Principal Member of Technical Staff | +1.781.442.2037 > Oracle Java Engineering > 1 Network Drive > Burlington, MA 01803 > Lance.Andersen at oracle.com > > > From peter.levart at gmail.com Tue Oct 21 20:30:18 2014 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 21 Oct 2014 22:30:18 +0200 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5446AAB0.3090304@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <5446AAB0.3090304@oracle.com> Message-ID: <5446C25A.1050109@gmail.com> On 10/21/2014 08:49 PM, Staffan Friberg wrote: > Hi, > > Got an offline comment that the package.html should be update as well > to cover CRC-32C. > > Otherwise there are no code changes in this new webrev. > > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.04 Hi Staffan, 198 if (end - off >= 8 && Unsafe.ARRAY_BOOLEAN_INDEX_SCALE == 1) { ARRAY_BOOLEAN_INDEX_SCALE -> ARRAY_BYTE_INDEX_SCALE Otherwise looks good now. Regards, Peter P.S. I think (by looking at DirectByteBuffer.asIntBuffer() implementation) that when doing 32 bit (4 byte) reads using Unsafe, the address only has to be aligned to 4 bytes (8 is necessary alignment for 64 bit reads). So updateDirectByteBuffer could make this alignment on 4 bytes as it's only using 32 bit reads (with additional check on ADDRESS_SIZE, you could do that for updateBytes too). You don't get much out of it, so you decide if it's worth complication. > > //Staffan > > On 10/21/2014 10:28 AM, Staffan Friberg wrote: >> Hi Peter, >> >> Thanks for the comments.. >>> >>> 217 if (Unsafe.ADDRESS_SIZE == 4) { >>> 218 // On 32 bit platforms read two ints >>> instead of a single 64bit long >>> >>> When you're reading from byte[] using Unsafe (updateBytes), you have >>> the option of reading 64bit values on 64bit platforms. When you're >>> reading from DirectByteBuffer memory (updateDirectByteBuffer), >>> you're only using 32bit reads. >> I will add a comment in the code for this decision. The reason is >> that read a long results in slightly worse performance in this case, >> in updateBytes it is faster. I was able to get it to run slightly >> faster by working directly with the address instead of always adding >> address + off, but this makes things worse in the 32bit case since >> all calculation will now be using long variables. So using the getInt >> as in the current code feels like the best solution as it strikes the >> best balance between 32 and 64bit. Below is how updateByteBuffer >> looked with the rewrite I mentioned. >> >> >> ong address = ((DirectBuffer) buffer).address(); >> crc = updateDirectByteBuffer(crc, address + pos, address + limit); >> >> >> private static int updateDirectByteBuffer(int crc, long adr, >> long end) { >> >> // Do only byte reads for arrays so short they can't be aligned >> if (end - adr >= 8) { >> >> // align on 8 bytes >> int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >> for (long alignEnd = adr + alignLength; adr < alignEnd; >> adr++) { >> crc = (crc >>> 8) >> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >> } >> >> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >> crc = Integer.reverseBytes(crc); >> } >> >> // slicing-by-8 >> for (; adr < (end - Long.BYTES); adr += Long.BYTES) { >> int firstHalf; >> int secondHalf; >> if (Unsafe.ADDRESS_SIZE == 4) { >> // On 32 bit platforms read two ints instead of a >> single 64bit long >> firstHalf = UNSAFE.getInt(adr); >> secondHalf = UNSAFE.getInt(adr + Integer.BYTES); >> } else { >> long value = UNSAFE.getLong(adr); >> if (ByteOrder.nativeOrder() == >> ByteOrder.LITTLE_ENDIAN) { >> firstHalf = (int) value; >> secondHalf = (int) (value >>> 32); >> } else { // ByteOrder.BIG_ENDIAN >> firstHalf = (int) (value >>> 32); >> secondHalf = (int) value; >> } >> } >> crc ^= firstHalf; >> if (ByteOrder.nativeOrder() == >> ByteOrder.LITTLE_ENDIAN) { >> crc = byteTable7[crc & 0xFF] >> ^ byteTable6[(crc >>> 8) & 0xFF] >> ^ byteTable5[(crc >>> 16) & 0xFF] >> ^ byteTable4[crc >>> 24] >> ^ byteTable3[secondHalf & 0xFF] >> ^ byteTable2[(secondHalf >>> 8) & 0xFF] >> ^ byteTable1[(secondHalf >>> 16) & 0xFF] >> ^ byteTable0[secondHalf >>> 24]; >> } else { // ByteOrder.BIG_ENDIAN >> crc = byteTable0[secondHalf & 0xFF] >> ^ byteTable1[(secondHalf >>> 8) & 0xFF] >> ^ byteTable2[(secondHalf >>> 16) & 0xFF] >> ^ byteTable3[secondHalf >>> 24] >> ^ byteTable4[crc & 0xFF] >> ^ byteTable5[(crc >>> 8) & 0xFF] >> ^ byteTable6[(crc >>> 16) & 0xFF] >> ^ byteTable7[crc >>> 24]; >> } >> } >> >> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >> crc = Integer.reverseBytes(crc); >> } >> } >> >> // Tail >> for (; adr < end; adr++) { >> crc = (crc >>> 8) >> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >> } >> >> return crc; >> } >> >> >>> >>> Also, in updateBytes, the usage of >>> Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a byte >>> array sounds a little scary. To be ultra portable you could check >>> that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use Unsafe for >>> byte arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to >>> manipulate 'offsets' instead. In updateDirectByteBuffer it would be >>> more appropriate to use Integer.BYTES/Long.BYTES too. >> Good idea. Added a check in the initial if statement and it will get >> automatically optimized away. >> >>> 225 firstHalf = (int) (value & 0xFFFFFFFF); >>> 226 secondHalf = (int) (value >>> 32); >>> 227 } else { // ByteOrder.BIG_ENDIAN >>> 228 firstHalf = (int) (value >>> 32); >>> 229 secondHalf = (int) (value & 0xFFFFFFFF); >>> >>> firstHalf = (int) value; // this is equivalent for line 225 >>> secondHalf = (int) value; // this is equivalent for line 229 >> Done. >> >> Here is the latest webrev, >> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >> >> Cheers, >> Staffan > From peter.levart at gmail.com Tue Oct 21 20:46:29 2014 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 21 Oct 2014 22:46:29 +0200 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5446C25A.1050109@gmail.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <5446AAB0.3090304@oracle.com> <5446C25A.1050109@gmail.com> Message-ID: <5446C625.6090804@gmail.com> Sorry Staffan, another nit... 212 for (; off < (end - Long.BYTES); off += Long.BYTES) { and 286 for (; off < (end - Long.BYTES); off += Long.BYTES) { I think you could change "off < (end - Long.BYTES)" to "off <= (end - Long.BYTES)". Am I right? Regards, Peter On 10/21/2014 10:30 PM, Peter Levart wrote: > > On 10/21/2014 08:49 PM, Staffan Friberg wrote: >> Hi, >> >> Got an offline comment that the package.html should be update as well >> to cover CRC-32C. >> >> Otherwise there are no code changes in this new webrev. >> >> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.04 > > > Hi Staffan, > > 198 if (end - off >= 8 && Unsafe.ARRAY_BOOLEAN_INDEX_SCALE == 1) { > > ARRAY_BOOLEAN_INDEX_SCALE -> ARRAY_BYTE_INDEX_SCALE > > > Otherwise looks good now. > > Regards, Peter > > P.S. > > I think (by looking at DirectByteBuffer.asIntBuffer() implementation) > that when doing 32 bit (4 byte) reads using Unsafe, the address only > has to be aligned to 4 bytes (8 is necessary alignment for 64 bit > reads). So updateDirectByteBuffer could make this alignment on 4 bytes > as it's only using 32 bit reads (with additional check on > ADDRESS_SIZE, you could do that for updateBytes too). > > You don't get much out of it, so you decide if it's worth complication. > > >> >> //Staffan >> >> On 10/21/2014 10:28 AM, Staffan Friberg wrote: >>> Hi Peter, >>> >>> Thanks for the comments.. >>>> >>>> 217 if (Unsafe.ADDRESS_SIZE == 4) { >>>> 218 // On 32 bit platforms read two ints >>>> instead of a single 64bit long >>>> >>>> When you're reading from byte[] using Unsafe (updateBytes), you >>>> have the option of reading 64bit values on 64bit platforms. When >>>> you're reading from DirectByteBuffer memory >>>> (updateDirectByteBuffer), you're only using 32bit reads. >>> I will add a comment in the code for this decision. The reason is >>> that read a long results in slightly worse performance in this case, >>> in updateBytes it is faster. I was able to get it to run slightly >>> faster by working directly with the address instead of always adding >>> address + off, but this makes things worse in the 32bit case since >>> all calculation will now be using long variables. So using the >>> getInt as in the current code feels like the best solution as it >>> strikes the best balance between 32 and 64bit. Below is how >>> updateByteBuffer looked with the rewrite I mentioned. >>> >>> >>> ong address = ((DirectBuffer) buffer).address(); >>> crc = updateDirectByteBuffer(crc, address + pos, address + limit); >>> >>> >>> private static int updateDirectByteBuffer(int crc, long adr, >>> long end) { >>> >>> // Do only byte reads for arrays so short they can't be aligned >>> if (end - adr >= 8) { >>> >>> // align on 8 bytes >>> int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >>> for (long alignEnd = adr + alignLength; adr < alignEnd; >>> adr++) { >>> crc = (crc >>> 8) >>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & >>> 0xFF]; >>> } >>> >>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>> crc = Integer.reverseBytes(crc); >>> } >>> >>> // slicing-by-8 >>> for (; adr < (end - Long.BYTES); adr += Long.BYTES) { >>> int firstHalf; >>> int secondHalf; >>> if (Unsafe.ADDRESS_SIZE == 4) { >>> // On 32 bit platforms read two ints instead of >>> a single 64bit long >>> firstHalf = UNSAFE.getInt(adr); >>> secondHalf = UNSAFE.getInt(adr + Integer.BYTES); >>> } else { >>> long value = UNSAFE.getLong(adr); >>> if (ByteOrder.nativeOrder() == >>> ByteOrder.LITTLE_ENDIAN) { >>> firstHalf = (int) value; >>> secondHalf = (int) (value >>> 32); >>> } else { // ByteOrder.BIG_ENDIAN >>> firstHalf = (int) (value >>> 32); >>> secondHalf = (int) value; >>> } >>> } >>> crc ^= firstHalf; >>> if (ByteOrder.nativeOrder() == >>> ByteOrder.LITTLE_ENDIAN) { >>> crc = byteTable7[crc & 0xFF] >>> ^ byteTable6[(crc >>> 8) & 0xFF] >>> ^ byteTable5[(crc >>> 16) & 0xFF] >>> ^ byteTable4[crc >>> 24] >>> ^ byteTable3[secondHalf & 0xFF] >>> ^ byteTable2[(secondHalf >>> 8) & 0xFF] >>> ^ byteTable1[(secondHalf >>> 16) & 0xFF] >>> ^ byteTable0[secondHalf >>> 24]; >>> } else { // ByteOrder.BIG_ENDIAN >>> crc = byteTable0[secondHalf & 0xFF] >>> ^ byteTable1[(secondHalf >>> 8) & 0xFF] >>> ^ byteTable2[(secondHalf >>> 16) & 0xFF] >>> ^ byteTable3[secondHalf >>> 24] >>> ^ byteTable4[crc & 0xFF] >>> ^ byteTable5[(crc >>> 8) & 0xFF] >>> ^ byteTable6[(crc >>> 16) & 0xFF] >>> ^ byteTable7[crc >>> 24]; >>> } >>> } >>> >>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>> crc = Integer.reverseBytes(crc); >>> } >>> } >>> >>> // Tail >>> for (; adr < end; adr++) { >>> crc = (crc >>> 8) >>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >>> } >>> >>> return crc; >>> } >>> >>> >>>> >>>> Also, in updateBytes, the usage of >>>> Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a byte >>>> array sounds a little scary. To be ultra portable you could check >>>> that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use Unsafe for >>>> byte arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to >>>> manipulate 'offsets' instead. In updateDirectByteBuffer it would be >>>> more appropriate to use Integer.BYTES/Long.BYTES too. >>> Good idea. Added a check in the initial if statement and it will get >>> automatically optimized away. >>> >>>> 225 firstHalf = (int) (value & 0xFFFFFFFF); >>>> 226 secondHalf = (int) (value >>> 32); >>>> 227 } else { // ByteOrder.BIG_ENDIAN >>>> 228 firstHalf = (int) (value >>> 32); >>>> 229 secondHalf = (int) (value & 0xFFFFFFFF); >>>> >>>> firstHalf = (int) value; // this is equivalent for line 225 >>>> secondHalf = (int) value; // this is equivalent for line 229 >>> Done. >>> >>> Here is the latest webrev, >>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>> >>> Cheers, >>> Staffan >> > From joe.darcy at oracle.com Tue Oct 21 20:58:25 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Tue, 21 Oct 2014 13:58:25 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5446BDE1.9090709@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <5446AAB0.3090304@oracle.com> <5446B551.7050605@oracle.com> <5446BDE1.9090709@oracle.com> Message-ID: <5446C8F1.8010100@oracle.com> On 10/21/2014 01:11 PM, Staffan Friberg wrote: > Converted. > > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.05 Conversion looks fine; thanks, -Joe > > //Staffan > > On 10/21/2014 12:34 PM, Joe Darcy wrote: >> Hi Staffan, >> >> If you are updating package.html, please also hg mv the file to be a >> package-info.java file with the equivalent javadoc. >> >> Thanks, >> >> -Joe >> >> On 10/21/2014 11:49 AM, Staffan Friberg wrote: >>> Hi, >>> >>> Got an offline comment that the package.html should be update as >>> well to cover CRC-32C. >>> >>> Otherwise there are no code changes in this new webrev. >>> >>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.04 >>> >>> //Staffan >>> >>> On 10/21/2014 10:28 AM, Staffan Friberg wrote: >>>> Hi Peter, >>>> >>>> Thanks for the comments.. >>>>> >>>>> 217 if (Unsafe.ADDRESS_SIZE == 4) { >>>>> 218 // On 32 bit platforms read two ints >>>>> instead of a single 64bit long >>>>> >>>>> When you're reading from byte[] using Unsafe (updateBytes), you >>>>> have the option of reading 64bit values on 64bit platforms. When >>>>> you're reading from DirectByteBuffer memory >>>>> (updateDirectByteBuffer), you're only using 32bit reads. >>>> I will add a comment in the code for this decision. The reason is >>>> that read a long results in slightly worse performance in this >>>> case, in updateBytes it is faster. I was able to get it to run >>>> slightly faster by working directly with the address instead of >>>> always adding address + off, but this makes things worse in the >>>> 32bit case since all calculation will now be using long variables. >>>> So using the getInt as in the current code feels like the best >>>> solution as it strikes the best balance between 32 and 64bit. Below >>>> is how updateByteBuffer looked with the rewrite I mentioned. >>>> >>>> >>>> ong address = ((DirectBuffer) buffer).address(); >>>> crc = updateDirectByteBuffer(crc, address + pos, address + limit); >>>> >>>> >>>> private static int updateDirectByteBuffer(int crc, long adr, >>>> long end) { >>>> >>>> // Do only byte reads for arrays so short they can't be >>>> aligned >>>> if (end - adr >= 8) { >>>> >>>> // align on 8 bytes >>>> int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >>>> for (long alignEnd = adr + alignLength; adr < alignEnd; >>>> adr++) { >>>> crc = (crc >>> 8) >>>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & >>>> 0xFF]; >>>> } >>>> >>>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>>> crc = Integer.reverseBytes(crc); >>>> } >>>> >>>> // slicing-by-8 >>>> for (; adr < (end - Long.BYTES); adr += Long.BYTES) { >>>> int firstHalf; >>>> int secondHalf; >>>> if (Unsafe.ADDRESS_SIZE == 4) { >>>> // On 32 bit platforms read two ints instead of >>>> a single 64bit long >>>> firstHalf = UNSAFE.getInt(adr); >>>> secondHalf = UNSAFE.getInt(adr + Integer.BYTES); >>>> } else { >>>> long value = UNSAFE.getLong(adr); >>>> if (ByteOrder.nativeOrder() == >>>> ByteOrder.LITTLE_ENDIAN) { >>>> firstHalf = (int) value; >>>> secondHalf = (int) (value >>> 32); >>>> } else { // ByteOrder.BIG_ENDIAN >>>> firstHalf = (int) (value >>> 32); >>>> secondHalf = (int) value; >>>> } >>>> } >>>> crc ^= firstHalf; >>>> if (ByteOrder.nativeOrder() == >>>> ByteOrder.LITTLE_ENDIAN) { >>>> crc = byteTable7[crc & 0xFF] >>>> ^ byteTable6[(crc >>> 8) & 0xFF] >>>> ^ byteTable5[(crc >>> 16) & 0xFF] >>>> ^ byteTable4[crc >>> 24] >>>> ^ byteTable3[secondHalf & 0xFF] >>>> ^ byteTable2[(secondHalf >>> 8) & 0xFF] >>>> ^ byteTable1[(secondHalf >>> 16) & 0xFF] >>>> ^ byteTable0[secondHalf >>> 24]; >>>> } else { // ByteOrder.BIG_ENDIAN >>>> crc = byteTable0[secondHalf & 0xFF] >>>> ^ byteTable1[(secondHalf >>> 8) & 0xFF] >>>> ^ byteTable2[(secondHalf >>> 16) & 0xFF] >>>> ^ byteTable3[secondHalf >>> 24] >>>> ^ byteTable4[crc & 0xFF] >>>> ^ byteTable5[(crc >>> 8) & 0xFF] >>>> ^ byteTable6[(crc >>> 16) & 0xFF] >>>> ^ byteTable7[crc >>> 24]; >>>> } >>>> } >>>> >>>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>>> crc = Integer.reverseBytes(crc); >>>> } >>>> } >>>> >>>> // Tail >>>> for (; adr < end; adr++) { >>>> crc = (crc >>> 8) >>>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >>>> } >>>> >>>> return crc; >>>> } >>>> >>>> >>>>> >>>>> Also, in updateBytes, the usage of >>>>> Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a >>>>> byte array sounds a little scary. To be ultra portable you could >>>>> check that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use >>>>> Unsafe for byte arrays if it is not 1. Then use >>>>> Integer.BYTES/Long.BYTES to manipulate 'offsets' instead. In >>>>> updateDirectByteBuffer it would be more appropriate to use >>>>> Integer.BYTES/Long.BYTES too. >>>> Good idea. Added a check in the initial if statement and it will >>>> get automatically optimized away. >>>> >>>>> 225 firstHalf = (int) (value & 0xFFFFFFFF); >>>>> 226 secondHalf = (int) (value >>> 32); >>>>> 227 } else { // ByteOrder.BIG_ENDIAN >>>>> 228 firstHalf = (int) (value >>> 32); >>>>> 229 secondHalf = (int) (value & >>>>> 0xFFFFFFFF); >>>>> >>>>> firstHalf = (int) value; // this is equivalent for line 225 >>>>> secondHalf = (int) value; // this is equivalent for line 229 >>>> Done. >>>> >>>> Here is the latest webrev, >>>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>>> >>>> Cheers, >>>> Staffan >>> >> > From jiangli.zhou at oracle.com Tue Oct 21 21:04:43 2014 From: jiangli.zhou at oracle.com (Jiangli Zhou) Date: Tue, 21 Oct 2014 14:04:43 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time In-Reply-To: <54469778.8090008@oracle.com> References: <54469778.8090008@oracle.com> Message-ID: <5446CA6B.5090204@oracle.com> Hi Ioi, Here are some comments from me: -src/share/vm/classfile/classLoader.cpp In ClassLoader::setup_search_path, if canonicalize is true it's not necessary to allocate the 'path' and copy the 'class_path' to 'path'. -src/share/vm/memory/metadataFactory.hpp In free_array, is it possible to disable it only when PrintSharedSpaces is enabled, instead of disabling it for all? -jdk/src/share/native/sun/misc/URLClassPath.c Is verifying class name needed in Java_sun_misc_URLClassPath_knownToNotExist0? The class name will be verified when the class loader loads the class. -jdk/src/share/classes/sun/misc/URLClassPath.java CanlookupCacheEnabled flag change during runtime? In getLookupCache() the flag is checked more than once. Thanks, Jiangli On 10/21/2014 10:27 AM, Ioi Lam wrote: > Please review this fix: > > http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v1/ > > Bug: Add an interface to the JVM's Class/Resource Lookup Index Cache > for improving sun.misc.URLClassPath search time > > https://bugs.openjdk.java.net/browse/JDK-8061651 > > Summary of fix: > > Some J2EE environments have lots of JAR files in the > classpath. However, during run-time, most classes are loaded by > custom classloaders which delegate to the system loader. As a > result, each class loaded by a custom classloader will cause many > JAR search failures (in sun.misc.URLClassPath). > > To limit the number of searches in URLClassPath, the 8uX HotSpot > VM is going to include a Class/Resource Lookup Index Cache that > records information about the class/resource entries in the JAR > files in the classpath. This can be used to improve > sun.misc.URLClassPath search time. > > This is part 1 of the REF -- we are adding appropriate interfaces > in both the JDK code and the HotSpot code to access this cache. > > URLClassPath.java is modified to use JNI to call into the HotSpot > JVM_XXX APIs to access the cache. > > The implementation of this cache is done in part 2 of this RFE. > > Note that this enhancement is for JDK 8uX only. In JDK9 and > beyond, we are considering an alternative implementation where the > cache is maintained in the core libs code, outside of HotSpot. > > Tests: > > JPRT > Adhoc SQE tests > > Thanks > - Ioi From xueming.shen at oracle.com Tue Oct 21 21:09:37 2014 From: xueming.shen at oracle.com (Xueming Shen) Date: Tue, 21 Oct 2014 14:09:37 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5446BDE1.9090709@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <5446AAB0.3090304@oracle.com> <5446B551.7050605@oracle.com> <5446BDE1.9090709@oracle.com> Message-ID: <5446CB91.3050503@oracle.com> Staffan, Thanks for the package.html update. Just wonder if it would be better to use buffer.remaining(), instead of the buffer.limit() - buffer.position() in Checksum.udpate(ByteBuffer)'s #implSpec The rest looks fine for me. -Sherman On 10/21/2014 01:11 PM, Staffan Friberg wrote: > Converted. > > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.05 > > //Staffan > > On 10/21/2014 12:34 PM, Joe Darcy wrote: >> Hi Staffan, >> >> If you are updating package.html, please also hg mv the file to be a package-info.java file with the equivalent javadoc. >> >> Thanks, >> >> -Joe >> >> On 10/21/2014 11:49 AM, Staffan Friberg wrote: >>> Hi, >>> >>> Got an offline comment that the package.html should be update as well to cover CRC-32C. >>> >>> Otherwise there are no code changes in this new webrev. >>> >>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.04 >>> >>> //Staffan >>> >>> On 10/21/2014 10:28 AM, Staffan Friberg wrote: >>>> Hi Peter, >>>> >>>> Thanks for the comments.. >>>>> >>>>> 217 if (Unsafe.ADDRESS_SIZE == 4) { >>>>> 218 // On 32 bit platforms read two ints instead of a single 64bit long >>>>> >>>>> When you're reading from byte[] using Unsafe (updateBytes), you have the option of reading 64bit values on 64bit platforms. When you're reading from DirectByteBuffer memory (updateDirectByteBuffer), you're only using 32bit reads. >>>> I will add a comment in the code for this decision. The reason is that read a long results in slightly worse performance in this case, in updateBytes it is faster. I was able to get it to run slightly faster by working directly with the address instead of always adding address + off, but this makes things worse in the 32bit case since all calculation will now be using long variables. So using the getInt as in the current code feels like the best solution as it strikes the best balance between 32 and 64bit. Below is how updateByteBuffer looked with the rewrite I mentioned. >>>> >>>> >>>> ong address = ((DirectBuffer) buffer).address(); >>>> crc = updateDirectByteBuffer(crc, address + pos, address + limit); >>>> >>>> >>>> private static int updateDirectByteBuffer(int crc, long adr, long end) { >>>> >>>> // Do only byte reads for arrays so short they can't be aligned >>>> if (end - adr >= 8) { >>>> >>>> // align on 8 bytes >>>> int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >>>> for (long alignEnd = adr + alignLength; adr < alignEnd; adr++) { >>>> crc = (crc >>> 8) >>>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >>>> } >>>> >>>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>>> crc = Integer.reverseBytes(crc); >>>> } >>>> >>>> // slicing-by-8 >>>> for (; adr < (end - Long.BYTES); adr += Long.BYTES) { >>>> int firstHalf; >>>> int secondHalf; >>>> if (Unsafe.ADDRESS_SIZE == 4) { >>>> // On 32 bit platforms read two ints instead of a single 64bit long >>>> firstHalf = UNSAFE.getInt(adr); >>>> secondHalf = UNSAFE.getInt(adr + Integer.BYTES); >>>> } else { >>>> long value = UNSAFE.getLong(adr); >>>> if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) { >>>> firstHalf = (int) value; >>>> secondHalf = (int) (value >>> 32); >>>> } else { // ByteOrder.BIG_ENDIAN >>>> firstHalf = (int) (value >>> 32); >>>> secondHalf = (int) value; >>>> } >>>> } >>>> crc ^= firstHalf; >>>> if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) { >>>> crc = byteTable7[crc & 0xFF] >>>> ^ byteTable6[(crc >>> 8) & 0xFF] >>>> ^ byteTable5[(crc >>> 16) & 0xFF] >>>> ^ byteTable4[crc >>> 24] >>>> ^ byteTable3[secondHalf & 0xFF] >>>> ^ byteTable2[(secondHalf >>> 8) & 0xFF] >>>> ^ byteTable1[(secondHalf >>> 16) & 0xFF] >>>> ^ byteTable0[secondHalf >>> 24]; >>>> } else { // ByteOrder.BIG_ENDIAN >>>> crc = byteTable0[secondHalf & 0xFF] >>>> ^ byteTable1[(secondHalf >>> 8) & 0xFF] >>>> ^ byteTable2[(secondHalf >>> 16) & 0xFF] >>>> ^ byteTable3[secondHalf >>> 24] >>>> ^ byteTable4[crc & 0xFF] >>>> ^ byteTable5[(crc >>> 8) & 0xFF] >>>> ^ byteTable6[(crc >>> 16) & 0xFF] >>>> ^ byteTable7[crc >>> 24]; >>>> } >>>> } >>>> >>>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>>> crc = Integer.reverseBytes(crc); >>>> } >>>> } >>>> >>>> // Tail >>>> for (; adr < end; adr++) { >>>> crc = (crc >>> 8) >>>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >>>> } >>>> >>>> return crc; >>>> } >>>> >>>> >>>>> >>>>> Also, in updateBytes, the usage of Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a byte array sounds a little scary. To be ultra portable you could check that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use Unsafe for byte arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to manipulate 'offsets' instead. In updateDirectByteBuffer it would be more appropriate to use Integer.BYTES/Long.BYTES too. >>>> Good idea. Added a check in the initial if statement and it will get automatically optimized away. >>>> >>>>> 225 firstHalf = (int) (value & 0xFFFFFFFF); >>>>> 226 secondHalf = (int) (value >>> 32); >>>>> 227 } else { // ByteOrder.BIG_ENDIAN >>>>> 228 firstHalf = (int) (value >>> 32); >>>>> 229 secondHalf = (int) (value & 0xFFFFFFFF); >>>>> >>>>> firstHalf = (int) value; // this is equivalent for line 225 >>>>> secondHalf = (int) value; // this is equivalent for line 229 >>>> Done. >>>> >>>> Here is the latest webrev, http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>>> >>>> Cheers, >>>> Staffan >>> >> > From ecki at zusammenkunft.net Tue Oct 21 21:08:58 2014 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Tue, 21 Oct 2014 23:08:58 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <544662EB.2040907@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> <544662EB.2040907@oracle.com> Message-ID: <20141021230858.00006471.ecki@zusammenkunft.net> Hello, one thing I wonder - in the old and in the new case there is nothing in definePackage() guaring the parents from getting to know the new package and causing a conflict (as the atomic insert is only on the specific packages table. Are those (parent and system package) immutable? Gruss Bernd the package Am Tue, 21 Oct 2014 15:43:07 +0200 schrieb Claes Redestad : > Hi Mandy, > > thanks for the review! > > On 10/15/2014 03:07 AM, Mandy Chung wrote: > > Claes, Peter, > > > > Thanks for the revised webrev and Peter's thorough review. > > webrev.05 looks much better. My comment is mostly minor. > > > > > > ClassLoader.java > > > > line 1582-1586 - I suggest to get rid of the "oldpkg" variable > > (it's really the package to be used and not an old pkg). > > > > pkg = new Package(name, specTitle, specVersion, specVendor, > > implTitle, implVersion, implVendor, > > sealBase, this); > > if (packages.putIfAbsent(name, pkg) != null) { > > throw new IllegalArgumentException(name + " already > > defined"); } > > return pkg; > > > > line 1634-1635: nit: the pkgName variable is not really needed. > > it's in the existing code and probably good to remove it. > > Package.java > > > > line 473: maybe better to leave the ClassLoader parameter in the > > constructor. > > I thought about adding a comment saying that this private > > constructor is only used for system package but keeping the loader > > parameter makes it more explicit. > > > > line 569: nit: formatting - indent to the right to align the first > > parameter > > to new Package(...) > > Fixed. > > > > > line 621-623: is this really needed? Uncontended case seems to be > > the common case. It seems the synchronized overhead would be > > insignificant. > > I'd prefer sticking to the double-checked idiom here, unless you > insist. > > I've cleaned up the code to avoid assignment in if-clauses, which > according to > anonymous sources makes the code more readable. Perhaps this addresses > some of your concerns? > > > > > line 624: a space is missing between synchronized and "(" > > Fixed. > > > > > Looks like there is one test > > jdk/test/java/lang/ClassLoader/GetPackage.java > > about packages. Can you add a new test to verify the system > > packages as that > > is one major change in your patch? > > http://cr.openjdk.java.net/~redestad/8060130/webrev.06 > > Since I don't want to add binary JAR files, I opted to add a test > which creates two JAR files, > each with a single class (with/without manifest) and then proceeds to > spawn processes > to verify that: > > - when the JAR with manifest is on bootclasspath, the package can be > found via > Package.getSystemPackage and the package object reflects values added > to the manifest > - when the JAR without manifest is on bootclaspath, the package can > be found via > Package.getSystemPackage but is empty apart from name > - adding the test.classes directory to bootclasspath behaves the same > as adding the JAR > without manifest > - for any case where the class/package is not on the bootclasspath, > the package information > can not be found via Package.getSystemPackage(). > > Does this cover everything? > > I guess there might be a way to make @run main/othervm or > main/bootclasspath pick > up a dynamically generated JAR file, but I've failed to find a way > that would make this work without > pregenerating the JARs. Suggestions on how this can be simplified are > welcome. > > /Claes > > > > > Thanks > > Mandy > > From staffan.friberg at oracle.com Tue Oct 21 21:14:30 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Tue, 21 Oct 2014 14:14:30 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5446C25A.1050109@gmail.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <5446AAB0.3090304@oracle.com> <5446C25A.1050109@gmail.com> Message-ID: <5446CCB6.5020604@oracle.com> Hi Peter, Thanks for catching! I would like to keep to 8 since the crc32c instruction on SPARC will require it, the plan is to add an intrinsic for it. Thanks, Staffan On 10/21/2014 01:30 PM, Peter Levart wrote: > > On 10/21/2014 08:49 PM, Staffan Friberg wrote: >> Hi, >> >> Got an offline comment that the package.html should be update as well >> to cover CRC-32C. >> >> Otherwise there are no code changes in this new webrev. >> >> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.04 > > > Hi Staffan, > > 198 if (end - off >= 8 && Unsafe.ARRAY_BOOLEAN_INDEX_SCALE == 1) { > > ARRAY_BOOLEAN_INDEX_SCALE -> ARRAY_BYTE_INDEX_SCALE > > > Otherwise looks good now. > > Regards, Peter > > P.S. > > I think (by looking at DirectByteBuffer.asIntBuffer() implementation) > that when doing 32 bit (4 byte) reads using Unsafe, the address only > has to be aligned to 4 bytes (8 is necessary alignment for 64 bit > reads). So updateDirectByteBuffer could make this alignment on 4 bytes > as it's only using 32 bit reads (with additional check on > ADDRESS_SIZE, you could do that for updateBytes too). > > You don't get much out of it, so you decide if it's worth complication. > > >> >> //Staffan >> >> On 10/21/2014 10:28 AM, Staffan Friberg wrote: >>> Hi Peter, >>> >>> Thanks for the comments.. >>>> >>>> 217 if (Unsafe.ADDRESS_SIZE == 4) { >>>> 218 // On 32 bit platforms read two ints >>>> instead of a single 64bit long >>>> >>>> When you're reading from byte[] using Unsafe (updateBytes), you >>>> have the option of reading 64bit values on 64bit platforms. When >>>> you're reading from DirectByteBuffer memory >>>> (updateDirectByteBuffer), you're only using 32bit reads. >>> I will add a comment in the code for this decision. The reason is >>> that read a long results in slightly worse performance in this case, >>> in updateBytes it is faster. I was able to get it to run slightly >>> faster by working directly with the address instead of always adding >>> address + off, but this makes things worse in the 32bit case since >>> all calculation will now be using long variables. So using the >>> getInt as in the current code feels like the best solution as it >>> strikes the best balance between 32 and 64bit. Below is how >>> updateByteBuffer looked with the rewrite I mentioned. >>> >>> >>> ong address = ((DirectBuffer) buffer).address(); >>> crc = updateDirectByteBuffer(crc, address + pos, address + limit); >>> >>> >>> private static int updateDirectByteBuffer(int crc, long adr, >>> long end) { >>> >>> // Do only byte reads for arrays so short they can't be aligned >>> if (end - adr >= 8) { >>> >>> // align on 8 bytes >>> int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >>> for (long alignEnd = adr + alignLength; adr < alignEnd; >>> adr++) { >>> crc = (crc >>> 8) >>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & >>> 0xFF]; >>> } >>> >>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>> crc = Integer.reverseBytes(crc); >>> } >>> >>> // slicing-by-8 >>> for (; adr < (end - Long.BYTES); adr += Long.BYTES) { >>> int firstHalf; >>> int secondHalf; >>> if (Unsafe.ADDRESS_SIZE == 4) { >>> // On 32 bit platforms read two ints instead of >>> a single 64bit long >>> firstHalf = UNSAFE.getInt(adr); >>> secondHalf = UNSAFE.getInt(adr + Integer.BYTES); >>> } else { >>> long value = UNSAFE.getLong(adr); >>> if (ByteOrder.nativeOrder() == >>> ByteOrder.LITTLE_ENDIAN) { >>> firstHalf = (int) value; >>> secondHalf = (int) (value >>> 32); >>> } else { // ByteOrder.BIG_ENDIAN >>> firstHalf = (int) (value >>> 32); >>> secondHalf = (int) value; >>> } >>> } >>> crc ^= firstHalf; >>> if (ByteOrder.nativeOrder() == >>> ByteOrder.LITTLE_ENDIAN) { >>> crc = byteTable7[crc & 0xFF] >>> ^ byteTable6[(crc >>> 8) & 0xFF] >>> ^ byteTable5[(crc >>> 16) & 0xFF] >>> ^ byteTable4[crc >>> 24] >>> ^ byteTable3[secondHalf & 0xFF] >>> ^ byteTable2[(secondHalf >>> 8) & 0xFF] >>> ^ byteTable1[(secondHalf >>> 16) & 0xFF] >>> ^ byteTable0[secondHalf >>> 24]; >>> } else { // ByteOrder.BIG_ENDIAN >>> crc = byteTable0[secondHalf & 0xFF] >>> ^ byteTable1[(secondHalf >>> 8) & 0xFF] >>> ^ byteTable2[(secondHalf >>> 16) & 0xFF] >>> ^ byteTable3[secondHalf >>> 24] >>> ^ byteTable4[crc & 0xFF] >>> ^ byteTable5[(crc >>> 8) & 0xFF] >>> ^ byteTable6[(crc >>> 16) & 0xFF] >>> ^ byteTable7[crc >>> 24]; >>> } >>> } >>> >>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>> crc = Integer.reverseBytes(crc); >>> } >>> } >>> >>> // Tail >>> for (; adr < end; adr++) { >>> crc = (crc >>> 8) >>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >>> } >>> >>> return crc; >>> } >>> >>> >>>> >>>> Also, in updateBytes, the usage of >>>> Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a byte >>>> array sounds a little scary. To be ultra portable you could check >>>> that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use Unsafe for >>>> byte arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to >>>> manipulate 'offsets' instead. In updateDirectByteBuffer it would be >>>> more appropriate to use Integer.BYTES/Long.BYTES too. >>> Good idea. Added a check in the initial if statement and it will get >>> automatically optimized away. >>> >>>> 225 firstHalf = (int) (value & 0xFFFFFFFF); >>>> 226 secondHalf = (int) (value >>> 32); >>>> 227 } else { // ByteOrder.BIG_ENDIAN >>>> 228 firstHalf = (int) (value >>> 32); >>>> 229 secondHalf = (int) (value & 0xFFFFFFFF); >>>> >>>> firstHalf = (int) value; // this is equivalent for line 225 >>>> secondHalf = (int) value; // this is equivalent for line 229 >>> Done. >>> >>> Here is the latest webrev, >>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>> >>> Cheers, >>> Staffan >> > From staffan.friberg at oracle.com Tue Oct 21 21:34:55 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Tue, 21 Oct 2014 14:34:55 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5446C625.6090804@gmail.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <5446AAB0.3090304@oracle.com> <5446C25A.1050109@gmail.com> <5446C625.6090804@gmail.com> Message-ID: <5446D17F.3060906@oracle.com> I believe it must be <, as it is in the tail loop as well, because end is (off+len or limit) so end is exclusive, similar to subString(begin,end). Makes sense? //Staffan On 10/21/2014 01:46 PM, Peter Levart wrote: > Sorry Staffan, another nit... > > 212 for (; off < (end - Long.BYTES); off += Long.BYTES) { > and > > 286 for (; off < (end - Long.BYTES); off += Long.BYTES) { > > > I think you could change "off < (end - Long.BYTES)" to "off <= (end - > Long.BYTES)". Am I right? > > Regards, Peter > > > On 10/21/2014 10:30 PM, Peter Levart wrote: >> >> On 10/21/2014 08:49 PM, Staffan Friberg wrote: >>> Hi, >>> >>> Got an offline comment that the package.html should be update as >>> well to cover CRC-32C. >>> >>> Otherwise there are no code changes in this new webrev. >>> >>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.04 >> >> >> Hi Staffan, >> >> 198 if (end - off >= 8 && Unsafe.ARRAY_BOOLEAN_INDEX_SCALE == 1) { >> >> ARRAY_BOOLEAN_INDEX_SCALE -> ARRAY_BYTE_INDEX_SCALE >> >> >> Otherwise looks good now. >> >> Regards, Peter >> >> P.S. >> >> I think (by looking at DirectByteBuffer.asIntBuffer() implementation) >> that when doing 32 bit (4 byte) reads using Unsafe, the address only >> has to be aligned to 4 bytes (8 is necessary alignment for 64 bit >> reads). So updateDirectByteBuffer could make this alignment on 4 >> bytes as it's only using 32 bit reads (with additional check on >> ADDRESS_SIZE, you could do that for updateBytes too). >> >> You don't get much out of it, so you decide if it's worth complication. >> >> >>> >>> //Staffan >>> >>> On 10/21/2014 10:28 AM, Staffan Friberg wrote: >>>> Hi Peter, >>>> >>>> Thanks for the comments.. >>>>> >>>>> 217 if (Unsafe.ADDRESS_SIZE == 4) { >>>>> 218 // On 32 bit platforms read two ints >>>>> instead of a single 64bit long >>>>> >>>>> When you're reading from byte[] using Unsafe (updateBytes), you >>>>> have the option of reading 64bit values on 64bit platforms. When >>>>> you're reading from DirectByteBuffer memory >>>>> (updateDirectByteBuffer), you're only using 32bit reads. >>>> I will add a comment in the code for this decision. The reason is >>>> that read a long results in slightly worse performance in this >>>> case, in updateBytes it is faster. I was able to get it to run >>>> slightly faster by working directly with the address instead of >>>> always adding address + off, but this makes things worse in the >>>> 32bit case since all calculation will now be using long variables. >>>> So using the getInt as in the current code feels like the best >>>> solution as it strikes the best balance between 32 and 64bit. Below >>>> is how updateByteBuffer looked with the rewrite I mentioned. >>>> >>>> >>>> ong address = ((DirectBuffer) buffer).address(); >>>> crc = updateDirectByteBuffer(crc, address + pos, address + limit); >>>> >>>> >>>> private static int updateDirectByteBuffer(int crc, long adr, >>>> long end) { >>>> >>>> // Do only byte reads for arrays so short they can't be >>>> aligned >>>> if (end - adr >= 8) { >>>> >>>> // align on 8 bytes >>>> int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >>>> for (long alignEnd = adr + alignLength; adr < alignEnd; >>>> adr++) { >>>> crc = (crc >>> 8) >>>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & >>>> 0xFF]; >>>> } >>>> >>>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>>> crc = Integer.reverseBytes(crc); >>>> } >>>> >>>> // slicing-by-8 >>>> for (; adr < (end - Long.BYTES); adr += Long.BYTES) { >>>> int firstHalf; >>>> int secondHalf; >>>> if (Unsafe.ADDRESS_SIZE == 4) { >>>> // On 32 bit platforms read two ints instead of >>>> a single 64bit long >>>> firstHalf = UNSAFE.getInt(adr); >>>> secondHalf = UNSAFE.getInt(adr + Integer.BYTES); >>>> } else { >>>> long value = UNSAFE.getLong(adr); >>>> if (ByteOrder.nativeOrder() == >>>> ByteOrder.LITTLE_ENDIAN) { >>>> firstHalf = (int) value; >>>> secondHalf = (int) (value >>> 32); >>>> } else { // ByteOrder.BIG_ENDIAN >>>> firstHalf = (int) (value >>> 32); >>>> secondHalf = (int) value; >>>> } >>>> } >>>> crc ^= firstHalf; >>>> if (ByteOrder.nativeOrder() == >>>> ByteOrder.LITTLE_ENDIAN) { >>>> crc = byteTable7[crc & 0xFF] >>>> ^ byteTable6[(crc >>> 8) & 0xFF] >>>> ^ byteTable5[(crc >>> 16) & 0xFF] >>>> ^ byteTable4[crc >>> 24] >>>> ^ byteTable3[secondHalf & 0xFF] >>>> ^ byteTable2[(secondHalf >>> 8) & 0xFF] >>>> ^ byteTable1[(secondHalf >>> 16) & 0xFF] >>>> ^ byteTable0[secondHalf >>> 24]; >>>> } else { // ByteOrder.BIG_ENDIAN >>>> crc = byteTable0[secondHalf & 0xFF] >>>> ^ byteTable1[(secondHalf >>> 8) & 0xFF] >>>> ^ byteTable2[(secondHalf >>> 16) & 0xFF] >>>> ^ byteTable3[secondHalf >>> 24] >>>> ^ byteTable4[crc & 0xFF] >>>> ^ byteTable5[(crc >>> 8) & 0xFF] >>>> ^ byteTable6[(crc >>> 16) & 0xFF] >>>> ^ byteTable7[crc >>> 24]; >>>> } >>>> } >>>> >>>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>>> crc = Integer.reverseBytes(crc); >>>> } >>>> } >>>> >>>> // Tail >>>> for (; adr < end; adr++) { >>>> crc = (crc >>> 8) >>>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >>>> } >>>> >>>> return crc; >>>> } >>>> >>>> >>>>> >>>>> Also, in updateBytes, the usage of >>>>> Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a >>>>> byte array sounds a little scary. To be ultra portable you could >>>>> check that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use >>>>> Unsafe for byte arrays if it is not 1. Then use >>>>> Integer.BYTES/Long.BYTES to manipulate 'offsets' instead. In >>>>> updateDirectByteBuffer it would be more appropriate to use >>>>> Integer.BYTES/Long.BYTES too. >>>> Good idea. Added a check in the initial if statement and it will >>>> get automatically optimized away. >>>> >>>>> 225 firstHalf = (int) (value & 0xFFFFFFFF); >>>>> 226 secondHalf = (int) (value >>> 32); >>>>> 227 } else { // ByteOrder.BIG_ENDIAN >>>>> 228 firstHalf = (int) (value >>> 32); >>>>> 229 secondHalf = (int) (value & >>>>> 0xFFFFFFFF); >>>>> >>>>> firstHalf = (int) value; // this is equivalent for line 225 >>>>> secondHalf = (int) value; // this is equivalent for line 229 >>>> Done. >>>> >>>> Here is the latest webrev, >>>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>>> >>>> Cheers, >>>> Staffan >>> >> > From staffan.friberg at oracle.com Tue Oct 21 22:16:04 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Tue, 21 Oct 2014 15:16:04 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5446CB91.3050503@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <5446AAB0.3090304@oracle.com> <5446B551.7050605@oracle.com> <5446BDE1.9090709@oracle.com> <5446CB91.3050503@oracle.com> Message-ID: <5446DB24.4000507@oracle.com> Thanks for the review. Updated the @implSpec. Also includes Peter's good catch. Webrev: http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.06 //Staffan On 10/21/2014 02:09 PM, Xueming Shen wrote: > Staffan, > > Thanks for the package.html update. > > Just wonder if it would be better to use > > buffer.remaining(), instead of the buffer.limit() - buffer.position() > > in Checksum.udpate(ByteBuffer)'s #implSpec > > The rest looks fine for me. > > -Sherman > > On 10/21/2014 01:11 PM, Staffan Friberg wrote: >> Converted. >> >> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.05 >> >> //Staffan >> >> On 10/21/2014 12:34 PM, Joe Darcy wrote: >>> Hi Staffan, >>> >>> If you are updating package.html, please also hg mv the file to be a >>> package-info.java file with the equivalent javadoc. >>> >>> Thanks, >>> >>> -Joe >>> >>> On 10/21/2014 11:49 AM, Staffan Friberg wrote: >>>> Hi, >>>> >>>> Got an offline comment that the package.html should be update as >>>> well to cover CRC-32C. >>>> >>>> Otherwise there are no code changes in this new webrev. >>>> >>>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.04 >>>> >>>> //Staffan >>>> >>>> On 10/21/2014 10:28 AM, Staffan Friberg wrote: >>>>> Hi Peter, >>>>> >>>>> Thanks for the comments.. >>>>>> >>>>>> 217 if (Unsafe.ADDRESS_SIZE == 4) { >>>>>> 218 // On 32 bit platforms read two ints >>>>>> instead of a single 64bit long >>>>>> >>>>>> When you're reading from byte[] using Unsafe (updateBytes), you >>>>>> have the option of reading 64bit values on 64bit platforms. When >>>>>> you're reading from DirectByteBuffer memory >>>>>> (updateDirectByteBuffer), you're only using 32bit reads. >>>>> I will add a comment in the code for this decision. The reason is >>>>> that read a long results in slightly worse performance in this >>>>> case, in updateBytes it is faster. I was able to get it to run >>>>> slightly faster by working directly with the address instead of >>>>> always adding address + off, but this makes things worse in the >>>>> 32bit case since all calculation will now be using long variables. >>>>> So using the getInt as in the current code feels like the best >>>>> solution as it strikes the best balance between 32 and 64bit. >>>>> Below is how updateByteBuffer looked with the rewrite I mentioned. >>>>> >>>>> >>>>> ong address = ((DirectBuffer) buffer).address(); >>>>> crc = updateDirectByteBuffer(crc, address + pos, address + limit); >>>>> >>>>> >>>>> private static int updateDirectByteBuffer(int crc, long adr, >>>>> long end) { >>>>> >>>>> // Do only byte reads for arrays so short they can't be >>>>> aligned >>>>> if (end - adr >= 8) { >>>>> >>>>> // align on 8 bytes >>>>> int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >>>>> for (long alignEnd = adr + alignLength; adr < >>>>> alignEnd; adr++) { >>>>> crc = (crc >>> 8) >>>>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & >>>>> 0xFF]; >>>>> } >>>>> >>>>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>>>> crc = Integer.reverseBytes(crc); >>>>> } >>>>> >>>>> // slicing-by-8 >>>>> for (; adr < (end - Long.BYTES); adr += Long.BYTES) { >>>>> int firstHalf; >>>>> int secondHalf; >>>>> if (Unsafe.ADDRESS_SIZE == 4) { >>>>> // On 32 bit platforms read two ints instead >>>>> of a single 64bit long >>>>> firstHalf = UNSAFE.getInt(adr); >>>>> secondHalf = UNSAFE.getInt(adr + Integer.BYTES); >>>>> } else { >>>>> long value = UNSAFE.getLong(adr); >>>>> if (ByteOrder.nativeOrder() == >>>>> ByteOrder.LITTLE_ENDIAN) { >>>>> firstHalf = (int) value; >>>>> secondHalf = (int) (value >>> 32); >>>>> } else { // ByteOrder.BIG_ENDIAN >>>>> firstHalf = (int) (value >>> 32); >>>>> secondHalf = (int) value; >>>>> } >>>>> } >>>>> crc ^= firstHalf; >>>>> if (ByteOrder.nativeOrder() == >>>>> ByteOrder.LITTLE_ENDIAN) { >>>>> crc = byteTable7[crc & 0xFF] >>>>> ^ byteTable6[(crc >>> 8) & 0xFF] >>>>> ^ byteTable5[(crc >>> 16) & 0xFF] >>>>> ^ byteTable4[crc >>> 24] >>>>> ^ byteTable3[secondHalf & 0xFF] >>>>> ^ byteTable2[(secondHalf >>> 8) & 0xFF] >>>>> ^ byteTable1[(secondHalf >>> 16) & 0xFF] >>>>> ^ byteTable0[secondHalf >>> 24]; >>>>> } else { // ByteOrder.BIG_ENDIAN >>>>> crc = byteTable0[secondHalf & 0xFF] >>>>> ^ byteTable1[(secondHalf >>> 8) & 0xFF] >>>>> ^ byteTable2[(secondHalf >>> 16) & 0xFF] >>>>> ^ byteTable3[secondHalf >>> 24] >>>>> ^ byteTable4[crc & 0xFF] >>>>> ^ byteTable5[(crc >>> 8) & 0xFF] >>>>> ^ byteTable6[(crc >>> 16) & 0xFF] >>>>> ^ byteTable7[crc >>> 24]; >>>>> } >>>>> } >>>>> >>>>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>>>> crc = Integer.reverseBytes(crc); >>>>> } >>>>> } >>>>> >>>>> // Tail >>>>> for (; adr < end; adr++) { >>>>> crc = (crc >>> 8) >>>>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >>>>> } >>>>> >>>>> return crc; >>>>> } >>>>> >>>>> >>>>>> >>>>>> Also, in updateBytes, the usage of >>>>>> Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a >>>>>> byte array sounds a little scary. To be ultra portable you could >>>>>> check that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use >>>>>> Unsafe for byte arrays if it is not 1. Then use >>>>>> Integer.BYTES/Long.BYTES to manipulate 'offsets' instead. In >>>>>> updateDirectByteBuffer it would be more appropriate to use >>>>>> Integer.BYTES/Long.BYTES too. >>>>> Good idea. Added a check in the initial if statement and it will >>>>> get automatically optimized away. >>>>> >>>>>> 225 firstHalf = (int) (value & 0xFFFFFFFF); >>>>>> 226 secondHalf = (int) (value >>> 32); >>>>>> 227 } else { // ByteOrder.BIG_ENDIAN >>>>>> 228 firstHalf = (int) (value >>> 32); >>>>>> 229 secondHalf = (int) (value & >>>>>> 0xFFFFFFFF); >>>>>> >>>>>> firstHalf = (int) value; // this is equivalent for line 225 >>>>>> secondHalf = (int) value; // this is equivalent for line 229 >>>>> Done. >>>>> >>>>> Here is the latest webrev, >>>>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>>>> >>>>> Cheers, >>>>> Staffan >>>> >>> >> > From david.holmes at oracle.com Wed Oct 22 02:23:46 2014 From: david.holmes at oracle.com (David Holmes) Date: Wed, 22 Oct 2014 12:23:46 +1000 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <544662EB.2040907@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> <544662EB.2040907@oracle.com> Message-ID: <54471532.10109@oracle.com> Hi Claes, In the test you should use the ProcessTools from the testlibrary not mess with System.getProperty("java.home") and create your own processes directly. The test should not require a full JDK to run, but should execute on a JRE or any compact profile. Thanks, David On 21/10/2014 11:43 PM, Claes Redestad wrote: > Hi Mandy, > > thanks for the review! > > On 10/15/2014 03:07 AM, Mandy Chung wrote: >> Claes, Peter, >> >> Thanks for the revised webrev and Peter's thorough review. webrev.05 >> looks much better. My comment is mostly minor. >> >> >> ClassLoader.java >> >> line 1582-1586 - I suggest to get rid of the "oldpkg" variable >> (it's really the package to be used and not an old pkg). >> >> pkg = new Package(name, specTitle, specVersion, specVendor, >> implTitle, implVersion, implVendor, >> sealBase, this); >> if (packages.putIfAbsent(name, pkg) != null) { >> throw new IllegalArgumentException(name + " already defined"); >> } >> return pkg; >> >> line 1634-1635: nit: the pkgName variable is not really needed. >> it's in the existing code and probably good to remove it. >> Package.java >> >> line 473: maybe better to leave the ClassLoader parameter in the >> constructor. >> I thought about adding a comment saying that this private constructor >> is only used for system package but keeping the loader parameter makes >> it more explicit. >> >> line 569: nit: formatting - indent to the right to align the first >> parameter >> to new Package(...) > > Fixed. > >> >> line 621-623: is this really needed? Uncontended case seems to be >> the common case. It seems the synchronized overhead would be >> insignificant. > > I'd prefer sticking to the double-checked idiom here, unless you insist. > > I've cleaned up the code to avoid assignment in if-clauses, which > according to > anonymous sources makes the code more readable. Perhaps this addresses > some of your concerns? > >> >> line 624: a space is missing between synchronized and "(" > > Fixed. > >> >> Looks like there is one test >> jdk/test/java/lang/ClassLoader/GetPackage.java >> about packages. Can you add a new test to verify the system packages >> as that >> is one major change in your patch? > > http://cr.openjdk.java.net/~redestad/8060130/webrev.06 > > Since I don't want to add binary JAR files, I opted to add a test which > creates two JAR files, > each with a single class (with/without manifest) and then proceeds to > spawn processes > to verify that: > > - when the JAR with manifest is on bootclasspath, the package can be > found via > Package.getSystemPackage and the package object reflects values added to > the manifest > - when the JAR without manifest is on bootclaspath, the package can be > found via > Package.getSystemPackage but is empty apart from name > - adding the test.classes directory to bootclasspath behaves the same as > adding the JAR > without manifest > - for any case where the class/package is not on the bootclasspath, the > package information > can not be found via Package.getSystemPackage(). > > Does this cover everything? > > I guess there might be a way to make @run main/othervm or > main/bootclasspath pick > up a dynamically generated JAR file, but I've failed to find a way that > would make this work without > pregenerating the JARs. Suggestions on how this can be simplified are > welcome. > > /Claes > >> >> Thanks >> Mandy >> From peter.levart at gmail.com Wed Oct 22 05:56:47 2014 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 22 Oct 2014 07:56:47 +0200 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5446D17F.3060906@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <5446AAB0.3090304@oracle.com> <5446C25A.1050109@gmail.com> <5446C625.6090804@gmail.com> <5446D17F.3060906@oracle.com> Message-ID: <5447471F.3000309@gmail.com> On 10/21/2014 11:34 PM, Staffan Friberg wrote: > I believe it must be <, as it is in the tail loop as well, because end > is (off+len or limit) so end is exclusive, similar to > subString(begin,end). > > Makes sense? > > //Staffan > > On 10/21/2014 01:46 PM, Peter Levart wrote: >> Sorry Staffan, another nit... >> >> 212 for (; off < (end - Long.BYTES); off += Long.BYTES) { >> and >> >> 286 for (; off < (end - Long.BYTES); off += Long.BYTES) { >> >> >> I think you could change "off < (end - Long.BYTES)" to "off <= (end - >> Long.BYTES)". Am I right? The tail loop has < : 319 for (; off < end; off++) { ...but it could be written as: for (; off <= (end - Byte.BYTES); off += Byte.BYTES) { ... ;-) In other words, when off == end - Long.BYTES, you can still read Long.BYTES starting at 'off' . Regards, Peter >> >> Regards, Peter >> >> >> On 10/21/2014 10:30 PM, Peter Levart wrote: >>> >>> On 10/21/2014 08:49 PM, Staffan Friberg wrote: >>>> Hi, >>>> >>>> Got an offline comment that the package.html should be update as >>>> well to cover CRC-32C. >>>> >>>> Otherwise there are no code changes in this new webrev. >>>> >>>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.04 >>> >>> >>> Hi Staffan, >>> >>> 198 if (end - off >= 8 && Unsafe.ARRAY_BOOLEAN_INDEX_SCALE >>> == 1) { >>> >>> ARRAY_BOOLEAN_INDEX_SCALE -> ARRAY_BYTE_INDEX_SCALE >>> >>> >>> Otherwise looks good now. >>> >>> Regards, Peter >>> >>> P.S. >>> >>> I think (by looking at DirectByteBuffer.asIntBuffer() >>> implementation) that when doing 32 bit (4 byte) reads using Unsafe, >>> the address only has to be aligned to 4 bytes (8 is necessary >>> alignment for 64 bit reads). So updateDirectByteBuffer could make >>> this alignment on 4 bytes as it's only using 32 bit reads (with >>> additional check on ADDRESS_SIZE, you could do that for updateBytes >>> too). >>> >>> You don't get much out of it, so you decide if it's worth complication. >>> >>> >>>> >>>> //Staffan >>>> >>>> On 10/21/2014 10:28 AM, Staffan Friberg wrote: >>>>> Hi Peter, >>>>> >>>>> Thanks for the comments.. >>>>>> >>>>>> 217 if (Unsafe.ADDRESS_SIZE == 4) { >>>>>> 218 // On 32 bit platforms read two ints >>>>>> instead of a single 64bit long >>>>>> >>>>>> When you're reading from byte[] using Unsafe (updateBytes), you >>>>>> have the option of reading 64bit values on 64bit platforms. When >>>>>> you're reading from DirectByteBuffer memory >>>>>> (updateDirectByteBuffer), you're only using 32bit reads. >>>>> I will add a comment in the code for this decision. The reason is >>>>> that read a long results in slightly worse performance in this >>>>> case, in updateBytes it is faster. I was able to get it to run >>>>> slightly faster by working directly with the address instead of >>>>> always adding address + off, but this makes things worse in the >>>>> 32bit case since all calculation will now be using long variables. >>>>> So using the getInt as in the current code feels like the best >>>>> solution as it strikes the best balance between 32 and 64bit. >>>>> Below is how updateByteBuffer looked with the rewrite I mentioned. >>>>> >>>>> >>>>> ong address = ((DirectBuffer) buffer).address(); >>>>> crc = updateDirectByteBuffer(crc, address + pos, address + limit); >>>>> >>>>> >>>>> private static int updateDirectByteBuffer(int crc, long adr, >>>>> long end) { >>>>> >>>>> // Do only byte reads for arrays so short they can't be >>>>> aligned >>>>> if (end - adr >= 8) { >>>>> >>>>> // align on 8 bytes >>>>> int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >>>>> for (long alignEnd = adr + alignLength; adr < >>>>> alignEnd; adr++) { >>>>> crc = (crc >>> 8) >>>>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & >>>>> 0xFF]; >>>>> } >>>>> >>>>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>>>> crc = Integer.reverseBytes(crc); >>>>> } >>>>> >>>>> // slicing-by-8 >>>>> for (; adr < (end - Long.BYTES); adr += Long.BYTES) { >>>>> int firstHalf; >>>>> int secondHalf; >>>>> if (Unsafe.ADDRESS_SIZE == 4) { >>>>> // On 32 bit platforms read two ints instead >>>>> of a single 64bit long >>>>> firstHalf = UNSAFE.getInt(adr); >>>>> secondHalf = UNSAFE.getInt(adr + Integer.BYTES); >>>>> } else { >>>>> long value = UNSAFE.getLong(adr); >>>>> if (ByteOrder.nativeOrder() == >>>>> ByteOrder.LITTLE_ENDIAN) { >>>>> firstHalf = (int) value; >>>>> secondHalf = (int) (value >>> 32); >>>>> } else { // ByteOrder.BIG_ENDIAN >>>>> firstHalf = (int) (value >>> 32); >>>>> secondHalf = (int) value; >>>>> } >>>>> } >>>>> crc ^= firstHalf; >>>>> if (ByteOrder.nativeOrder() == >>>>> ByteOrder.LITTLE_ENDIAN) { >>>>> crc = byteTable7[crc & 0xFF] >>>>> ^ byteTable6[(crc >>> 8) & 0xFF] >>>>> ^ byteTable5[(crc >>> 16) & 0xFF] >>>>> ^ byteTable4[crc >>> 24] >>>>> ^ byteTable3[secondHalf & 0xFF] >>>>> ^ byteTable2[(secondHalf >>> 8) & 0xFF] >>>>> ^ byteTable1[(secondHalf >>> 16) & 0xFF] >>>>> ^ byteTable0[secondHalf >>> 24]; >>>>> } else { // ByteOrder.BIG_ENDIAN >>>>> crc = byteTable0[secondHalf & 0xFF] >>>>> ^ byteTable1[(secondHalf >>> 8) & 0xFF] >>>>> ^ byteTable2[(secondHalf >>> 16) & 0xFF] >>>>> ^ byteTable3[secondHalf >>> 24] >>>>> ^ byteTable4[crc & 0xFF] >>>>> ^ byteTable5[(crc >>> 8) & 0xFF] >>>>> ^ byteTable6[(crc >>> 16) & 0xFF] >>>>> ^ byteTable7[crc >>> 24]; >>>>> } >>>>> } >>>>> >>>>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>>>> crc = Integer.reverseBytes(crc); >>>>> } >>>>> } >>>>> >>>>> // Tail >>>>> for (; adr < end; adr++) { >>>>> crc = (crc >>> 8) >>>>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >>>>> } >>>>> >>>>> return crc; >>>>> } >>>>> >>>>> >>>>>> >>>>>> Also, in updateBytes, the usage of >>>>>> Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a >>>>>> byte array sounds a little scary. To be ultra portable you could >>>>>> check that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use >>>>>> Unsafe for byte arrays if it is not 1. Then use >>>>>> Integer.BYTES/Long.BYTES to manipulate 'offsets' instead. In >>>>>> updateDirectByteBuffer it would be more appropriate to use >>>>>> Integer.BYTES/Long.BYTES too. >>>>> Good idea. Added a check in the initial if statement and it will >>>>> get automatically optimized away. >>>>> >>>>>> 225 firstHalf = (int) (value & 0xFFFFFFFF); >>>>>> 226 secondHalf = (int) (value >>> 32); >>>>>> 227 } else { // ByteOrder.BIG_ENDIAN >>>>>> 228 firstHalf = (int) (value >>> 32); >>>>>> 229 secondHalf = (int) (value & >>>>>> 0xFFFFFFFF); >>>>>> >>>>>> firstHalf = (int) value; // this is equivalent for line 225 >>>>>> secondHalf = (int) value; // this is equivalent for line 229 >>>>> Done. >>>>> >>>>> Here is the latest webrev, >>>>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>>>> >>>>> Cheers, >>>>> Staffan >>>> >>> >> > > From claes.redestad at oracle.com Wed Oct 22 12:40:38 2014 From: claes.redestad at oracle.com (Claes Redestad) Date: Wed, 22 Oct 2014 14:40:38 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <54471532.10109@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> <544662EB.2040907@oracle.com> <54471532.10109@oracle.com> Message-ID: <5447A5C6.60802@oracle.com> Thanks! Updated: http://cr.openjdk.java.net/~redestad/8060130/webrev.07/ On a related note, java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java is failing when I run make TEST=jdk_lang test from jdk9-dev, and it seems to be due to the test expecting java.home to be set to a JRE dir inside a JDK. I na?vely copied my first approach from how sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java discovers the jar binary. Both these tests seems flawed and should use jdk.testlibrary.JDKToolFinder.getJDKTool("jar"), no? /Claes On 10/22/2014 04:23 AM, David Holmes wrote: > Hi Claes, > > In the test you should use the ProcessTools from the testlibrary not > mess with System.getProperty("java.home") and create your own > processes directly. The test should not require a full JDK to run, but > should execute on a JRE or any compact profile. > > Thanks, > David > > On 21/10/2014 11:43 PM, Claes Redestad wrote: >> Hi Mandy, >> >> thanks for the review! >> >> On 10/15/2014 03:07 AM, Mandy Chung wrote: >>> Claes, Peter, >>> >>> Thanks for the revised webrev and Peter's thorough review. webrev.05 >>> looks much better. My comment is mostly minor. >>> >>> >>> ClassLoader.java >>> >>> line 1582-1586 - I suggest to get rid of the "oldpkg" variable >>> (it's really the package to be used and not an old pkg). >>> >>> pkg = new Package(name, specTitle, specVersion, specVendor, >>> implTitle, implVersion, implVendor, >>> sealBase, this); >>> if (packages.putIfAbsent(name, pkg) != null) { >>> throw new IllegalArgumentException(name + " already defined"); >>> } >>> return pkg; >>> >>> line 1634-1635: nit: the pkgName variable is not really needed. >>> it's in the existing code and probably good to remove it. >>> Package.java >>> >>> line 473: maybe better to leave the ClassLoader parameter in the >>> constructor. >>> I thought about adding a comment saying that this private >>> constructor >>> is only used for system package but keeping the loader parameter >>> makes >>> it more explicit. >>> >>> line 569: nit: formatting - indent to the right to align the first >>> parameter >>> to new Package(...) >> >> Fixed. >> >>> >>> line 621-623: is this really needed? Uncontended case seems to be >>> the common case. It seems the synchronized overhead would be >>> insignificant. >> >> I'd prefer sticking to the double-checked idiom here, unless you insist. >> >> I've cleaned up the code to avoid assignment in if-clauses, which >> according to >> anonymous sources makes the code more readable. Perhaps this addresses >> some of your concerns? >> >>> >>> line 624: a space is missing between synchronized and "(" >> >> Fixed. >> >>> >>> Looks like there is one test >>> jdk/test/java/lang/ClassLoader/GetPackage.java >>> about packages. Can you add a new test to verify the system packages >>> as that >>> is one major change in your patch? >> >> http://cr.openjdk.java.net/~redestad/8060130/webrev.06 >> >> Since I don't want to add binary JAR files, I opted to add a test which >> creates two JAR files, >> each with a single class (with/without manifest) and then proceeds to >> spawn processes >> to verify that: >> >> - when the JAR with manifest is on bootclasspath, the package can be >> found via >> Package.getSystemPackage and the package object reflects values added to >> the manifest >> - when the JAR without manifest is on bootclaspath, the package can be >> found via >> Package.getSystemPackage but is empty apart from name >> - adding the test.classes directory to bootclasspath behaves the same as >> adding the JAR >> without manifest >> - for any case where the class/package is not on the bootclasspath, the >> package information >> can not be found via Package.getSystemPackage(). >> >> Does this cover everything? >> >> I guess there might be a way to make @run main/othervm or >> main/bootclasspath pick >> up a dynamically generated JAR file, but I've failed to find a way that >> would make this work without >> pregenerating the JARs. Suggestions on how this can be simplified are >> welcome. >> >> /Claes >> >>> >>> Thanks >>> Mandy >>> From kumar.x.srinivasan at oracle.com Wed Oct 22 15:09:06 2014 From: kumar.x.srinivasan at oracle.com (Kumar Srinivasan) Date: Wed, 22 Oct 2014 08:09:06 -0700 Subject: RFR: 8061830: [asm] refresh internal ASM version v5.0.3 Message-ID: <5447C892.6040009@oracle.com> Hello, Please review fix for JDK-8061830, this is merely a refresh of the existing source base from upstream ObjectWeb/ASM, the webrev is here: http://cr.openjdk.java.net/~ksrini/8061830/webrev.00/ All the validations performed are documented in the JBS issue. Thanks Kumar From staffan.friberg at oracle.com Wed Oct 22 17:54:56 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Wed, 22 Oct 2014 10:54:56 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5447471F.3000309@gmail.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <5446AAB0.3090304@oracle.com> <5446C25A.1050109@gmail.com> <5446C625.6090804@gmail.com> <5446D17F.3060906@oracle.com> <5447471F.3000309@gmail.com> Message-ID: <5447EF70.4030906@oracle.com> You're right, managed to convince myself here as well. Will change it to <=. An unfortunate side-effect seems to be that in a benchmark with 1024 long array it seems like the performance drops when the tail loop is not utilized. As you can see below there is a slight drop when the data is perfectly aligned in the array causing neither alignment or tail loop to be utilized. Not going to dig into why right now, but an interesting effect. @Benchmark @OperationsPerInvocation(1024) public void byteArray_1K() { checksum.update(unalignedByteArray_1k, offset, 1024); } Benchmark (offset) Mode Samples Score Score error Units o.c.CRC32CUnaligned.byteArray_1K 0 thrpt 5 983198.048 654.467 ops/ms o.c.CRC32CUnaligned.byteArray_1K 1 thrpt 5 1013136.714 3801.537 ops/ms o.c.CRC32CUnaligned.byteArray_1K 2 thrpt 5 1006899.265 10998.612 ops/ms o.c.CRC32CUnaligned.byteArray_1K 3 thrpt 5 1014419.366 3745.875 ops/ms o.c.CRC32CUnaligned.byteArray_1K 4 thrpt 5 1007777.937 1585.989 ops/ms o.c.CRC32CUnaligned.byteArray_1K 5 thrpt 5 1011249.564 852.333 ops/ms o.c.CRC32CUnaligned.byteArray_1K 6 thrpt 5 1013622.327 4075.303 ops/ms o.c.CRC32CUnaligned.byteArray_1K 7 thrpt 5 1008137.616 1672.262 ops/ms o.c.CRC32CUnaligned.byteArray_1K 8 thrpt 5 985838.295 448.735 ops/ms o.c.CRC32CUnaligned.byteArray_1K 9 thrpt 5 1005935.356 4250.381 ops/ms o.c.CRC32CUnaligned.byteArray_1K 10 thrpt 5 995912.149 2447.272 ops/ms With just using < then the performance is equal across all alignments. Benchmark (offset) Mode Samples Score Score error Units o.c.CRC32CUnaligned.byteArray_1K 0 thrpt 5 1003094.419 2656.518 ops/ms o.c.CRC32CUnaligned.byteArray_1K 1 thrpt 5 1009641.996 2519.614 ops/ms o.c.CRC32CUnaligned.byteArray_1K 2 thrpt 5 1009169.464 12987.786 ops/ms o.c.CRC32CUnaligned.byteArray_1K 3 thrpt 5 1006869.144 1617.988 ops/ms o.c.CRC32CUnaligned.byteArray_1K 4 thrpt 5 1005490.644 1234.283 ops/ms o.c.CRC32CUnaligned.byteArray_1K 5 thrpt 5 1007468.090 327.541 ops/ms o.c.CRC32CUnaligned.byteArray_1K 6 thrpt 5 1014316.244 1174.920 ops/ms o.c.CRC32CUnaligned.byteArray_1K 7 thrpt 5 1008378.002 1440.734 ops/ms o.c.CRC32CUnaligned.byteArray_1K 8 thrpt 5 1003253.408 10786.210 ops/ms o.c.CRC32CUnaligned.byteArray_1K 9 thrpt 5 1000950.362 250.617 ops/ms o.c.CRC32CUnaligned.byteArray_1K 10 thrpt 5 1003783.897 11333.132 ops/ms //Staffan On 10/21/2014 10:56 PM, Peter Levart wrote: > On 10/21/2014 11:34 PM, Staffan Friberg wrote: >> I believe it must be <, as it is in the tail loop as well, because >> end is (off+len or limit) so end is exclusive, similar to >> subString(begin,end). >> >> Makes sense? >> >> //Staffan >> >> On 10/21/2014 01:46 PM, Peter Levart wrote: >>> Sorry Staffan, another nit... >>> >>> 212 for (; off < (end - Long.BYTES); off += Long.BYTES) { >>> and >>> >>> 286 for (; off < (end - Long.BYTES); off += Long.BYTES) { >>> >>> >>> I think you could change "off < (end - Long.BYTES)" to "off <= (end >>> - Long.BYTES)". Am I right? > > The tail loop has < : > > 319 for (; off < end; off++) { > > > ...but it could be written as: > > > for (; off <= (end - Byte.BYTES); off += Byte.BYTES) { ... > > > ;-) > > In other words, when off == end - Long.BYTES, you can still read > Long.BYTES starting at 'off' . > > Regards, Peter > > >>> >>> Regards, Peter >>> >>> >>> On 10/21/2014 10:30 PM, Peter Levart wrote: >>>> >>>> On 10/21/2014 08:49 PM, Staffan Friberg wrote: >>>>> Hi, >>>>> >>>>> Got an offline comment that the package.html should be update as >>>>> well to cover CRC-32C. >>>>> >>>>> Otherwise there are no code changes in this new webrev. >>>>> >>>>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.04 >>>> >>>> >>>> Hi Staffan, >>>> >>>> 198 if (end - off >= 8 && >>>> Unsafe.ARRAY_BOOLEAN_INDEX_SCALE == 1) { >>>> >>>> ARRAY_BOOLEAN_INDEX_SCALE -> ARRAY_BYTE_INDEX_SCALE >>>> >>>> >>>> Otherwise looks good now. >>>> >>>> Regards, Peter >>>> >>>> P.S. >>>> >>>> I think (by looking at DirectByteBuffer.asIntBuffer() >>>> implementation) that when doing 32 bit (4 byte) reads using Unsafe, >>>> the address only has to be aligned to 4 bytes (8 is necessary >>>> alignment for 64 bit reads). So updateDirectByteBuffer could make >>>> this alignment on 4 bytes as it's only using 32 bit reads (with >>>> additional check on ADDRESS_SIZE, you could do that for updateBytes >>>> too). >>>> >>>> You don't get much out of it, so you decide if it's worth >>>> complication. >>>> >>>> >>>>> >>>>> //Staffan >>>>> >>>>> On 10/21/2014 10:28 AM, Staffan Friberg wrote: >>>>>> Hi Peter, >>>>>> >>>>>> Thanks for the comments.. >>>>>>> >>>>>>> 217 if (Unsafe.ADDRESS_SIZE == 4) { >>>>>>> 218 // On 32 bit platforms read two ints >>>>>>> instead of a single 64bit long >>>>>>> >>>>>>> When you're reading from byte[] using Unsafe (updateBytes), you >>>>>>> have the option of reading 64bit values on 64bit platforms. When >>>>>>> you're reading from DirectByteBuffer memory >>>>>>> (updateDirectByteBuffer), you're only using 32bit reads. >>>>>> I will add a comment in the code for this decision. The reason is >>>>>> that read a long results in slightly worse performance in this >>>>>> case, in updateBytes it is faster. I was able to get it to run >>>>>> slightly faster by working directly with the address instead of >>>>>> always adding address + off, but this makes things worse in the >>>>>> 32bit case since all calculation will now be using long >>>>>> variables. So using the getInt as in the current code feels like >>>>>> the best solution as it strikes the best balance between 32 and >>>>>> 64bit. Below is how updateByteBuffer looked with the rewrite I >>>>>> mentioned. >>>>>> >>>>>> >>>>>> ong address = ((DirectBuffer) buffer).address(); >>>>>> crc = updateDirectByteBuffer(crc, address + pos, address + limit); >>>>>> >>>>>> >>>>>> private static int updateDirectByteBuffer(int crc, long adr, >>>>>> long end) { >>>>>> >>>>>> // Do only byte reads for arrays so short they can't be >>>>>> aligned >>>>>> if (end - adr >= 8) { >>>>>> >>>>>> // align on 8 bytes >>>>>> int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >>>>>> for (long alignEnd = adr + alignLength; adr < >>>>>> alignEnd; adr++) { >>>>>> crc = (crc >>> 8) >>>>>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & >>>>>> 0xFF]; >>>>>> } >>>>>> >>>>>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>>>>> crc = Integer.reverseBytes(crc); >>>>>> } >>>>>> >>>>>> // slicing-by-8 >>>>>> for (; adr < (end - Long.BYTES); adr += Long.BYTES) { >>>>>> int firstHalf; >>>>>> int secondHalf; >>>>>> if (Unsafe.ADDRESS_SIZE == 4) { >>>>>> // On 32 bit platforms read two ints instead >>>>>> of a single 64bit long >>>>>> firstHalf = UNSAFE.getInt(adr); >>>>>> secondHalf = UNSAFE.getInt(adr + Integer.BYTES); >>>>>> } else { >>>>>> long value = UNSAFE.getLong(adr); >>>>>> if (ByteOrder.nativeOrder() == >>>>>> ByteOrder.LITTLE_ENDIAN) { >>>>>> firstHalf = (int) value; >>>>>> secondHalf = (int) (value >>> 32); >>>>>> } else { // ByteOrder.BIG_ENDIAN >>>>>> firstHalf = (int) (value >>> 32); >>>>>> secondHalf = (int) value; >>>>>> } >>>>>> } >>>>>> crc ^= firstHalf; >>>>>> if (ByteOrder.nativeOrder() == >>>>>> ByteOrder.LITTLE_ENDIAN) { >>>>>> crc = byteTable7[crc & 0xFF] >>>>>> ^ byteTable6[(crc >>> 8) & 0xFF] >>>>>> ^ byteTable5[(crc >>> 16) & 0xFF] >>>>>> ^ byteTable4[crc >>> 24] >>>>>> ^ byteTable3[secondHalf & 0xFF] >>>>>> ^ byteTable2[(secondHalf >>> 8) & 0xFF] >>>>>> ^ byteTable1[(secondHalf >>> 16) & 0xFF] >>>>>> ^ byteTable0[secondHalf >>> 24]; >>>>>> } else { // ByteOrder.BIG_ENDIAN >>>>>> crc = byteTable0[secondHalf & 0xFF] >>>>>> ^ byteTable1[(secondHalf >>> 8) & 0xFF] >>>>>> ^ byteTable2[(secondHalf >>> 16) & 0xFF] >>>>>> ^ byteTable3[secondHalf >>> 24] >>>>>> ^ byteTable4[crc & 0xFF] >>>>>> ^ byteTable5[(crc >>> 8) & 0xFF] >>>>>> ^ byteTable6[(crc >>> 16) & 0xFF] >>>>>> ^ byteTable7[crc >>> 24]; >>>>>> } >>>>>> } >>>>>> >>>>>> if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >>>>>> crc = Integer.reverseBytes(crc); >>>>>> } >>>>>> } >>>>>> >>>>>> // Tail >>>>>> for (; adr < end; adr++) { >>>>>> crc = (crc >>> 8) >>>>>> ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >>>>>> } >>>>>> >>>>>> return crc; >>>>>> } >>>>>> >>>>>> >>>>>>> >>>>>>> Also, in updateBytes, the usage of >>>>>>> Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a >>>>>>> byte array sounds a little scary. To be ultra portable you could >>>>>>> check that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use >>>>>>> Unsafe for byte arrays if it is not 1. Then use >>>>>>> Integer.BYTES/Long.BYTES to manipulate 'offsets' instead. In >>>>>>> updateDirectByteBuffer it would be more appropriate to use >>>>>>> Integer.BYTES/Long.BYTES too. >>>>>> Good idea. Added a check in the initial if statement and it will >>>>>> get automatically optimized away. >>>>>> >>>>>>> 225 firstHalf = (int) (value & 0xFFFFFFFF); >>>>>>> 226 secondHalf = (int) (value >>> 32); >>>>>>> 227 } else { // ByteOrder.BIG_ENDIAN >>>>>>> 228 firstHalf = (int) (value >>> 32); >>>>>>> 229 secondHalf = (int) (value & >>>>>>> 0xFFFFFFFF); >>>>>>> >>>>>>> firstHalf = (int) value; // this is equivalent for line 225 >>>>>>> secondHalf = (int) value; // this is equivalent for line 229 >>>>>> Done. >>>>>> >>>>>> Here is the latest webrev, >>>>>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>>>>> >>>>>> Cheers, >>>>>> Staffan >>>>> >>>> >>> >> >> > From ecki at zusammenkunft.net Wed Oct 22 21:10:25 2014 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Wed, 22 Oct 2014 23:10:25 +0200 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <544697D2.6080301@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> Message-ID: <20141022231025.00007607.ecki@zusammenkunft.net> Hello, just a question in the default impl: + } else { + byte[] b = new byte[rem]; + buffer.get(b); + update(b, 0, b.length); + } would it be a good idea to actually put a ceiling on the size of the array which is processed at once? Something below the typical G1 Humongous sinze or even something which keeps it in young (as those arrays are known to be recycled immediatelly). Gruss Bernd Am Tue, 21 Oct 2014 10:28:50 -0700 schrieb Staffan Friberg : > Hi Peter, > > Thanks for the comments.. > > > > 217 if (Unsafe.ADDRESS_SIZE == 4) { > > 218 // On 32 bit platforms read two ints > > instead of a single 64bit long > > > > When you're reading from byte[] using Unsafe (updateBytes), you > > have the option of reading 64bit values on 64bit platforms. When > > you're reading from DirectByteBuffer memory > > (updateDirectByteBuffer), you're only using 32bit reads. > I will add a comment in the code for this decision. The reason is > that read a long results in slightly worse performance in this case, > in updateBytes it is faster. I was able to get it to run slightly > faster by working directly with the address instead of always adding > address + off, but this makes things worse in the 32bit case since > all calculation will now be using long variables. So using the getInt > as in the current code feels like the best solution as it strikes the > best balance between 32 and 64bit. Below is how updateByteBuffer > looked with the rewrite I mentioned. > > > ong address = ((DirectBuffer) buffer).address(); > crc = updateDirectByteBuffer(crc, address + pos, address + limit); > > > private static int updateDirectByteBuffer(int crc, long adr, > long end) { > > // Do only byte reads for arrays so short they can't be > aligned if (end - adr >= 8) { > > // align on 8 bytes > int alignLength = (8 - (int) (adr & 0x7)) & 0x7; > for (long alignEnd = adr + alignLength; adr < alignEnd; > adr++) { crc = (crc >>> 8) > ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & > 0xFF]; } > > if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { > crc = Integer.reverseBytes(crc); > } > > // slicing-by-8 > for (; adr < (end - Long.BYTES); adr += Long.BYTES) { > int firstHalf; > int secondHalf; > if (Unsafe.ADDRESS_SIZE == 4) { > // On 32 bit platforms read two ints instead of > a single 64bit long firstHalf = UNSAFE.getInt(adr); > secondHalf = UNSAFE.getInt(adr + Integer.BYTES); > } else { > long value = UNSAFE.getLong(adr); > if (ByteOrder.nativeOrder() == > ByteOrder.LITTLE_ENDIAN) { firstHalf = (int) value; > secondHalf = (int) (value >>> 32); > } else { // ByteOrder.BIG_ENDIAN > firstHalf = (int) (value >>> 32); > secondHalf = (int) value; > } > } > crc ^= firstHalf; > if (ByteOrder.nativeOrder() == > ByteOrder.LITTLE_ENDIAN) { crc = byteTable7[crc & 0xFF] > ^ byteTable6[(crc >>> 8) & 0xFF] > ^ byteTable5[(crc >>> 16) & 0xFF] > ^ byteTable4[crc >>> 24] > ^ byteTable3[secondHalf & 0xFF] > ^ byteTable2[(secondHalf >>> 8) & 0xFF] > ^ byteTable1[(secondHalf >>> 16) & 0xFF] > ^ byteTable0[secondHalf >>> 24]; > } else { // ByteOrder.BIG_ENDIAN > crc = byteTable0[secondHalf & 0xFF] > ^ byteTable1[(secondHalf >>> 8) & 0xFF] > ^ byteTable2[(secondHalf >>> 16) & 0xFF] > ^ byteTable3[secondHalf >>> 24] > ^ byteTable4[crc & 0xFF] > ^ byteTable5[(crc >>> 8) & 0xFF] > ^ byteTable6[(crc >>> 16) & 0xFF] > ^ byteTable7[crc >>> 24]; > } > } > > if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { > crc = Integer.reverseBytes(crc); > } > } > > // Tail > for (; adr < end; adr++) { > crc = (crc >>> 8) > ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; > } > > return crc; > } > > > > > > Also, in updateBytes, the usage of > > Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a byte > > array sounds a little scary. To be ultra portable you could check > > that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use Unsafe for > > byte arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to > > manipulate 'offsets' instead. In updateDirectByteBuffer it would be > > more appropriate to use Integer.BYTES/Long.BYTES too. > Good idea. Added a check in the initial if statement and it will get > automatically optimized away. > > > 225 firstHalf = (int) (value & > > 0xFFFFFFFF); 226 secondHalf = (int) (value > > >>> 32); 227 } else { // ByteOrder.BIG_ENDIAN > > 228 firstHalf = (int) (value >>> 32); > > 229 secondHalf = (int) (value & > > 0xFFFFFFFF); > > > > firstHalf = (int) value; // this is equivalent for line 225 > > secondHalf = (int) value; // this is equivalent for line 229 > Done. > > Here is the latest webrev, > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 > > Cheers, > Staffan From mandy.chung at oracle.com Wed Oct 22 21:35:32 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 22 Oct 2014 14:35:32 -0700 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <544662EB.2040907@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> <544662EB.2040907@oracle.com> Message-ID: <54482324.3060306@oracle.com> On 10/21/2014 6:43 AM, Claes Redestad wrote: > > http://cr.openjdk.java.net/~redestad/8060130/webrev.07/ Looks good. A minor nit: Package.java line 636: it can return EMPTY_MANIFEST that will set manifest to non-null so that an invalid file would avoid opening the file every time getManifest is called (although this case rarely happens). line 639 can then be simplified. GetSystemPackage.java test This is great. Thanks for adding the test. Can you break the long lines such as the call to JarBuilder.addClassFile and runSubprocess. Have you run this on windows? I think you need to use File.separator rather than "/" in the -Xbootclasspath/p argument. This test uses a special class loader that delegates to null class loader only. Since you have the verification in place, it'd be good to also call Package.getPackage and Package.getPackages to verify that the same "package2" instance is returned. As a sanity check, you could check "java.lang" package must be present. In the verifyPackage, it throws Exception. You can simply throw RuntimeException that would avoid the need of the checked exception. Nit: line 35-37, 43-46 - no need to declare these import as java.lang.* are imported by default. Copyright year should be 2014. > > > I'd prefer sticking to the double-checked idiom here, unless you insist. > > I've cleaned up the code to avoid assignment in if-clauses, which > according to > anonymous sources makes the code more readable. Perhaps this addresses > some of your concerns? > Looks okay. Initialize manifest to EMPTY_MANIFEST would clean that a little. > > Since I don't want to add binary JAR files, I opted to add a test > which creates two JAR files, > each with a single class (with/without manifest) and then proceeds to > spawn processes > to verify that: > Thanks for adding the test. > - when the JAR with manifest is on bootclasspath, the package can be > found via > Package.getSystemPackage and the package object reflects values added > to the manifest > - when the JAR without manifest is on bootclaspath, the package can be > found via > Package.getSystemPackage but is empty apart from name > - adding the test.classes directory to bootclasspath behaves the same > as adding the JAR > without manifest > - for any case where the class/package is not on the bootclasspath, > the package information > can not be found via Package.getSystemPackage(). > > Does this cover everything? > This is great. See my comment above. > I guess there might be a way to make @run main/othervm or > main/bootclasspath pick > up a dynamically generated JAR file, but I've failed to find a way > that would make this work without > pregenerating the JARs. Suggestions on how this can be simplified are > welcome. > What you have is fine. The other way is to do it in a shell test that is not preferable as you would have to manage FS for different OSes etc. Mandy From mandy.chung at oracle.com Wed Oct 22 21:56:59 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 22 Oct 2014 14:56:59 -0700 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <20141021230858.00006471.ecki@zusammenkunft.net> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> <544662EB.2040907@oracle.com> <20141021230858.00006471.ecki@zusammenkunft.net> Message-ID: <5448282B.1010900@oracle.com> On 10/21/2014 2:08 PM, Bernd Eckenfels wrote: > Hello, > > one thing I wonder - in the old and in the new case there is nothing > in definePackage() guaring the parents from getting to know the new > package and causing a conflict (as the atomic insert is only on the > specific packages table. Are those (parent and system package) > immutable? > Each class loader maintains its own package map. I guess your question is related to my comment about two class loaders can define classes in a package of the same name (two different runtime packages). ClassLoader.getPackage(s) assumes there is only one Package for each name in the class loader chain which seems wrong to me. Claes has filed a bug to track this: https://bugs.openjdk.java.net/browse/JDK-8061804 Mandy [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-October/029146.html From stanimir at riflexo.com Wed Oct 22 22:04:54 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Thu, 23 Oct 2014 01:04:54 +0300 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <20141022231025.00007607.ecki@zusammenkunft.net> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <20141022231025.00007607.ecki@zusammenkunft.net> Message-ID: On Thu, Oct 23, 2014 at 12:10 AM, Bernd Eckenfels wrote: > Hello, > > just a question in the default impl: > > + } else { > + byte[] b = new byte[rem]; > + buffer.get(b); > + update(b, 0, b.length); > + } > > would it be a good idea to actually put a ceiling on the size of the > array which is processed at once? This is an excellent catch. Should not be too large, probably 4k or so. Stanimir > Am Tue, 21 Oct 2014 10:28:50 -0700 > schrieb Staffan Friberg : > > > Hi Peter, > > > > Thanks for the comments.. > > > > > > 217 if (Unsafe.ADDRESS_SIZE == 4) { > > > 218 // On 32 bit platforms read two ints > > > instead of a single 64bit long > > > > > > When you're reading from byte[] using Unsafe (updateBytes), you > > > have the option of reading 64bit values on 64bit platforms. When > > > you're reading from DirectByteBuffer memory > > > (updateDirectByteBuffer), you're only using 32bit reads. > > I will add a comment in the code for this decision. The reason is > > that read a long results in slightly worse performance in this case, > > in updateBytes it is faster. I was able to get it to run slightly > > faster by working directly with the address instead of always adding > > address + off, but this makes things worse in the 32bit case since > > all calculation will now be using long variables. So using the getInt > > as in the current code feels like the best solution as it strikes the > > best balance between 32 and 64bit. Below is how updateByteBuffer > > looked with the rewrite I mentioned. > > > > > > ong address = ((DirectBuffer) buffer).address(); > > crc = updateDirectByteBuffer(crc, address + pos, address + limit); > > > > > > private static int updateDirectByteBuffer(int crc, long adr, > > long end) { > > > > // Do only byte reads for arrays so short they can't be > > aligned if (end - adr >= 8) { > > > > // align on 8 bytes > > int alignLength = (8 - (int) (adr & 0x7)) & 0x7; > > for (long alignEnd = adr + alignLength; adr < alignEnd; > > adr++) { crc = (crc >>> 8) > > ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & > > 0xFF]; } > > > > if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { > > crc = Integer.reverseBytes(crc); > > } > > > > // slicing-by-8 > > for (; adr < (end - Long.BYTES); adr += Long.BYTES) { > > int firstHalf; > > int secondHalf; > > if (Unsafe.ADDRESS_SIZE == 4) { > > // On 32 bit platforms read two ints instead of > > a single 64bit long firstHalf = UNSAFE.getInt(adr); > > secondHalf = UNSAFE.getInt(adr + Integer.BYTES); > > } else { > > long value = UNSAFE.getLong(adr); > > if (ByteOrder.nativeOrder() == > > ByteOrder.LITTLE_ENDIAN) { firstHalf = (int) value; > > secondHalf = (int) (value >>> 32); > > } else { // ByteOrder.BIG_ENDIAN > > firstHalf = (int) (value >>> 32); > > secondHalf = (int) value; > > } > > } > > crc ^= firstHalf; > > if (ByteOrder.nativeOrder() == > > ByteOrder.LITTLE_ENDIAN) { crc = byteTable7[crc & 0xFF] > > ^ byteTable6[(crc >>> 8) & 0xFF] > > ^ byteTable5[(crc >>> 16) & 0xFF] > > ^ byteTable4[crc >>> 24] > > ^ byteTable3[secondHalf & 0xFF] > > ^ byteTable2[(secondHalf >>> 8) & 0xFF] > > ^ byteTable1[(secondHalf >>> 16) & 0xFF] > > ^ byteTable0[secondHalf >>> 24]; > > } else { // ByteOrder.BIG_ENDIAN > > crc = byteTable0[secondHalf & 0xFF] > > ^ byteTable1[(secondHalf >>> 8) & 0xFF] > > ^ byteTable2[(secondHalf >>> 16) & 0xFF] > > ^ byteTable3[secondHalf >>> 24] > > ^ byteTable4[crc & 0xFF] > > ^ byteTable5[(crc >>> 8) & 0xFF] > > ^ byteTable6[(crc >>> 16) & 0xFF] > > ^ byteTable7[crc >>> 24]; > > } > > } > > > > if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { > > crc = Integer.reverseBytes(crc); > > } > > } > > > > // Tail > > for (; adr < end; adr++) { > > crc = (crc >>> 8) > > ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; > > } > > > > return crc; > > } > > > > > > > > > > Also, in updateBytes, the usage of > > > Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a byte > > > array sounds a little scary. To be ultra portable you could check > > > that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use Unsafe for > > > byte arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to > > > manipulate 'offsets' instead. In updateDirectByteBuffer it would be > > > more appropriate to use Integer.BYTES/Long.BYTES too. > > Good idea. Added a check in the initial if statement and it will get > > automatically optimized away. > > > > > 225 firstHalf = (int) (value & > > > 0xFFFFFFFF); 226 secondHalf = (int) (value > > > >>> 32); 227 } else { // ByteOrder.BIG_ENDIAN > > > 228 firstHalf = (int) (value >>> 32); > > > 229 secondHalf = (int) (value & > > > 0xFFFFFFFF); > > > > > > firstHalf = (int) value; // this is equivalent for line 225 > > > secondHalf = (int) value; // this is equivalent for line 229 > > Done. > > > > Here is the latest webrev, > > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 > > > > Cheers, > > Staffan > > From mandy.chung at oracle.com Wed Oct 22 22:42:22 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 22 Oct 2014 15:42:22 -0700 Subject: RFR: 8061244 Use of stack-less ClassNotFoundException thrown from (URL)ClassLoader.findClass() In-Reply-To: <54463760.6090809@gmail.com> References: <543EF592.3030409@gmail.com> <543F754B.4020001@gmail.com> <543F8558.2030401@gmail.com> <543FD0A6.3080207@gmail.com> <54463760.6090809@gmail.com> Message-ID: <544832CE.4020203@oracle.com> Hi Peter, On 10/21/2014 3:37 AM, Peter Levart wrote: > http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.03/ I skimmed through this webrev. I would suggest to hold off this patch and there are various ideas of the optimization for class loading performance with modules. Throwing CNFE attributes to one part of the class loading cost that hasn't proven to be significant in real-world applications. Recently I have instrumented the class loading code to add more fine-grained performance counters to determine the overhead of CNFE with and without stacktrace and again the applications I used to measure shows the CNFE stack trace isn't the focus. A class lookup cost would depend on the class loader hierarchy, the search path of each class loader and what classes are being looked up from a class loader. The cost of looking up a class local in the class loader's search path involves the parent delegation lookup time + CNFE + findClass (lookup class in its local search path). In a typical real-world application, the parent delegation lookup time would be much significant than CNFE. CNFE is thrown by loadClass for class lookup that is one typical suspect for class loading performance issue. On the other hand, resource lookup actually has the parent delegation performance cost in which CNFE is not involved. With modules, this would give the opportunity to consider skipping parent delegation, direct class lookup when the class is known to be local. That'd avoid CNFE creation completely. Talking about exceptions and fillInStackTrace, it's known to be significant cost. It'd be interesting to have the VM flag that can measure the time it spends in filling in the backtrace of each exception type (and perhaps the mean and max stack depth) that will give a better idea of the performance distribution. In addition, doPrivileged wraps checked exception with PrivilegedActionException that essentially has the same stack trace and it doubles the cost even in the absence of security manager. I have exchanged some mail with the security team to see if this is a low-hanging fruit to improve the performance. Mandy From martinrb at google.com Wed Oct 22 22:53:13 2014 From: martinrb at google.com (Martin Buchholz) Date: Wed, 22 Oct 2014 15:53:13 -0700 Subject: Loading classes with many methods is very expensive Message-ID: Here at Google we have both kinds of scalability problems - loading classes from a classpath with 10,000 jars, and loading a single class file packed with the maximal number of methods. This message is about the latter. If you have a class with ~64k methods with a superclass that also has ~64k methods, class loading that single class will cost you ~30sec and calling Class.getMethods another ~10sec. Both are unacceptably slow. I think both are due to O(N^2) algorithms, the first in hotspot, and the second in Class.java. I have the start of a fix for Class.java, but it makes the common case slower. A really good fix is harder to find. In general, I think Class.java could benefit from some performance-oriented rework. Is anyone else working on class loading performance, especially in hotspot? Here's the benchmark (that could perhaps be integrated into openjdk even without a fix) http://cr.openjdk.java.net/~martin/webrevs/openjdk9/Class.getMethods-benchmark/test/java/lang/Class/getMethods/ManyMethodsBenchmark.java.html Base class load time: 186.44 ms getDeclaredMethods: Methods: 65521, Total time: 43.27 ms, Time per method: 0.0007 ms getMethods : Methods: 65530, Total time: 60.82 ms, Time per method: 0.0009 ms Derived class load time: 33440.13 ms getDeclaredMethods: Methods: 65521, Total time: 39.71 ms, Time per method: 0.0006 ms getMethods : Methods: 65530, Total time: 11582.54 ms, Time per method: 0.1768 ms From stanimir at riflexo.com Wed Oct 22 23:57:30 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Thu, 23 Oct 2014 02:57:30 +0300 Subject: Loading classes with many methods is very expensive In-Reply-To: References: Message-ID: Class.java can easily be improved by adding an auxiliary HasMap indexing the position in the array by name and then checking only few overloaded signatures in case of a match. The auxiliary map can be deployed only past some threshold of methods, so it should not affect the common case. Alternatively sorting the array and using binary search is quite trivial to implement as well. Btw, really nice benchmark. Stanimir On Thu, Oct 23, 2014 at 1:53 AM, Martin Buchholz wrote: > Here at Google we have both kinds of scalability problems - loading classes > from a classpath with 10,000 jars, and loading a single class file packed > with the maximal number of methods. This message is about the latter. > > If you have a class with ~64k methods with a superclass that also has ~64k > methods, class loading that single class will cost you ~30sec and calling > Class.getMethods another ~10sec. Both are unacceptably slow. I think both > are due to O(N^2) algorithms, the first in hotspot, and the second in > Class.java. > > I have the start of a fix for Class.java, but it makes the common case > slower. A really good fix is harder to find. In general, I think > Class.java could benefit from some performance-oriented rework. Is anyone > else working on class loading performance, especially in hotspot? > > Here's the benchmark (that could perhaps be integrated into openjdk even > without a fix) > > > http://cr.openjdk.java.net/~martin/webrevs/openjdk9/Class.getMethods-benchmark/test/java/lang/Class/getMethods/ManyMethodsBenchmark.java.html > > Base class load time: 186.44 ms > getDeclaredMethods: Methods: 65521, Total time: 43.27 ms, Time per method: > 0.0007 ms > getMethods : Methods: 65530, Total time: 60.82 ms, Time per method: > 0.0009 ms > Derived class load time: 33440.13 ms > getDeclaredMethods: Methods: 65521, Total time: 39.71 ms, Time per method: > 0.0006 ms > getMethods : Methods: 65530, Total time: 11582.54 ms, Time per > method: 0.1768 ms > From claes.redestad at oracle.com Wed Oct 22 23:58:15 2014 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 23 Oct 2014 01:58:15 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <54482324.3060306@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> <544662EB.2040907@oracle.com> <54482324.3060306@oracle.com> Message-ID: <54484497.3090705@oracle.com> On 2014-10-22 23:35, Mandy Chung wrote: > > On 10/21/2014 6:43 AM, Claes Redestad wrote: >> >> http://cr.openjdk.java.net/~redestad/8060130/webrev.07/ > > Looks good. Thanks! > > A minor nit: Package.java line 636: it can return EMPTY_MANIFEST > that will set manifest to non-null so that an invalid file would avoid > opening the file every time getManifest is called (although this case > rarely happens). line 639 can then be simplified. We need to consider the case where JarInputStream.getManifest() returns null, which would mean we'd either end up no simpler on line 639 or simply adding a similar check around the value returned from jis.getManifest(). I also think I saw that referencing the static EMPTY_PACKAGES from within the privileged anonymous class adds synthetic access methods... More importantly, the current approach should already ensure any file is only scanned once by virtue of always setting manifest to a non-null value in the end. No? > > GetSystemPackage.java test > This is great. Thanks for adding the test. Thanks! > > Can you break the long lines such as the call to > JarBuilder.addClassFile and runSubprocess. Sure. Cleaned it up a bit. > Have you run this on windows? I think you need to use File.separator > rather than "/" in the -Xbootclasspath/p argument. Yes, I've run the test via JPRT and verified it gets picked up and run using the default testset, so Windows, Solaris, Mac and Linux should be covered. > > This test uses a special class loader that delegates to null class > loader only. Since you have the verification in place, it'd be good > to also call Package.getPackage and Package.getPackages to verify that > the same "package2" instance is returned. As a sanity check, you > could check "java.lang" package must be present. I've added some sanity checks as suggested. Sadly, it seems that since the application classloader will define and load package2 first in this test, there'll always be a Package defined in the ClassLoader.pkgs that will mask the Package instance in Package.pkgs when retrieved via the public methods in Package. If JDK-8061804 is resolved, we could change to check for identity in the Package.getPackages() case, which would improve the specificness of the test... For now, perhaps we could trick things in this test and put our dummy class into java.lang in our test here and ensure that the package retrieved is identical. Worth the hassle? > > In the verifyPackage, it throws Exception. You can simply throw > RuntimeException that would avoid the need of the checked exception. Sure. I've restructured a bit to keep line lengths in check. > Nit: line 35-37, 43-46 - no need to declare these import as > java.lang.* are imported by default. Some IDEs... > > Copyright year should be 2014. Fixed. http://cr.openjdk.java.net/~redestad/8060130/webrev.08 /Claes > >> >> >> I'd prefer sticking to the double-checked idiom here, unless you insist. >> >> I've cleaned up the code to avoid assignment in if-clauses, which >> according to >> anonymous sources makes the code more readable. Perhaps this addresses >> some of your concerns? >> > > Looks okay. Initialize manifest to EMPTY_MANIFEST would clean that a > little. > >> >> Since I don't want to add binary JAR files, I opted to add a test >> which creates two JAR files, >> each with a single class (with/without manifest) and then proceeds to >> spawn processes >> to verify that: >> > > Thanks for adding the test. > >> - when the JAR with manifest is on bootclasspath, the package can be >> found via >> Package.getSystemPackage and the package object reflects values added >> to the manifest >> - when the JAR without manifest is on bootclaspath, the package can >> be found via >> Package.getSystemPackage but is empty apart from name >> - adding the test.classes directory to bootclasspath behaves the same >> as adding the JAR >> without manifest >> - for any case where the class/package is not on the bootclasspath, >> the package information >> can not be found via Package.getSystemPackage(). >> >> Does this cover everything? >> > > This is great. See my comment above. > >> I guess there might be a way to make @run main/othervm or >> main/bootclasspath pick >> up a dynamically generated JAR file, but I've failed to find a way >> that would make this work without >> pregenerating the JARs. Suggestions on how this can be simplified are >> welcome. >> > > What you have is fine. The other way is to do it in a shell test > that is not preferable as you would have to manage FS for different > OSes etc. > > Mandy > From staffan.friberg at oracle.com Thu Oct 23 00:06:17 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Wed, 22 Oct 2014 17:06:17 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <20141022231025.00007607.ecki@zusammenkunft.net> Message-ID: <54484679.80402@oracle.com> Hi, I was thinking about this earlier when I started writing the patch and then I forgot about it again. I haven't been able to figure out when the code will be executed. ByteBuffer is implemented in such a way that only the JDK can extend it and as far as I can tell you can only create 3 types of ByteBuffers (Direct, Mapped and Heap), all of which will be handled by the more efficient calls above. That said just to make the code a bit safer from OOM it is probably best to update the default method and all current implementations which all use the same pattern. A reasonable solution should be the following code byte[] b = new byte[(buffer.remaining() < 4096) ? buffer.remaining() : 4096]; while (buffer.hasRemaining()) { int length = (buffer.remaining() < b.length) ? buffer.remaining() : b.length; buffer.get(b, 0, length); update(b, 0, length); } Xueming, do you have any further comment? Regards, Staffan On 10/22/2014 03:04 PM, Stanimir Simeonoff wrote: > > > On Thu, Oct 23, 2014 at 12:10 AM, Bernd Eckenfels > > wrote: > > Hello, > > just a question in the default impl: > > + } else { > + byte[] b = new byte[rem]; > + buffer.get(b); > + update(b, 0, b.length); > + } > > would it be a good idea to actually put a ceiling on the size of the > array which is processed at once? > > This is an excellent catch. > Should not be too large, probably 4k or so. > > Stanimir > > > Am Tue, 21 Oct 2014 10:28:50 -0700 > schrieb Staffan Friberg >: > > > Hi Peter, > > > > Thanks for the comments.. > > > > > > 217 if (Unsafe.ADDRESS_SIZE == 4) { > > > 218 // On 32 bit platforms read two ints > > > instead of a single 64bit long > > > > > > When you're reading from byte[] using Unsafe (updateBytes), you > > > have the option of reading 64bit values on 64bit platforms. When > > > you're reading from DirectByteBuffer memory > > > (updateDirectByteBuffer), you're only using 32bit reads. > > I will add a comment in the code for this decision. The reason is > > that read a long results in slightly worse performance in this case, > > in updateBytes it is faster. I was able to get it to run slightly > > faster by working directly with the address instead of always adding > > address + off, but this makes things worse in the 32bit case since > > all calculation will now be using long variables. So using the > getInt > > as in the current code feels like the best solution as it > strikes the > > best balance between 32 and 64bit. Below is how updateByteBuffer > > looked with the rewrite I mentioned. > > > > > > ong address = ((DirectBuffer) buffer).address(); > > crc = updateDirectByteBuffer(crc, address + pos, address + limit); > > > > > > private static int updateDirectByteBuffer(int crc, long adr, > > long end) { > > > > // Do only byte reads for arrays so short they can't be > > aligned if (end - adr >= 8) { > > > > // align on 8 bytes > > int alignLength = (8 - (int) (adr & 0x7)) & 0x7; > > for (long alignEnd = adr + alignLength; adr < alignEnd; > > adr++) { crc = (crc >>> 8) > > ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & > > 0xFF]; } > > > > if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { > > crc = Integer.reverseBytes(crc); > > } > > > > // slicing-by-8 > > for (; adr < (end - Long.BYTES); adr += Long.BYTES) { > > int firstHalf; > > int secondHalf; > > if (Unsafe.ADDRESS_SIZE == 4) { > > // On 32 bit platforms read two ints instead of > > a single 64bit long firstHalf = UNSAFE.getInt(adr); > > secondHalf = UNSAFE.getInt(adr + > Integer.BYTES); > > } else { > > long value = UNSAFE.getLong(adr); > > if (ByteOrder.nativeOrder() == > > ByteOrder.LITTLE_ENDIAN) { firstHalf = (int) value; > > secondHalf = (int) (value >>> 32); > > } else { // ByteOrder.BIG_ENDIAN > > firstHalf = (int) (value >>> 32); > > secondHalf = (int) value; > > } > > } > > crc ^= firstHalf; > > if (ByteOrder.nativeOrder() == > > ByteOrder.LITTLE_ENDIAN) { crc = byteTable7[crc & 0xFF] > > ^ byteTable6[(crc >>> 8) & 0xFF] > > ^ byteTable5[(crc >>> 16) & 0xFF] > > ^ byteTable4[crc >>> 24] > > ^ byteTable3[secondHalf & 0xFF] > > ^ byteTable2[(secondHalf >>> 8) & 0xFF] > > ^ byteTable1[(secondHalf >>> 16) & > 0xFF] > > ^ byteTable0[secondHalf >>> 24]; > > } else { // ByteOrder.BIG_ENDIAN > > crc = byteTable0[secondHalf & 0xFF] > > ^ byteTable1[(secondHalf >>> 8) & 0xFF] > > ^ byteTable2[(secondHalf >>> 16) & > 0xFF] > > ^ byteTable3[secondHalf >>> 24] > > ^ byteTable4[crc & 0xFF] > > ^ byteTable5[(crc >>> 8) & 0xFF] > > ^ byteTable6[(crc >>> 16) & 0xFF] > > ^ byteTable7[crc >>> 24]; > > } > > } > > > > if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { > > crc = Integer.reverseBytes(crc); > > } > > } > > > > // Tail > > for (; adr < end; adr++) { > > crc = (crc >>> 8) > > ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & > 0xFF]; > > } > > > > return crc; > > } > > > > > > > > > > Also, in updateBytes, the usage of > > > Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a > byte > > > array sounds a little scary. To be ultra portable you could check > > > that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use > Unsafe for > > > byte arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to > > > manipulate 'offsets' instead. In updateDirectByteBuffer it > would be > > > more appropriate to use Integer.BYTES/Long.BYTES too. > > Good idea. Added a check in the initial if statement and it will get > > automatically optimized away. > > > > > 225 firstHalf = (int) (value & > > > 0xFFFFFFFF); 226 secondHalf = (int) (value > > > >>> 32); 227 } else { // ByteOrder.BIG_ENDIAN > > > 228 firstHalf = (int) (value >>> 32); > > > 229 secondHalf = (int) (value & > > > 0xFFFFFFFF); > > > > > > firstHalf = (int) value; // this is equivalent for line 225 > > > secondHalf = (int) value; // this is equivalent for line 229 > > Done. > > > > Here is the latest webrev, > > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 > > > > > Cheers, > > Staffan > > From staffan.friberg at oracle.com Thu Oct 23 00:11:48 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Wed, 22 Oct 2014 17:11:48 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <54484679.80402@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <20141022231025.00007607.ecki@zusammenkunft.net> <54484679.80402@oracle.com> Message-ID: <544847C4.1040204@oracle.com> Just realized that in the Checksum default case we will actually end up there for Direct buffers. //Staffan On 10/22/2014 05:06 PM, Staffan Friberg wrote: > Hi, > > I was thinking about this earlier when I started writing the patch and > then I forgot about it again. I haven't been able to figure out when > the code will be executed. ByteBuffer is implemented in such a way > that only the JDK can extend it and as far as I can tell you can only > create 3 types of ByteBuffers (Direct, Mapped and Heap), all of which > will be handled by the more efficient calls above. > > That said just to make the code a bit safer from OOM it is probably > best to update the default method and all current implementations > which all use the same pattern. > > A reasonable solution should be the following code > > byte[] b = new byte[(buffer.remaining() < 4096) > ? buffer.remaining() : 4096]; > while (buffer.hasRemaining()) { > int length = (buffer.remaining() < b.length) > ? buffer.remaining() : b.length; > buffer.get(b, 0, length); > update(b, 0, length); > } > > Xueming, do you have any further comment? > > Regards, > Staffan > > On 10/22/2014 03:04 PM, Stanimir Simeonoff wrote: >> >> >> On Thu, Oct 23, 2014 at 12:10 AM, Bernd Eckenfels >> > wrote: >> >> Hello, >> >> just a question in the default impl: >> >> + } else { >> + byte[] b = new byte[rem]; >> + buffer.get(b); >> + update(b, 0, b.length); >> + } >> >> would it be a good idea to actually put a ceiling on the size of the >> array which is processed at once? >> This is an excellent catch. >> Should not be too large, probably 4k or so. >> >> Stanimir >> >> >> Am Tue, 21 Oct 2014 10:28:50 -0700 >> schrieb Staffan Friberg > >: >> >> > Hi Peter, >> > >> > Thanks for the comments.. >> > > >> > > 217 if (Unsafe.ADDRESS_SIZE == 4) { >> > > 218 // On 32 bit platforms read two ints >> > > instead of a single 64bit long >> > > >> > > When you're reading from byte[] using Unsafe (updateBytes), you >> > > have the option of reading 64bit values on 64bit platforms. When >> > > you're reading from DirectByteBuffer memory >> > > (updateDirectByteBuffer), you're only using 32bit reads. >> > I will add a comment in the code for this decision. The reason is >> > that read a long results in slightly worse performance in this >> case, >> > in updateBytes it is faster. I was able to get it to run slightly >> > faster by working directly with the address instead of always >> adding >> > address + off, but this makes things worse in the 32bit case since >> > all calculation will now be using long variables. So using the >> getInt >> > as in the current code feels like the best solution as it >> strikes the >> > best balance between 32 and 64bit. Below is how updateByteBuffer >> > looked with the rewrite I mentioned. >> > >> > >> > ong address = ((DirectBuffer) buffer).address(); >> > crc = updateDirectByteBuffer(crc, address + pos, address + >> limit); >> > >> > >> > private static int updateDirectByteBuffer(int crc, long adr, >> > long end) { >> > >> > // Do only byte reads for arrays so short they can't be >> > aligned if (end - adr >= 8) { >> > >> > // align on 8 bytes >> > int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >> > for (long alignEnd = adr + alignLength; adr < >> alignEnd; >> > adr++) { crc = (crc >>> 8) >> > ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & >> > 0xFF]; } >> > >> > if (ByteOrder.nativeOrder() == >> ByteOrder.BIG_ENDIAN) { >> > crc = Integer.reverseBytes(crc); >> > } >> > >> > // slicing-by-8 >> > for (; adr < (end - Long.BYTES); adr += Long.BYTES) { >> > int firstHalf; >> > int secondHalf; >> > if (Unsafe.ADDRESS_SIZE == 4) { >> > // On 32 bit platforms read two ints >> instead of >> > a single 64bit long firstHalf = UNSAFE.getInt(adr); >> > secondHalf = UNSAFE.getInt(adr + >> Integer.BYTES); >> > } else { >> > long value = UNSAFE.getLong(adr); >> > if (ByteOrder.nativeOrder() == >> > ByteOrder.LITTLE_ENDIAN) { firstHalf = (int) value; >> > secondHalf = (int) (value >>> 32); >> > } else { // ByteOrder.BIG_ENDIAN >> > firstHalf = (int) (value >>> 32); >> > secondHalf = (int) value; >> > } >> > } >> > crc ^= firstHalf; >> > if (ByteOrder.nativeOrder() == >> > ByteOrder.LITTLE_ENDIAN) { crc = byteTable7[crc & 0xFF] >> > ^ byteTable6[(crc >>> 8) & 0xFF] >> > ^ byteTable5[(crc >>> 16) & 0xFF] >> > ^ byteTable4[crc >>> 24] >> > ^ byteTable3[secondHalf & 0xFF] >> > ^ byteTable2[(secondHalf >>> 8) & >> 0xFF] >> > ^ byteTable1[(secondHalf >>> 16) & >> 0xFF] >> > ^ byteTable0[secondHalf >>> 24]; >> > } else { // ByteOrder.BIG_ENDIAN >> > crc = byteTable0[secondHalf & 0xFF] >> > ^ byteTable1[(secondHalf >>> 8) & >> 0xFF] >> > ^ byteTable2[(secondHalf >>> 16) & >> 0xFF] >> > ^ byteTable3[secondHalf >>> 24] >> > ^ byteTable4[crc & 0xFF] >> > ^ byteTable5[(crc >>> 8) & 0xFF] >> > ^ byteTable6[(crc >>> 16) & 0xFF] >> > ^ byteTable7[crc >>> 24]; >> > } >> > } >> > >> > if (ByteOrder.nativeOrder() == >> ByteOrder.BIG_ENDIAN) { >> > crc = Integer.reverseBytes(crc); >> > } >> > } >> > >> > // Tail >> > for (; adr < end; adr++) { >> > crc = (crc >>> 8) >> > ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & >> 0xFF]; >> > } >> > >> > return crc; >> > } >> > >> > >> > > >> > > Also, in updateBytes, the usage of >> > > Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a >> byte >> > > array sounds a little scary. To be ultra portable you could >> check >> > > that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use >> Unsafe for >> > > byte arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to >> > > manipulate 'offsets' instead. In updateDirectByteBuffer it >> would be >> > > more appropriate to use Integer.BYTES/Long.BYTES too. >> > Good idea. Added a check in the initial if statement and it >> will get >> > automatically optimized away. >> > >> > > 225 firstHalf = (int) (value & >> > > 0xFFFFFFFF); 226 secondHalf = (int) (value >> > > >>> 32); 227 } else { // >> ByteOrder.BIG_ENDIAN >> > > 228 firstHalf = (int) (value >>> 32); >> > > 229 secondHalf = (int) (value & >> > > 0xFFFFFFFF); >> > > >> > > firstHalf = (int) value; // this is equivalent for line 225 >> > > secondHalf = (int) value; // this is equivalent for line 229 >> > Done. >> > >> > Here is the latest webrev, >> > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >> >> > >> > Cheers, >> > Staffan >> >> > From stanimir at riflexo.com Thu Oct 23 00:37:29 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Thu, 23 Oct 2014 03:37:29 +0300 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <54484679.80402@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <20141022231025.00007607.ecki@zusammenkunft.net> <54484679.80402@oracle.com> Message-ID: Hi Staffan, The readonly buffer (ByteBuffer.asReadOnlyBuffer()) don't have array() "working". You can use "int length = Math.min(buffer.remaining, b.length)" instead, same with new byte[Math.min(4096, buffer.remaining)]. Using smaller chunks will be more performance friendly than allocating/eating up a huge byte[]. If you feel like, add a test with a heap bytebuffer.asReadOnlyBuffer(). Stanimir On Thu, Oct 23, 2014 at 3:06 AM, Staffan Friberg wrote: > Hi, > > I was thinking about this earlier when I started writing the patch and > then I forgot about it again. I haven't been able to figure out when the > code will be executed. ByteBuffer is implemented in such a way that only > the JDK can extend it and as far as I can tell you can only create 3 types > of ByteBuffers (Direct, Mapped and Heap), all of which will be handled by > the more efficient calls above. > > That said just to make the code a bit safer from OOM it is probably best > to update the default method and all current implementations which all use > the same pattern. > > A reasonable solution should be the following code > > byte[] b = new byte[(buffer.remaining() < 4096) > ? buffer.remaining() : 4096]; > while (buffer.hasRemaining()) { > int length = (buffer.remaining() < b.length) > ? buffer.remaining() : b.length; > buffer.get(b, 0, length); > update(b, 0, length); > } > > Xueming, do you have any further comment? > > Regards, > Staffan > > On 10/22/2014 03:04 PM, Stanimir Simeonoff wrote: > > > > On Thu, Oct 23, 2014 at 12:10 AM, Bernd Eckenfels > wrote: > >> Hello, >> >> just a question in the default impl: >> >> + } else { >> + byte[] b = new byte[rem]; >> + buffer.get(b); >> + update(b, 0, b.length); >> + } >> >> would it be a good idea to actually put a ceiling on the size of the >> array which is processed at once? > > This is an excellent catch. > Should not be too large, probably 4k or so. > > Stanimir > > >> Am Tue, 21 Oct 2014 10:28:50 -0700 >> schrieb Staffan Friberg : >> >> > Hi Peter, >> > >> > Thanks for the comments.. >> > > >> > > 217 if (Unsafe.ADDRESS_SIZE == 4) { >> > > 218 // On 32 bit platforms read two ints >> > > instead of a single 64bit long >> > > >> > > When you're reading from byte[] using Unsafe (updateBytes), you >> > > have the option of reading 64bit values on 64bit platforms. When >> > > you're reading from DirectByteBuffer memory >> > > (updateDirectByteBuffer), you're only using 32bit reads. >> > I will add a comment in the code for this decision. The reason is >> > that read a long results in slightly worse performance in this case, >> > in updateBytes it is faster. I was able to get it to run slightly >> > faster by working directly with the address instead of always adding >> > address + off, but this makes things worse in the 32bit case since >> > all calculation will now be using long variables. So using the getInt >> > as in the current code feels like the best solution as it strikes the >> > best balance between 32 and 64bit. Below is how updateByteBuffer >> > looked with the rewrite I mentioned. >> > >> > >> > ong address = ((DirectBuffer) buffer).address(); >> > crc = updateDirectByteBuffer(crc, address + pos, address + limit); >> > >> > >> > private static int updateDirectByteBuffer(int crc, long adr, >> > long end) { >> > >> > // Do only byte reads for arrays so short they can't be >> > aligned if (end - adr >= 8) { >> > >> > // align on 8 bytes >> > int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >> > for (long alignEnd = adr + alignLength; adr < alignEnd; >> > adr++) { crc = (crc >>> 8) >> > ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & >> > 0xFF]; } >> > >> > if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >> > crc = Integer.reverseBytes(crc); >> > } >> > >> > // slicing-by-8 >> > for (; adr < (end - Long.BYTES); adr += Long.BYTES) { >> > int firstHalf; >> > int secondHalf; >> > if (Unsafe.ADDRESS_SIZE == 4) { >> > // On 32 bit platforms read two ints instead of >> > a single 64bit long firstHalf = UNSAFE.getInt(adr); >> > secondHalf = UNSAFE.getInt(adr + Integer.BYTES); >> > } else { >> > long value = UNSAFE.getLong(adr); >> > if (ByteOrder.nativeOrder() == >> > ByteOrder.LITTLE_ENDIAN) { firstHalf = (int) value; >> > secondHalf = (int) (value >>> 32); >> > } else { // ByteOrder.BIG_ENDIAN >> > firstHalf = (int) (value >>> 32); >> > secondHalf = (int) value; >> > } >> > } >> > crc ^= firstHalf; >> > if (ByteOrder.nativeOrder() == >> > ByteOrder.LITTLE_ENDIAN) { crc = byteTable7[crc & 0xFF] >> > ^ byteTable6[(crc >>> 8) & 0xFF] >> > ^ byteTable5[(crc >>> 16) & 0xFF] >> > ^ byteTable4[crc >>> 24] >> > ^ byteTable3[secondHalf & 0xFF] >> > ^ byteTable2[(secondHalf >>> 8) & 0xFF] >> > ^ byteTable1[(secondHalf >>> 16) & 0xFF] >> > ^ byteTable0[secondHalf >>> 24]; >> > } else { // ByteOrder.BIG_ENDIAN >> > crc = byteTable0[secondHalf & 0xFF] >> > ^ byteTable1[(secondHalf >>> 8) & 0xFF] >> > ^ byteTable2[(secondHalf >>> 16) & 0xFF] >> > ^ byteTable3[secondHalf >>> 24] >> > ^ byteTable4[crc & 0xFF] >> > ^ byteTable5[(crc >>> 8) & 0xFF] >> > ^ byteTable6[(crc >>> 16) & 0xFF] >> > ^ byteTable7[crc >>> 24]; >> > } >> > } >> > >> > if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) { >> > crc = Integer.reverseBytes(crc); >> > } >> > } >> > >> > // Tail >> > for (; adr < end; adr++) { >> > crc = (crc >>> 8) >> > ^ byteTable[(crc ^ UNSAFE.getByte(adr)) & 0xFF]; >> > } >> > >> > return crc; >> > } >> > >> > >> > > >> > > Also, in updateBytes, the usage of >> > > Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to index a byte >> > > array sounds a little scary. To be ultra portable you could check >> > > that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use Unsafe for >> > > byte arrays if it is not 1. Then use Integer.BYTES/Long.BYTES to >> > > manipulate 'offsets' instead. In updateDirectByteBuffer it would be >> > > more appropriate to use Integer.BYTES/Long.BYTES too. >> > Good idea. Added a check in the initial if statement and it will get >> > automatically optimized away. >> > >> > > 225 firstHalf = (int) (value & >> > > 0xFFFFFFFF); 226 secondHalf = (int) (value >> > > >>> 32); 227 } else { // ByteOrder.BIG_ENDIAN >> > > 228 firstHalf = (int) (value >>> 32); >> > > 229 secondHalf = (int) (value & >> > > 0xFFFFFFFF); >> > > >> > > firstHalf = (int) value; // this is equivalent for line 225 >> > > secondHalf = (int) value; // this is equivalent for line 229 >> > Done. >> > >> > Here is the latest webrev, >> > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >> > >> > Cheers, >> > Staffan >> >> > > From mandy.chung at oracle.com Thu Oct 23 00:54:28 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 22 Oct 2014 17:54:28 -0700 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <54484497.3090705@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> <544662EB.2040907@oracle.com> <54482324.3060306@oracle.com> <54484497.3090705@oracle.com> Message-ID: <544851C4.70508@oracle.com> On 10/22/2014 4:58 PM, Claes Redestad wrote: > >> >> A minor nit: Package.java line 636: it can return EMPTY_MANIFEST >> that will set manifest to non-null so that an invalid file would >> avoid opening the file every time getManifest is called (although >> this case rarely happens). line 639 can then be simplified. > > We need to consider the case where JarInputStream.getManifest() > returns null, which would mean we'd either end up no simpler on line > 639 or simply adding a similar check around the value returned from > jis.getManifest(). I also think I saw that referencing the static > EMPTY_PACKAGES from within the privileged anonymous class adds > synthetic access methods... > > More importantly, the current approach should already ensure any file > is only scanned once by virtue of always setting manifest to a > non-null value in the end. No? That's right. I missed that you did set manifest to non-null in line 639. That's fine then. > > > Yes, I've run the test via JPRT and verified it gets picked up and run > using the default testset, so Windows, Solaris, Mac and Linux should > be covered. That's good. > >> >> This test uses a special class loader that delegates to null class >> loader only. Since you have the verification in place, it'd be good >> to also call Package.getPackage and Package.getPackages to verify >> that the same "package2" instance is returned. As a sanity check, >> you could check "java.lang" package must be present. > > I've added some sanity checks as suggested. Sadly, it seems that since > the application classloader will define and load package2 first in > this test, there'll always be a Package defined in the > ClassLoader.pkgs that will mask the Package instance in Package.pkgs > when retrieved via the public methods in Package. Can you remove package2/Class2.class after you create the jar files? > If JDK-8061804 is resolved, we could change to check for identity in > the Package.getPackages() case, which would improve the specificness > of the test... For now, perhaps we could trick things in this test and > put our dummy class into java.lang in our test here and ensure that > the package retrieved is identical. Worth the hassle? What I meant is to check if the returned Package contains "java.lang" package that always exists in the system packages. You don't need to put a dummy class in java.lang to get "java.lang" Package since it must be defined in the running VM. e.g. you can refactor line 169-176 to a findPackage method that returns Package matching the given package name such that in line 164 you can call findPackage("java.lang") that should return non-null. > >> Nit: line 35-37, 43-46 - no need to declare these import as >> java.lang.* are imported by default. > > Some IDEs... > Which IDE are you using? I think it might be your configuration. Thanks Mandy From mandy.chung at oracle.com Thu Oct 23 01:08:21 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 22 Oct 2014 18:08:21 -0700 Subject: Review request: JDK-8043277: Update jdk regression tests to extend the default security policy instead of override Message-ID: <54485505.4030002@oracle.com> jtreg policy option overrides the system security policy file and hence some existing test policy files have to duplicate the entries to grant permissions for JDK. jtreg has been enhanced to provide "java.security.policy" option to specify using the specified policy file in the same way as -Djava.security.policy= to extend the system security policy. The current jtreg "policy" option actually translates to -Djava.security.policy== (double equals) to override the system security policy. This patch updates several tests to use the new java.security.policy options along with removing the duplicated entries from the test policy files. Webrev: http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8043277/webrev.00/ thanks Mandy [1] https://bugs.openjdk.java.net/browse/CODETOOLS-7900898 From ecki at zusammenkunft.net Thu Oct 23 01:27:30 2014 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Thu, 23 Oct 2014 03:27:30 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <5448282B.1010900@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> <544662EB.2040907@oracle.com> <20141021230858.00006471.ecki@zusammenkunft.net> <5448282B.1010900@oracle.com> Message-ID: <20141023032730.00000ae4.ecki@zusammenkunft.net> Am Wed, 22 Oct 2014 14:56:59 -0700 schrieb Mandy Chung : > I guess your question is related to my comment about two class loaders > can define classes in a package of the same name (two different > runtime packages). ClassLoader.getPackage(s) assumes there is only > one Package for each name in the class loader chain which seems wrong > to me. Claes has filed a bug to track this: > https://bugs.openjdk.java.net/browse/JDK-8061804 Yes, I think thats the same, Mandy. One option for solving that in a still performant (lockless on hot path) way would be a "ConcurrentSet" of package names used for the initial decision if the hierachy needs traversed (and why may define a package). With a set of strings it would not keep the packages alive so it can be global. Not sure if it would need a cleanup mechanism.. hmm. Gruss Bernd From staffan.friberg at oracle.com Thu Oct 23 01:52:28 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Wed, 22 Oct 2014 18:52:28 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <20141022231025.00007607.ecki@zusammenkunft.net> <54484679.80402@oracle.com> Message-ID: <54485F5C.5000200@oracle.com> Webrev with these last updates. Added more tests to make sure CRC32C, CRC32 and Checksum default methods all are covered. http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.07 //Staffan On 10/22/2014 05:37 PM, Stanimir Simeonoff wrote: > Hi Staffan, > > The readonly buffer (ByteBuffer.asReadOnlyBuffer()) don't have array() > "working". > You can use "int length = Math.min(buffer.remaining, b.length)" > instead, same with new byte[Math.min(4096, buffer.remaining)]. Using > smaller chunks will be more performance friendly than > allocating/eating up a huge byte[]. > If you feel like, add a test with a heap bytebuffer.asReadOnlyBuffer(). > > Stanimir > > > On Thu, Oct 23, 2014 at 3:06 AM, Staffan Friberg > > wrote: > > Hi, > > I was thinking about this earlier when I started writing the patch > and then I forgot about it again. I haven't been able to figure > out when the code will be executed. ByteBuffer is implemented in > such a way that only the JDK can extend it and as far as I can > tell you can only create 3 types of ByteBuffers (Direct, Mapped > and Heap), all of which will be handled by the more efficient > calls above. > > That said just to make the code a bit safer from OOM it is > probably best to update the default method and all current > implementations which all use the same pattern. > > A reasonable solution should be the following code > > byte[] b = new byte[(buffer.remaining() < 4096) > ? buffer.remaining() : 4096]; > while (buffer.hasRemaining()) { > int length = (buffer.remaining() < b.length) > ? buffer.remaining() : b.length; > buffer.get(b, 0, length); > update(b, 0, length); > } > > Xueming, do you have any further comment? > > Regards, > Staffan > > On 10/22/2014 03:04 PM, Stanimir Simeonoff wrote: >> >> >> On Thu, Oct 23, 2014 at 12:10 AM, Bernd Eckenfels >> > wrote: >> >> Hello, >> >> just a question in the default impl: >> >> + } else { >> + byte[] b = new byte[rem]; >> + buffer.get(b); >> + update(b, 0, b.length); >> + } >> >> would it be a good idea to actually put a ceiling on the size >> of the >> array which is processed at once? >> >> This is an excellent catch. >> Should not be too large, probably 4k or so. >> >> Stanimir >> >> >> Am Tue, 21 Oct 2014 10:28:50 -0700 >> schrieb Staffan Friberg > >: >> >> > Hi Peter, >> > >> > Thanks for the comments.. >> > > >> > > 217 if (Unsafe.ADDRESS_SIZE == 4) { >> > > 218 // On 32 bit platforms read two >> ints >> > > instead of a single 64bit long >> > > >> > > When you're reading from byte[] using Unsafe >> (updateBytes), you >> > > have the option of reading 64bit values on 64bit >> platforms. When >> > > you're reading from DirectByteBuffer memory >> > > (updateDirectByteBuffer), you're only using 32bit reads. >> > I will add a comment in the code for this decision. The >> reason is >> > that read a long results in slightly worse performance in >> this case, >> > in updateBytes it is faster. I was able to get it to run >> slightly >> > faster by working directly with the address instead of >> always adding >> > address + off, but this makes things worse in the 32bit >> case since >> > all calculation will now be using long variables. So using >> the getInt >> > as in the current code feels like the best solution as it >> strikes the >> > best balance between 32 and 64bit. Below is how >> updateByteBuffer >> > looked with the rewrite I mentioned. >> > >> > >> > ong address = ((DirectBuffer) buffer).address(); >> > crc = updateDirectByteBuffer(crc, address + pos, address >> + limit); >> > >> > >> > private static int updateDirectByteBuffer(int crc, >> long adr, >> > long end) { >> > >> > // Do only byte reads for arrays so short they >> can't be >> > aligned if (end - adr >= 8) { >> > >> > // align on 8 bytes >> > int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >> > for (long alignEnd = adr + alignLength; adr < >> alignEnd; >> > adr++) { crc = (crc >>> 8) >> > ^ byteTable[(crc ^ >> UNSAFE.getByte(adr)) & >> > 0xFF]; } >> > >> > if (ByteOrder.nativeOrder() == >> ByteOrder.BIG_ENDIAN) { >> > crc = Integer.reverseBytes(crc); >> > } >> > >> > // slicing-by-8 >> > for (; adr < (end - Long.BYTES); adr += >> Long.BYTES) { >> > int firstHalf; >> > int secondHalf; >> > if (Unsafe.ADDRESS_SIZE == 4) { >> > // On 32 bit platforms read two ints >> instead of >> > a single 64bit long firstHalf = UNSAFE.getInt(adr); >> > secondHalf = UNSAFE.getInt(adr + >> Integer.BYTES); >> > } else { >> > long value = UNSAFE.getLong(adr); >> > if (ByteOrder.nativeOrder() == >> > ByteOrder.LITTLE_ENDIAN) { firstHalf = (int) value; >> > secondHalf = (int) (value >>> 32); >> > } else { // ByteOrder.BIG_ENDIAN >> > firstHalf = (int) (value >>> 32); >> > secondHalf = (int) value; >> > } >> > } >> > crc ^= firstHalf; >> > if (ByteOrder.nativeOrder() == >> > ByteOrder.LITTLE_ENDIAN) { crc = byteTable7[crc & 0xFF] >> > ^ byteTable6[(crc >>> 8) & 0xFF] >> > ^ byteTable5[(crc >>> 16) & 0xFF] >> > ^ byteTable4[crc >>> 24] >> > ^ byteTable3[secondHalf & 0xFF] >> > ^ byteTable2[(secondHalf >>> >> 8) & 0xFF] >> > ^ byteTable1[(secondHalf >>> >> 16) & 0xFF] >> > ^ byteTable0[secondHalf >>> 24]; >> > } else { // ByteOrder.BIG_ENDIAN >> > crc = byteTable0[secondHalf & 0xFF] >> > ^ byteTable1[(secondHalf >>> >> 8) & 0xFF] >> > ^ byteTable2[(secondHalf >>> >> 16) & 0xFF] >> > ^ byteTable3[secondHalf >>> 24] >> > ^ byteTable4[crc & 0xFF] >> > ^ byteTable5[(crc >>> 8) & 0xFF] >> > ^ byteTable6[(crc >>> 16) & 0xFF] >> > ^ byteTable7[crc >>> 24]; >> > } >> > } >> > >> > if (ByteOrder.nativeOrder() == >> ByteOrder.BIG_ENDIAN) { >> > crc = Integer.reverseBytes(crc); >> > } >> > } >> > >> > // Tail >> > for (; adr < end; adr++) { >> > crc = (crc >>> 8) >> > ^ byteTable[(crc ^ >> UNSAFE.getByte(adr)) & 0xFF]; >> > } >> > >> > return crc; >> > } >> > >> > >> > > >> > > Also, in updateBytes, the usage of >> > > Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to >> index a byte >> > > array sounds a little scary. To be ultra portable you >> could check >> > > that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use >> Unsafe for >> > > byte arrays if it is not 1. Then use >> Integer.BYTES/Long.BYTES to >> > > manipulate 'offsets' instead. In updateDirectByteBuffer >> it would be >> > > more appropriate to use Integer.BYTES/Long.BYTES too. >> > Good idea. Added a check in the initial if statement and it >> will get >> > automatically optimized away. >> > >> > > 225 firstHalf = (int) (value & >> > > 0xFFFFFFFF); 226 secondHalf = (int) (value >> > > >>> 32); 227 } else { // ByteOrder.BIG_ENDIAN >> > > 228 firstHalf = (int) (value >>> 32); >> > > 229 secondHalf = (int) (value & >> > > 0xFFFFFFFF); >> > > >> > > firstHalf = (int) value; // this is equivalent for line 225 >> > > secondHalf = (int) value; // this is equivalent for line 229 >> > Done. >> > >> > Here is the latest webrev, >> > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >> >> > >> > Cheers, >> > Staffan >> >> > > From david.holmes at oracle.com Thu Oct 23 02:54:32 2014 From: david.holmes at oracle.com (David Holmes) Date: Thu, 23 Oct 2014 12:54:32 +1000 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <5447A5C6.60802@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> <544662EB.2040907@oracle.com> <54471532.10109@oracle.com> <5447A5C6.60802@oracle.com> Message-ID: <54486DE8.9020101@oracle.com> On 22/10/2014 10:40 PM, Claes Redestad wrote: > Thanks! Updated: > > http://cr.openjdk.java.net/~redestad/8060130/webrev.07/ > > On a related note, > java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java is > failing when I run make TEST=jdk_lang test from jdk9-dev, and it seems > to be due to the test expecting java.home to be set to a JRE dir inside > a JDK. I na?vely copied my first approach from how > sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java discovers the jar > binary. Both these tests seems flawed and should use > jdk.testlibrary.JDKToolFinder.getJDKTool("jar"), no? Yes. :) They should just use the available jar tool (normally from the "compile JDK"). Thanks, David > /Claes > > On 10/22/2014 04:23 AM, David Holmes wrote: >> Hi Claes, >> >> In the test you should use the ProcessTools from the testlibrary not >> mess with System.getProperty("java.home") and create your own >> processes directly. The test should not require a full JDK to run, but >> should execute on a JRE or any compact profile. >> >> Thanks, >> David >> >> On 21/10/2014 11:43 PM, Claes Redestad wrote: >>> Hi Mandy, >>> >>> thanks for the review! >>> >>> On 10/15/2014 03:07 AM, Mandy Chung wrote: >>>> Claes, Peter, >>>> >>>> Thanks for the revised webrev and Peter's thorough review. webrev.05 >>>> looks much better. My comment is mostly minor. >>>> >>>> >>>> ClassLoader.java >>>> >>>> line 1582-1586 - I suggest to get rid of the "oldpkg" variable >>>> (it's really the package to be used and not an old pkg). >>>> >>>> pkg = new Package(name, specTitle, specVersion, specVendor, >>>> implTitle, implVersion, implVendor, >>>> sealBase, this); >>>> if (packages.putIfAbsent(name, pkg) != null) { >>>> throw new IllegalArgumentException(name + " already defined"); >>>> } >>>> return pkg; >>>> >>>> line 1634-1635: nit: the pkgName variable is not really needed. >>>> it's in the existing code and probably good to remove it. >>>> Package.java >>>> >>>> line 473: maybe better to leave the ClassLoader parameter in the >>>> constructor. >>>> I thought about adding a comment saying that this private >>>> constructor >>>> is only used for system package but keeping the loader parameter >>>> makes >>>> it more explicit. >>>> >>>> line 569: nit: formatting - indent to the right to align the first >>>> parameter >>>> to new Package(...) >>> >>> Fixed. >>> >>>> >>>> line 621-623: is this really needed? Uncontended case seems to be >>>> the common case. It seems the synchronized overhead would be >>>> insignificant. >>> >>> I'd prefer sticking to the double-checked idiom here, unless you insist. >>> >>> I've cleaned up the code to avoid assignment in if-clauses, which >>> according to >>> anonymous sources makes the code more readable. Perhaps this addresses >>> some of your concerns? >>> >>>> >>>> line 624: a space is missing between synchronized and "(" >>> >>> Fixed. >>> >>>> >>>> Looks like there is one test >>>> jdk/test/java/lang/ClassLoader/GetPackage.java >>>> about packages. Can you add a new test to verify the system packages >>>> as that >>>> is one major change in your patch? >>> >>> http://cr.openjdk.java.net/~redestad/8060130/webrev.06 >>> >>> Since I don't want to add binary JAR files, I opted to add a test which >>> creates two JAR files, >>> each with a single class (with/without manifest) and then proceeds to >>> spawn processes >>> to verify that: >>> >>> - when the JAR with manifest is on bootclasspath, the package can be >>> found via >>> Package.getSystemPackage and the package object reflects values added to >>> the manifest >>> - when the JAR without manifest is on bootclaspath, the package can be >>> found via >>> Package.getSystemPackage but is empty apart from name >>> - adding the test.classes directory to bootclasspath behaves the same as >>> adding the JAR >>> without manifest >>> - for any case where the class/package is not on the bootclasspath, the >>> package information >>> can not be found via Package.getSystemPackage(). >>> >>> Does this cover everything? >>> >>> I guess there might be a way to make @run main/othervm or >>> main/bootclasspath pick >>> up a dynamically generated JAR file, but I've failed to find a way that >>> would make this work without >>> pregenerating the JARs. Suggestions on how this can be simplified are >>> welcome. >>> >>> /Claes >>> >>>> >>>> Thanks >>>> Mandy >>>> > From sundararajan.athijegannathan at oracle.com Thu Oct 23 03:57:35 2014 From: sundararajan.athijegannathan at oracle.com (A. Sundararajan) Date: Thu, 23 Oct 2014 09:27:35 +0530 Subject: RFR: 8061830: [asm] refresh internal ASM version v5.0.3 In-Reply-To: <5447C892.6040009@oracle.com> References: <5447C892.6040009@oracle.com> Message-ID: <54487CAF.7070501@oracle.com> +1 -Sundar On Wednesday 22 October 2014 08:39 PM, Kumar Srinivasan wrote: > Hello, > > Please review fix for JDK-8061830, this is merely a refresh of the > existing source > base from upstream ObjectWeb/ASM, the webrev is here: > http://cr.openjdk.java.net/~ksrini/8061830/webrev.00/ > > All the validations performed are documented in the JBS issue. > > Thanks > Kumar > > From peter.levart at gmail.com Thu Oct 23 08:05:00 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 23 Oct 2014 10:05:00 +0200 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <54485F5C.5000200@oracle.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <20141022231025.00007607.ecki@zusammenkunft.net> <54484679.80402@oracle.com> <54485F5C.5000200@oracle.com> Message-ID: <5448B6AC.5060206@gmail.com> On 10/23/2014 03:52 AM, Staffan Friberg wrote: > Webrev with these last updates. Added more tests to make sure CRC32C, > CRC32 and Checksum default methods all are covered. > > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.07 Hi Staffan, Regarding default case: 168 } else { 169 byte[] b = new byte[Math.min(buffer.remaining(), 4096)]; 170 while (buffer.hasRemaining()) { 171 int length = Math.min(buffer.remaining(), b.length); 172 buffer.get(b, 0, length); 173 update(b, 0, length); 174 } 175 } Have you tried using get()/getInt() directly on the (ro) ByteBuffer instead of copying to byte[] chunks? Intuitively one would expect it perform faster if a redundant copy is avoided. Ah, you already told us that you plan to use intrinsic for CRC32C in the future, so you want to have "addresses" at hand. A hackish way to avoid copying in this case is to access the byte[] and offset using reflection. But this would have to be wrapped with doPrivileged() which would worsen performance for small buffers. A way to avoid repeated access checks is to do them at class initialization time, using MethodHandle(s). For example, something like: private static final MethodHandle bbArrayGetter; private static final MethodHandle bbArrayOffsetGetter; static { MethodHandle hbGetter; MethodHandle offsetGetter; try { Field hbField = ByteBuffer.class.getDeclaredField("hb"); Field offsetField = ByteBuffer.class.getDeclaredField("offset"); AccessController.doPrivileged(new PrivilegedAction() { @Override public Void run() { hbField.setAccessible(true); offsetField.setAccessible(true); return null; } }); hbGetter = MethodHandles.lookup().unreflectGetter(hbField); offsetGetter = MethodHandles.lookup().unreflectGetter(offsetField); } catch (NoSuchFieldException | IllegalAccessException e) { hbGetter = null; offsetGetter = null; } bbArrayGetter = hbGetter; bbArrayOffsetGetter = offsetGetter; } private static byte[] getArrayOrNull(ByteBuffer bb) { if (bb.hasArray()) return bb.array(); if (bbArrayGetter != null) { try { return (byte[]) bbArrayGetter.invokeExact(bb); } catch (Throwable e) { throw new InternalError(e); } } return null; } private static int getArrayOffset(ByteBuffer bb) { if (bb.hasArray()) return bb.arrayOffset(); if (bbArrayOffsetGetter != null) { try { return (int) bbArrayOffsetGetter.invokeExact(bb); } catch (Throwable e) { throw new InternalError(e); } } throw new UnsupportedOperationException(); } Regards, Peter > > //Staffan > > On 10/22/2014 05:37 PM, Stanimir Simeonoff wrote: >> Hi Staffan, >> >> The readonly buffer (ByteBuffer.asReadOnlyBuffer()) don't have >> array() "working". >> You can use "int length = Math.min(buffer.remaining, b.length)" >> instead, same with new byte[Math.min(4096, buffer.remaining)]. Using >> smaller chunks will be more performance friendly than >> allocating/eating up a huge byte[]. >> If you feel like, add a test with a heap bytebuffer.asReadOnlyBuffer(). >> >> Stanimir >> >> >> On Thu, Oct 23, 2014 at 3:06 AM, Staffan Friberg >> > wrote: >> >> Hi, >> >> I was thinking about this earlier when I started writing the patch >> and then I forgot about it again. I haven't been able to figure >> out when the code will be executed. ByteBuffer is implemented in >> such a way that only the JDK can extend it and as far as I can >> tell you can only create 3 types of ByteBuffers (Direct, Mapped >> and Heap), all of which will be handled by the more efficient >> calls above. >> >> That said just to make the code a bit safer from OOM it is >> probably best to update the default method and all current >> implementations which all use the same pattern. >> >> A reasonable solution should be the following code >> >> byte[] b = new byte[(buffer.remaining() < 4096) >> ? buffer.remaining() : 4096]; >> while (buffer.hasRemaining()) { >> int length = (buffer.remaining() < b.length) >> ? buffer.remaining() : b.length; >> buffer.get(b, 0, length); >> update(b, 0, length); >> } >> >> Xueming, do you have any further comment? >> >> Regards, >> Staffan >> >> On 10/22/2014 03:04 PM, Stanimir Simeonoff wrote: >>> >>> >>> On Thu, Oct 23, 2014 at 12:10 AM, Bernd Eckenfels >>> > wrote: >>> >>> Hello, >>> >>> just a question in the default impl: >>> >>> + } else { >>> + byte[] b = new byte[rem]; >>> + buffer.get(b); >>> + update(b, 0, b.length); >>> + } >>> >>> would it be a good idea to actually put a ceiling on the size >>> of the >>> array which is processed at once? >>> This is an excellent catch. >>> Should not be too large, probably 4k or so. >>> >>> Stanimir >>> >>> >>> Am Tue, 21 Oct 2014 10:28:50 -0700 >>> schrieb Staffan Friberg >> >: >>> >>> > Hi Peter, >>> > >>> > Thanks for the comments.. >>> > > >>> > > 217 if (Unsafe.ADDRESS_SIZE == 4) { >>> > > 218 // On 32 bit platforms read two >>> ints >>> > > instead of a single 64bit long >>> > > >>> > > When you're reading from byte[] using Unsafe >>> (updateBytes), you >>> > > have the option of reading 64bit values on 64bit >>> platforms. When >>> > > you're reading from DirectByteBuffer memory >>> > > (updateDirectByteBuffer), you're only using 32bit reads. >>> > I will add a comment in the code for this decision. The >>> reason is >>> > that read a long results in slightly worse performance in >>> this case, >>> > in updateBytes it is faster. I was able to get it to run >>> slightly >>> > faster by working directly with the address instead of >>> always adding >>> > address + off, but this makes things worse in the 32bit >>> case since >>> > all calculation will now be using long variables. So using >>> the getInt >>> > as in the current code feels like the best solution as it >>> strikes the >>> > best balance between 32 and 64bit. Below is how >>> updateByteBuffer >>> > looked with the rewrite I mentioned. >>> > >>> > >>> > ong address = ((DirectBuffer) buffer).address(); >>> > crc = updateDirectByteBuffer(crc, address + pos, address >>> + limit); >>> > >>> > >>> > private static int updateDirectByteBuffer(int crc, >>> long adr, >>> > long end) { >>> > >>> > // Do only byte reads for arrays so short they >>> can't be >>> > aligned if (end - adr >= 8) { >>> > >>> > // align on 8 bytes >>> > int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >>> > for (long alignEnd = adr + alignLength; adr < >>> alignEnd; >>> > adr++) { crc = (crc >>> 8) >>> > ^ byteTable[(crc ^ >>> UNSAFE.getByte(adr)) & >>> > 0xFF]; } >>> > >>> > if (ByteOrder.nativeOrder() == >>> ByteOrder.BIG_ENDIAN) { >>> > crc = Integer.reverseBytes(crc); >>> > } >>> > >>> > // slicing-by-8 >>> > for (; adr < (end - Long.BYTES); adr += >>> Long.BYTES) { >>> > int firstHalf; >>> > int secondHalf; >>> > if (Unsafe.ADDRESS_SIZE == 4) { >>> > // On 32 bit platforms read two ints >>> instead of >>> > a single 64bit long firstHalf = UNSAFE.getInt(adr); >>> > secondHalf = UNSAFE.getInt(adr + >>> Integer.BYTES); >>> > } else { >>> > long value = UNSAFE.getLong(adr); >>> > if (ByteOrder.nativeOrder() == >>> > ByteOrder.LITTLE_ENDIAN) { firstHalf = (int) value; >>> > secondHalf = (int) (value >>> 32); >>> > } else { // ByteOrder.BIG_ENDIAN >>> > firstHalf = (int) (value >>> 32); >>> > secondHalf = (int) value; >>> > } >>> > } >>> > crc ^= firstHalf; >>> > if (ByteOrder.nativeOrder() == >>> > ByteOrder.LITTLE_ENDIAN) { crc = byteTable7[crc & 0xFF] >>> > ^ byteTable6[(crc >>> 8) & 0xFF] >>> > ^ byteTable5[(crc >>> 16) & >>> 0xFF] >>> > ^ byteTable4[crc >>> 24] >>> > ^ byteTable3[secondHalf & 0xFF] >>> > ^ byteTable2[(secondHalf >>> >>> 8) & 0xFF] >>> > ^ byteTable1[(secondHalf >>> >>> 16) & 0xFF] >>> > ^ byteTable0[secondHalf >>> 24]; >>> > } else { // ByteOrder.BIG_ENDIAN >>> > crc = byteTable0[secondHalf & 0xFF] >>> > ^ byteTable1[(secondHalf >>> >>> 8) & 0xFF] >>> > ^ byteTable2[(secondHalf >>> >>> 16) & 0xFF] >>> > ^ byteTable3[secondHalf >>> 24] >>> > ^ byteTable4[crc & 0xFF] >>> > ^ byteTable5[(crc >>> 8) & 0xFF] >>> > ^ byteTable6[(crc >>> 16) & >>> 0xFF] >>> > ^ byteTable7[crc >>> 24]; >>> > } >>> > } >>> > >>> > if (ByteOrder.nativeOrder() == >>> ByteOrder.BIG_ENDIAN) { >>> > crc = Integer.reverseBytes(crc); >>> > } >>> > } >>> > >>> > // Tail >>> > for (; adr < end; adr++) { >>> > crc = (crc >>> 8) >>> > ^ byteTable[(crc ^ >>> UNSAFE.getByte(adr)) & 0xFF]; >>> > } >>> > >>> > return crc; >>> > } >>> > >>> > >>> > > >>> > > Also, in updateBytes, the usage of >>> > > Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to >>> index a byte >>> > > array sounds a little scary. To be ultra portable you >>> could check >>> > > that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use >>> Unsafe for >>> > > byte arrays if it is not 1. Then use >>> Integer.BYTES/Long.BYTES to >>> > > manipulate 'offsets' instead. In updateDirectByteBuffer >>> it would be >>> > > more appropriate to use Integer.BYTES/Long.BYTES too. >>> > Good idea. Added a check in the initial if statement and it >>> will get >>> > automatically optimized away. >>> > >>> > > 225 firstHalf = (int) (value & >>> > > 0xFFFFFFFF); 226 secondHalf = (int) (value >>> > > >>> 32); 227 } else { // ByteOrder.BIG_ENDIAN >>> > > 228 firstHalf = (int) (value >>> 32); >>> > > 229 secondHalf = (int) (value & >>> > > 0xFFFFFFFF); >>> > > >>> > > firstHalf = (int) value; // this is equivalent for line 225 >>> > > secondHalf = (int) value; // this is equivalent for line >>> 229 >>> > Done. >>> > >>> > Here is the latest webrev, >>> > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>> >>> > >>> > Cheers, >>> > Staffan >>> >>> >> >> > From stanimir at riflexo.com Thu Oct 23 08:16:42 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Thu, 23 Oct 2014 11:16:42 +0300 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5448B6AC.5060206@gmail.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <20141022231025.00007607.ecki@zusammenkunft.net> <54484679.80402@oracle.com> <54485F5C.5000200@oracle.com> <5448B6AC.5060206@gmail.com> Message-ID: Unsafe is available, so the fields (array, offset) can be read directly UNSAFE.getObject(buffer, hbOffset), UNSAFE.getObject(buffer, offsetOffset). No need for MethodHandlers. During class init the offsets have to be resolved, pretty much like any CAS utilizing algorithm. I didn't propose it as readOnlyBuffers are very, very rarely used and even more unlikely to be used to calculate checksums. It just makes the code ugly. Stanimir On Thu, Oct 23, 2014 at 11:05 AM, Peter Levart wrote: > On 10/23/2014 03:52 AM, Staffan Friberg wrote: > >> Webrev with these last updates. Added more tests to make sure CRC32C, >> CRC32 and Checksum default methods all are covered. >> >> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.07 >> > > Hi Staffan, > > Regarding default case: > > 168 } else { > 169 byte[] b = new byte[Math.min(buffer.remaining(), 4096)]; > 170 while (buffer.hasRemaining()) { > 171 int length = Math.min(buffer.remaining(), b.length); > 172 buffer.get(b, 0, length); > 173 update(b, 0, length); > 174 } > 175 } > > > Have you tried using get()/getInt() directly on the (ro) ByteBuffer > instead of copying to byte[] chunks? Intuitively one would expect it > perform faster if a redundant copy is avoided. Ah, you already told us that > you plan to use intrinsic for CRC32C in the future, so you want to have > "addresses" at hand. > > A hackish way to avoid copying in this case is to access the byte[] and > offset using reflection. But this would have to be wrapped with > doPrivileged() which would worsen performance for small buffers. A way to > avoid repeated access checks is to do them at class initialization time, > using MethodHandle(s). For example, something like: > > > private static final MethodHandle bbArrayGetter; > private static final MethodHandle bbArrayOffsetGetter; > > static { > MethodHandle hbGetter; > MethodHandle offsetGetter; > try { > Field hbField = ByteBuffer.class.getDeclaredField("hb"); > Field offsetField = ByteBuffer.class. > getDeclaredField("offset"); > AccessController.doPrivileged(new PrivilegedAction() { > @Override > public Void run() { > hbField.setAccessible(true); > offsetField.setAccessible(true); > return null; > } > }); > hbGetter = MethodHandles.lookup().unreflectGetter(hbField); > offsetGetter = MethodHandles.lookup(). > unreflectGetter(offsetField); > } catch (NoSuchFieldException | IllegalAccessException e) { > hbGetter = null; > offsetGetter = null; > } > bbArrayGetter = hbGetter; > bbArrayOffsetGetter = offsetGetter; > } > > private static byte[] getArrayOrNull(ByteBuffer bb) { > if (bb.hasArray()) return bb.array(); > if (bbArrayGetter != null) { > try { > return (byte[]) bbArrayGetter.invokeExact(bb); > } catch (Throwable e) { > throw new InternalError(e); > } > } > return null; > } > > private static int getArrayOffset(ByteBuffer bb) { > if (bb.hasArray()) return bb.arrayOffset(); > if (bbArrayOffsetGetter != null) { > try { > return (int) bbArrayOffsetGetter.invokeExact(bb); > } catch (Throwable e) { > throw new InternalError(e); > } > } > throw new UnsupportedOperationException(); > } > > > > Regards, Peter > > >> //Staffan >> >> On 10/22/2014 05:37 PM, Stanimir Simeonoff wrote: >> >>> Hi Staffan, >>> >>> The readonly buffer (ByteBuffer.asReadOnlyBuffer()) don't have array() >>> "working". >>> You can use "int length = Math.min(buffer.remaining, b.length)" instead, >>> same with new byte[Math.min(4096, buffer.remaining)]. Using smaller chunks >>> will be more performance friendly than allocating/eating up a huge byte[]. >>> If you feel like, add a test with a heap bytebuffer.asReadOnlyBuffer(). >>> >>> Stanimir >>> >>> >>> On Thu, Oct 23, 2014 at 3:06 AM, Staffan Friberg < >>> staffan.friberg at oracle.com > wrote: >>> >>> Hi, >>> >>> I was thinking about this earlier when I started writing the patch >>> and then I forgot about it again. I haven't been able to figure >>> out when the code will be executed. ByteBuffer is implemented in >>> such a way that only the JDK can extend it and as far as I can >>> tell you can only create 3 types of ByteBuffers (Direct, Mapped >>> and Heap), all of which will be handled by the more efficient >>> calls above. >>> >>> That said just to make the code a bit safer from OOM it is >>> probably best to update the default method and all current >>> implementations which all use the same pattern. >>> >>> A reasonable solution should be the following code >>> >>> byte[] b = new byte[(buffer.remaining() < 4096) >>> ? buffer.remaining() : 4096]; >>> while (buffer.hasRemaining()) { >>> int length = (buffer.remaining() < b.length) >>> ? buffer.remaining() : b.length; >>> buffer.get(b, 0, length); >>> update(b, 0, length); >>> } >>> >>> Xueming, do you have any further comment? >>> >>> Regards, >>> Staffan >>> >>> On 10/22/2014 03:04 PM, Stanimir Simeonoff wrote: >>> >>>> >>>> >>>> On Thu, Oct 23, 2014 at 12:10 AM, Bernd Eckenfels >>>> > wrote: >>>> >>>> Hello, >>>> >>>> just a question in the default impl: >>>> >>>> + } else { >>>> + byte[] b = new byte[rem]; >>>> + buffer.get(b); >>>> + update(b, 0, b.length); >>>> + } >>>> >>>> would it be a good idea to actually put a ceiling on the size >>>> of the >>>> array which is processed at once? >>>> This is an excellent catch. >>>> Should not be too large, probably 4k or so. >>>> >>>> Stanimir >>>> >>>> >>>> Am Tue, 21 Oct 2014 10:28:50 -0700 >>>> schrieb Staffan Friberg >>> >: >>>> >>>> >>>> > Hi Peter, >>>> > >>>> > Thanks for the comments.. >>>> > > >>>> > > 217 if (Unsafe.ADDRESS_SIZE == 4) { >>>> > > 218 // On 32 bit platforms read two >>>> ints >>>> > > instead of a single 64bit long >>>> > > >>>> > > When you're reading from byte[] using Unsafe >>>> (updateBytes), you >>>> > > have the option of reading 64bit values on 64bit >>>> platforms. When >>>> > > you're reading from DirectByteBuffer memory >>>> > > (updateDirectByteBuffer), you're only using 32bit reads. >>>> > I will add a comment in the code for this decision. The >>>> reason is >>>> > that read a long results in slightly worse performance in >>>> this case, >>>> > in updateBytes it is faster. I was able to get it to run >>>> slightly >>>> > faster by working directly with the address instead of >>>> always adding >>>> > address + off, but this makes things worse in the 32bit >>>> case since >>>> > all calculation will now be using long variables. So using >>>> the getInt >>>> > as in the current code feels like the best solution as it >>>> strikes the >>>> > best balance between 32 and 64bit. Below is how >>>> updateByteBuffer >>>> > looked with the rewrite I mentioned. >>>> > >>>> > >>>> > ong address = ((DirectBuffer) buffer).address(); >>>> > crc = updateDirectByteBuffer(crc, address + pos, address >>>> + limit); >>>> > >>>> > >>>> > private static int updateDirectByteBuffer(int crc, >>>> long adr, >>>> > long end) { >>>> > >>>> > // Do only byte reads for arrays so short they >>>> can't be >>>> > aligned if (end - adr >= 8) { >>>> > >>>> > // align on 8 bytes >>>> > int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >>>> > for (long alignEnd = adr + alignLength; adr < >>>> alignEnd; >>>> > adr++) { crc = (crc >>> 8) >>>> > ^ byteTable[(crc ^ >>>> UNSAFE.getByte(adr)) & >>>> > 0xFF]; } >>>> > >>>> > if (ByteOrder.nativeOrder() == >>>> ByteOrder.BIG_ENDIAN) { >>>> > crc = Integer.reverseBytes(crc); >>>> > } >>>> > >>>> > // slicing-by-8 >>>> > for (; adr < (end - Long.BYTES); adr += >>>> Long.BYTES) { >>>> > int firstHalf; >>>> > int secondHalf; >>>> > if (Unsafe.ADDRESS_SIZE == 4) { >>>> > // On 32 bit platforms read two ints >>>> instead of >>>> > a single 64bit long firstHalf = UNSAFE.getInt(adr); >>>> > secondHalf = UNSAFE.getInt(adr + >>>> Integer.BYTES); >>>> > } else { >>>> > long value = UNSAFE.getLong(adr); >>>> > if (ByteOrder.nativeOrder() == >>>> > ByteOrder.LITTLE_ENDIAN) { firstHalf = (int) value; >>>> > secondHalf = (int) (value >>> 32); >>>> > } else { // ByteOrder.BIG_ENDIAN >>>> > firstHalf = (int) (value >>> 32); >>>> > secondHalf = (int) value; >>>> > } >>>> > } >>>> > crc ^= firstHalf; >>>> > if (ByteOrder.nativeOrder() == >>>> > ByteOrder.LITTLE_ENDIAN) { crc = byteTable7[crc & 0xFF] >>>> > ^ byteTable6[(crc >>> 8) & 0xFF] >>>> > ^ byteTable5[(crc >>> 16) & 0xFF] >>>> > ^ byteTable4[crc >>> 24] >>>> > ^ byteTable3[secondHalf & 0xFF] >>>> > ^ byteTable2[(secondHalf >>> >>>> 8) & 0xFF] >>>> > ^ byteTable1[(secondHalf >>> >>>> 16) & 0xFF] >>>> > ^ byteTable0[secondHalf >>> 24]; >>>> > } else { // ByteOrder.BIG_ENDIAN >>>> > crc = byteTable0[secondHalf & 0xFF] >>>> > ^ byteTable1[(secondHalf >>> >>>> 8) & 0xFF] >>>> > ^ byteTable2[(secondHalf >>> >>>> 16) & 0xFF] >>>> > ^ byteTable3[secondHalf >>> 24] >>>> > ^ byteTable4[crc & 0xFF] >>>> > ^ byteTable5[(crc >>> 8) & 0xFF] >>>> > ^ byteTable6[(crc >>> 16) & 0xFF] >>>> > ^ byteTable7[crc >>> 24]; >>>> > } >>>> > } >>>> > >>>> > if (ByteOrder.nativeOrder() == >>>> ByteOrder.BIG_ENDIAN) { >>>> > crc = Integer.reverseBytes(crc); >>>> > } >>>> > } >>>> > >>>> > // Tail >>>> > for (; adr < end; adr++) { >>>> > crc = (crc >>> 8) >>>> > ^ byteTable[(crc ^ >>>> UNSAFE.getByte(adr)) & 0xFF]; >>>> > } >>>> > >>>> > return crc; >>>> > } >>>> > >>>> > >>>> > > >>>> > > Also, in updateBytes, the usage of >>>> > > Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to >>>> index a byte >>>> > > array sounds a little scary. To be ultra portable you >>>> could check >>>> > > that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use >>>> Unsafe for >>>> > > byte arrays if it is not 1. Then use >>>> Integer.BYTES/Long.BYTES to >>>> > > manipulate 'offsets' instead. In updateDirectByteBuffer >>>> it would be >>>> > > more appropriate to use Integer.BYTES/Long.BYTES too. >>>> > Good idea. Added a check in the initial if statement and it >>>> will get >>>> > automatically optimized away. >>>> > >>>> > > 225 firstHalf = (int) (value & >>>> > > 0xFFFFFFFF); 226 secondHalf = (int) (value >>>> > > >>> 32); 227 } else { // ByteOrder.BIG_ENDIAN >>>> > > 228 firstHalf = (int) (value >>> 32); >>>> > > 229 secondHalf = (int) (value & >>>> > > 0xFFFFFFFF); >>>> > > >>>> > > firstHalf = (int) value; // this is equivalent for line 225 >>>> > > secondHalf = (int) value; // this is equivalent for line 229 >>>> > Done. >>>> > >>>> > Here is the latest webrev, >>>> > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>>> >>>> > >>>> > Cheers, >>>> > Staffan >>>> >>>> >>>> >>> >>> >> > From stanimir at riflexo.com Thu Oct 23 08:18:05 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Thu, 23 Oct 2014 11:18:05 +0300 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <20141022231025.00007607.ecki@zusammenkunft.net> <54484679.80402@oracle.com> <54485F5C.5000200@oracle.com> <5448B6AC.5060206@gmail.com> Message-ID: >>, UNSAFE.getObject(buffer, offsetOffset) Obviously should be Unsafe.getInt(buffer, offsetOffset) On Thu, Oct 23, 2014 at 11:16 AM, Stanimir Simeonoff wrote: > Unsafe is available, so the fields (array, offset) can be read directly > UNSAFE.getObject(buffer, hbOffset), UNSAFE.getObject(buffer, offsetOffset). > No need for MethodHandlers. > During class init the offsets have to be resolved, pretty much like any > CAS utilizing algorithm. > > I didn't propose it as readOnlyBuffers are very, very rarely used and even > more unlikely to be used to calculate checksums. It just makes the code > ugly. > > Stanimir > > On Thu, Oct 23, 2014 at 11:05 AM, Peter Levart > wrote: > >> On 10/23/2014 03:52 AM, Staffan Friberg wrote: >> >>> Webrev with these last updates. Added more tests to make sure CRC32C, >>> CRC32 and Checksum default methods all are covered. >>> >>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.07 >>> >> >> Hi Staffan, >> >> Regarding default case: >> >> 168 } else { >> 169 byte[] b = new byte[Math.min(buffer.remaining(), 4096)]; >> 170 while (buffer.hasRemaining()) { >> 171 int length = Math.min(buffer.remaining(), b.length); >> 172 buffer.get(b, 0, length); >> 173 update(b, 0, length); >> 174 } >> 175 } >> >> >> Have you tried using get()/getInt() directly on the (ro) ByteBuffer >> instead of copying to byte[] chunks? Intuitively one would expect it >> perform faster if a redundant copy is avoided. Ah, you already told us that >> you plan to use intrinsic for CRC32C in the future, so you want to have >> "addresses" at hand. >> >> A hackish way to avoid copying in this case is to access the byte[] and >> offset using reflection. But this would have to be wrapped with >> doPrivileged() which would worsen performance for small buffers. A way to >> avoid repeated access checks is to do them at class initialization time, >> using MethodHandle(s). For example, something like: >> >> >> private static final MethodHandle bbArrayGetter; >> private static final MethodHandle bbArrayOffsetGetter; >> >> static { >> MethodHandle hbGetter; >> MethodHandle offsetGetter; >> try { >> Field hbField = ByteBuffer.class.getDeclaredField("hb"); >> Field offsetField = ByteBuffer.class. >> getDeclaredField("offset"); >> AccessController.doPrivileged(new PrivilegedAction() { >> @Override >> public Void run() { >> hbField.setAccessible(true); >> offsetField.setAccessible(true); >> return null; >> } >> }); >> hbGetter = MethodHandles.lookup().unreflectGetter(hbField); >> offsetGetter = MethodHandles.lookup(). >> unreflectGetter(offsetField); >> } catch (NoSuchFieldException | IllegalAccessException e) { >> hbGetter = null; >> offsetGetter = null; >> } >> bbArrayGetter = hbGetter; >> bbArrayOffsetGetter = offsetGetter; >> } >> >> private static byte[] getArrayOrNull(ByteBuffer bb) { >> if (bb.hasArray()) return bb.array(); >> if (bbArrayGetter != null) { >> try { >> return (byte[]) bbArrayGetter.invokeExact(bb); >> } catch (Throwable e) { >> throw new InternalError(e); >> } >> } >> return null; >> } >> >> private static int getArrayOffset(ByteBuffer bb) { >> if (bb.hasArray()) return bb.arrayOffset(); >> if (bbArrayOffsetGetter != null) { >> try { >> return (int) bbArrayOffsetGetter.invokeExact(bb); >> } catch (Throwable e) { >> throw new InternalError(e); >> } >> } >> throw new UnsupportedOperationException(); >> } >> >> >> >> Regards, Peter >> >> >>> //Staffan >>> >>> On 10/22/2014 05:37 PM, Stanimir Simeonoff wrote: >>> >>>> Hi Staffan, >>>> >>>> The readonly buffer (ByteBuffer.asReadOnlyBuffer()) don't have array() >>>> "working". >>>> You can use "int length = Math.min(buffer.remaining, b.length)" >>>> instead, same with new byte[Math.min(4096, buffer.remaining)]. Using >>>> smaller chunks will be more performance friendly than allocating/eating up >>>> a huge byte[]. >>>> If you feel like, add a test with a heap bytebuffer.asReadOnlyBuffer(). >>>> >>>> Stanimir >>>> >>>> >>>> On Thu, Oct 23, 2014 at 3:06 AM, Staffan Friberg < >>>> staffan.friberg at oracle.com > wrote: >>>> >>>> Hi, >>>> >>>> I was thinking about this earlier when I started writing the patch >>>> and then I forgot about it again. I haven't been able to figure >>>> out when the code will be executed. ByteBuffer is implemented in >>>> such a way that only the JDK can extend it and as far as I can >>>> tell you can only create 3 types of ByteBuffers (Direct, Mapped >>>> and Heap), all of which will be handled by the more efficient >>>> calls above. >>>> >>>> That said just to make the code a bit safer from OOM it is >>>> probably best to update the default method and all current >>>> implementations which all use the same pattern. >>>> >>>> A reasonable solution should be the following code >>>> >>>> byte[] b = new byte[(buffer.remaining() < 4096) >>>> ? buffer.remaining() : 4096]; >>>> while (buffer.hasRemaining()) { >>>> int length = (buffer.remaining() < b.length) >>>> ? buffer.remaining() : b.length; >>>> buffer.get(b, 0, length); >>>> update(b, 0, length); >>>> } >>>> >>>> Xueming, do you have any further comment? >>>> >>>> Regards, >>>> Staffan >>>> >>>> On 10/22/2014 03:04 PM, Stanimir Simeonoff wrote: >>>> >>>>> >>>>> >>>>> On Thu, Oct 23, 2014 at 12:10 AM, Bernd Eckenfels >>>>> > wrote: >>>>> >>>>> Hello, >>>>> >>>>> just a question in the default impl: >>>>> >>>>> + } else { >>>>> + byte[] b = new byte[rem]; >>>>> + buffer.get(b); >>>>> + update(b, 0, b.length); >>>>> + } >>>>> >>>>> would it be a good idea to actually put a ceiling on the size >>>>> of the >>>>> array which is processed at once? >>>>> This is an excellent catch. >>>>> Should not be too large, probably 4k or so. >>>>> >>>>> Stanimir >>>>> >>>>> >>>>> Am Tue, 21 Oct 2014 10:28:50 -0700 >>>>> schrieb Staffan Friberg >>>> >: >>>>> >>>>> >>>>> > Hi Peter, >>>>> > >>>>> > Thanks for the comments.. >>>>> > > >>>>> > > 217 if (Unsafe.ADDRESS_SIZE == 4) { >>>>> > > 218 // On 32 bit platforms read two >>>>> ints >>>>> > > instead of a single 64bit long >>>>> > > >>>>> > > When you're reading from byte[] using Unsafe >>>>> (updateBytes), you >>>>> > > have the option of reading 64bit values on 64bit >>>>> platforms. When >>>>> > > you're reading from DirectByteBuffer memory >>>>> > > (updateDirectByteBuffer), you're only using 32bit reads. >>>>> > I will add a comment in the code for this decision. The >>>>> reason is >>>>> > that read a long results in slightly worse performance in >>>>> this case, >>>>> > in updateBytes it is faster. I was able to get it to run >>>>> slightly >>>>> > faster by working directly with the address instead of >>>>> always adding >>>>> > address + off, but this makes things worse in the 32bit >>>>> case since >>>>> > all calculation will now be using long variables. So using >>>>> the getInt >>>>> > as in the current code feels like the best solution as it >>>>> strikes the >>>>> > best balance between 32 and 64bit. Below is how >>>>> updateByteBuffer >>>>> > looked with the rewrite I mentioned. >>>>> > >>>>> > >>>>> > ong address = ((DirectBuffer) buffer).address(); >>>>> > crc = updateDirectByteBuffer(crc, address + pos, address >>>>> + limit); >>>>> > >>>>> > >>>>> > private static int updateDirectByteBuffer(int crc, >>>>> long adr, >>>>> > long end) { >>>>> > >>>>> > // Do only byte reads for arrays so short they >>>>> can't be >>>>> > aligned if (end - adr >= 8) { >>>>> > >>>>> > // align on 8 bytes >>>>> > int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >>>>> > for (long alignEnd = adr + alignLength; adr < >>>>> alignEnd; >>>>> > adr++) { crc = (crc >>> 8) >>>>> > ^ byteTable[(crc ^ >>>>> UNSAFE.getByte(adr)) & >>>>> > 0xFF]; } >>>>> > >>>>> > if (ByteOrder.nativeOrder() == >>>>> ByteOrder.BIG_ENDIAN) { >>>>> > crc = Integer.reverseBytes(crc); >>>>> > } >>>>> > >>>>> > // slicing-by-8 >>>>> > for (; adr < (end - Long.BYTES); adr += >>>>> Long.BYTES) { >>>>> > int firstHalf; >>>>> > int secondHalf; >>>>> > if (Unsafe.ADDRESS_SIZE == 4) { >>>>> > // On 32 bit platforms read two ints >>>>> instead of >>>>> > a single 64bit long firstHalf = UNSAFE.getInt(adr); >>>>> > secondHalf = UNSAFE.getInt(adr + >>>>> Integer.BYTES); >>>>> > } else { >>>>> > long value = UNSAFE.getLong(adr); >>>>> > if (ByteOrder.nativeOrder() == >>>>> > ByteOrder.LITTLE_ENDIAN) { firstHalf = (int) value; >>>>> > secondHalf = (int) (value >>> 32); >>>>> > } else { // ByteOrder.BIG_ENDIAN >>>>> > firstHalf = (int) (value >>> 32); >>>>> > secondHalf = (int) value; >>>>> > } >>>>> > } >>>>> > crc ^= firstHalf; >>>>> > if (ByteOrder.nativeOrder() == >>>>> > ByteOrder.LITTLE_ENDIAN) { crc = byteTable7[crc & 0xFF] >>>>> > ^ byteTable6[(crc >>> 8) & 0xFF] >>>>> > ^ byteTable5[(crc >>> 16) & >>>>> 0xFF] >>>>> > ^ byteTable4[crc >>> 24] >>>>> > ^ byteTable3[secondHalf & 0xFF] >>>>> > ^ byteTable2[(secondHalf >>> >>>>> 8) & 0xFF] >>>>> > ^ byteTable1[(secondHalf >>> >>>>> 16) & 0xFF] >>>>> > ^ byteTable0[secondHalf >>> 24]; >>>>> > } else { // ByteOrder.BIG_ENDIAN >>>>> > crc = byteTable0[secondHalf & 0xFF] >>>>> > ^ byteTable1[(secondHalf >>> >>>>> 8) & 0xFF] >>>>> > ^ byteTable2[(secondHalf >>> >>>>> 16) & 0xFF] >>>>> > ^ byteTable3[secondHalf >>> 24] >>>>> > ^ byteTable4[crc & 0xFF] >>>>> > ^ byteTable5[(crc >>> 8) & 0xFF] >>>>> > ^ byteTable6[(crc >>> 16) & >>>>> 0xFF] >>>>> > ^ byteTable7[crc >>> 24]; >>>>> > } >>>>> > } >>>>> > >>>>> > if (ByteOrder.nativeOrder() == >>>>> ByteOrder.BIG_ENDIAN) { >>>>> > crc = Integer.reverseBytes(crc); >>>>> > } >>>>> > } >>>>> > >>>>> > // Tail >>>>> > for (; adr < end; adr++) { >>>>> > crc = (crc >>> 8) >>>>> > ^ byteTable[(crc ^ >>>>> UNSAFE.getByte(adr)) & 0xFF]; >>>>> > } >>>>> > >>>>> > return crc; >>>>> > } >>>>> > >>>>> > >>>>> > > >>>>> > > Also, in updateBytes, the usage of >>>>> > > Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to >>>>> index a byte >>>>> > > array sounds a little scary. To be ultra portable you >>>>> could check >>>>> > > that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use >>>>> Unsafe for >>>>> > > byte arrays if it is not 1. Then use >>>>> Integer.BYTES/Long.BYTES to >>>>> > > manipulate 'offsets' instead. In updateDirectByteBuffer >>>>> it would be >>>>> > > more appropriate to use Integer.BYTES/Long.BYTES too. >>>>> > Good idea. Added a check in the initial if statement and it >>>>> will get >>>>> > automatically optimized away. >>>>> > >>>>> > > 225 firstHalf = (int) (value & >>>>> > > 0xFFFFFFFF); 226 secondHalf = (int) (value >>>>> > > >>> 32); 227 } else { // ByteOrder.BIG_ENDIAN >>>>> > > 228 firstHalf = (int) (value >>> 32); >>>>> > > 229 secondHalf = (int) (value & >>>>> > > 0xFFFFFFFF); >>>>> > > >>>>> > > firstHalf = (int) value; // this is equivalent for line 225 >>>>> > > secondHalf = (int) value; // this is equivalent for line >>>>> 229 >>>>> > Done. >>>>> > >>>>> > Here is the latest webrev, >>>>> > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>>>> >>>>> > >>>>> > Cheers, >>>>> > Staffan >>>>> >>>>> >>>>> >>>> >>>> >>> >> > From aleksey.shipilev at oracle.com Thu Oct 23 08:37:14 2014 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Thu, 23 Oct 2014 12:37:14 +0400 Subject: RFR (JAXP): 8061686: Size limits in BufferAllocator should have been final In-Reply-To: <5446AF73.2000009@oracle.com> References: <5446AF73.2000009@oracle.com> Message-ID: <5448BE3A.8060904@oracle.com> On 21.10.2014 23:09, huizhe wang wrote: > http://cr.openjdk.java.net/~joehw/jdk9/8061686/webrev/ +1 (not a Reviewer) -Aleksey From peter.levart at gmail.com Thu Oct 23 09:05:18 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 23 Oct 2014 11:05:18 +0200 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <20141022231025.00007607.ecki@zusammenkunft.net> <54484679.80402@oracle.com> <54485F5C.5000200@oracle.com> <5448B6AC.5060206@gmail.com> Message-ID: <5448C4CE.2080107@gmail.com> On 10/23/2014 10:16 AM, Stanimir Simeonoff wrote: > Unsafe is available, so the fields (array, offset) can be read directly > UNSAFE.getObject(buffer, hbOffset), UNSAFE.getObject(buffer, offsetOffset). > No need for MethodHandlers. > During class init the offsets have to be resolved, pretty much like any CAS > utilizing algorithm. > > I didn't propose it as readOnlyBuffers are very, very rarely used and even > more unlikely to be used to calculate checksums. It just makes the code > ugly. Agreed. And when Staffan introduces intrinsic, he could pass the ByteBuffer instance to it and extract the byte[] there... Peter > > Stanimir > > On Thu, Oct 23, 2014 at 11:05 AM, Peter Levart > wrote: > >> On 10/23/2014 03:52 AM, Staffan Friberg wrote: >> >>> Webrev with these last updates. Added more tests to make sure CRC32C, >>> CRC32 and Checksum default methods all are covered. >>> >>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.07 >>> >> Hi Staffan, >> >> Regarding default case: >> >> 168 } else { >> 169 byte[] b = new byte[Math.min(buffer.remaining(), 4096)]; >> 170 while (buffer.hasRemaining()) { >> 171 int length = Math.min(buffer.remaining(), b.length); >> 172 buffer.get(b, 0, length); >> 173 update(b, 0, length); >> 174 } >> 175 } >> >> >> Have you tried using get()/getInt() directly on the (ro) ByteBuffer >> instead of copying to byte[] chunks? Intuitively one would expect it >> perform faster if a redundant copy is avoided. Ah, you already told us that >> you plan to use intrinsic for CRC32C in the future, so you want to have >> "addresses" at hand. >> >> A hackish way to avoid copying in this case is to access the byte[] and >> offset using reflection. But this would have to be wrapped with >> doPrivileged() which would worsen performance for small buffers. A way to >> avoid repeated access checks is to do them at class initialization time, >> using MethodHandle(s). For example, something like: >> >> >> private static final MethodHandle bbArrayGetter; >> private static final MethodHandle bbArrayOffsetGetter; >> >> static { >> MethodHandle hbGetter; >> MethodHandle offsetGetter; >> try { >> Field hbField = ByteBuffer.class.getDeclaredField("hb"); >> Field offsetField = ByteBuffer.class. >> getDeclaredField("offset"); >> AccessController.doPrivileged(new PrivilegedAction() { >> @Override >> public Void run() { >> hbField.setAccessible(true); >> offsetField.setAccessible(true); >> return null; >> } >> }); >> hbGetter = MethodHandles.lookup().unreflectGetter(hbField); >> offsetGetter = MethodHandles.lookup(). >> unreflectGetter(offsetField); >> } catch (NoSuchFieldException | IllegalAccessException e) { >> hbGetter = null; >> offsetGetter = null; >> } >> bbArrayGetter = hbGetter; >> bbArrayOffsetGetter = offsetGetter; >> } >> >> private static byte[] getArrayOrNull(ByteBuffer bb) { >> if (bb.hasArray()) return bb.array(); >> if (bbArrayGetter != null) { >> try { >> return (byte[]) bbArrayGetter.invokeExact(bb); >> } catch (Throwable e) { >> throw new InternalError(e); >> } >> } >> return null; >> } >> >> private static int getArrayOffset(ByteBuffer bb) { >> if (bb.hasArray()) return bb.arrayOffset(); >> if (bbArrayOffsetGetter != null) { >> try { >> return (int) bbArrayOffsetGetter.invokeExact(bb); >> } catch (Throwable e) { >> throw new InternalError(e); >> } >> } >> throw new UnsupportedOperationException(); >> } >> >> >> >> Regards, Peter >> >> >>> //Staffan >>> >>> On 10/22/2014 05:37 PM, Stanimir Simeonoff wrote: >>> >>>> Hi Staffan, >>>> >>>> The readonly buffer (ByteBuffer.asReadOnlyBuffer()) don't have array() >>>> "working". >>>> You can use "int length = Math.min(buffer.remaining, b.length)" instead, >>>> same with new byte[Math.min(4096, buffer.remaining)]. Using smaller chunks >>>> will be more performance friendly than allocating/eating up a huge byte[]. >>>> If you feel like, add a test with a heap bytebuffer.asReadOnlyBuffer(). >>>> >>>> Stanimir >>>> >>>> >>>> On Thu, Oct 23, 2014 at 3:06 AM, Staffan Friberg < >>>> staffan.friberg at oracle.com > wrote: >>>> >>>> Hi, >>>> >>>> I was thinking about this earlier when I started writing the patch >>>> and then I forgot about it again. I haven't been able to figure >>>> out when the code will be executed. ByteBuffer is implemented in >>>> such a way that only the JDK can extend it and as far as I can >>>> tell you can only create 3 types of ByteBuffers (Direct, Mapped >>>> and Heap), all of which will be handled by the more efficient >>>> calls above. >>>> >>>> That said just to make the code a bit safer from OOM it is >>>> probably best to update the default method and all current >>>> implementations which all use the same pattern. >>>> >>>> A reasonable solution should be the following code >>>> >>>> byte[] b = new byte[(buffer.remaining() < 4096) >>>> ? buffer.remaining() : 4096]; >>>> while (buffer.hasRemaining()) { >>>> int length = (buffer.remaining() < b.length) >>>> ? buffer.remaining() : b.length; >>>> buffer.get(b, 0, length); >>>> update(b, 0, length); >>>> } >>>> >>>> Xueming, do you have any further comment? >>>> >>>> Regards, >>>> Staffan >>>> >>>> On 10/22/2014 03:04 PM, Stanimir Simeonoff wrote: >>>> >>>>> >>>>> On Thu, Oct 23, 2014 at 12:10 AM, Bernd Eckenfels >>>>> > wrote: >>>>> >>>>> Hello, >>>>> >>>>> just a question in the default impl: >>>>> >>>>> + } else { >>>>> + byte[] b = new byte[rem]; >>>>> + buffer.get(b); >>>>> + update(b, 0, b.length); >>>>> + } >>>>> >>>>> would it be a good idea to actually put a ceiling on the size >>>>> of the >>>>> array which is processed at once? >>>>> This is an excellent catch. >>>>> Should not be too large, probably 4k or so. >>>>> >>>>> Stanimir >>>>> >>>>> >>>>> Am Tue, 21 Oct 2014 10:28:50 -0700 >>>>> schrieb Staffan Friberg >>>> >: >>>>> >>>>> >>>>> > Hi Peter, >>>>> > >>>>> > Thanks for the comments.. >>>>> > > >>>>> > > 217 if (Unsafe.ADDRESS_SIZE == 4) { >>>>> > > 218 // On 32 bit platforms read two >>>>> ints >>>>> > > instead of a single 64bit long >>>>> > > >>>>> > > When you're reading from byte[] using Unsafe >>>>> (updateBytes), you >>>>> > > have the option of reading 64bit values on 64bit >>>>> platforms. When >>>>> > > you're reading from DirectByteBuffer memory >>>>> > > (updateDirectByteBuffer), you're only using 32bit reads. >>>>> > I will add a comment in the code for this decision. The >>>>> reason is >>>>> > that read a long results in slightly worse performance in >>>>> this case, >>>>> > in updateBytes it is faster. I was able to get it to run >>>>> slightly >>>>> > faster by working directly with the address instead of >>>>> always adding >>>>> > address + off, but this makes things worse in the 32bit >>>>> case since >>>>> > all calculation will now be using long variables. So using >>>>> the getInt >>>>> > as in the current code feels like the best solution as it >>>>> strikes the >>>>> > best balance between 32 and 64bit. Below is how >>>>> updateByteBuffer >>>>> > looked with the rewrite I mentioned. >>>>> > >>>>> > >>>>> > ong address = ((DirectBuffer) buffer).address(); >>>>> > crc = updateDirectByteBuffer(crc, address + pos, address >>>>> + limit); >>>>> > >>>>> > >>>>> > private static int updateDirectByteBuffer(int crc, >>>>> long adr, >>>>> > long end) { >>>>> > >>>>> > // Do only byte reads for arrays so short they >>>>> can't be >>>>> > aligned if (end - adr >= 8) { >>>>> > >>>>> > // align on 8 bytes >>>>> > int alignLength = (8 - (int) (adr & 0x7)) & 0x7; >>>>> > for (long alignEnd = adr + alignLength; adr < >>>>> alignEnd; >>>>> > adr++) { crc = (crc >>> 8) >>>>> > ^ byteTable[(crc ^ >>>>> UNSAFE.getByte(adr)) & >>>>> > 0xFF]; } >>>>> > >>>>> > if (ByteOrder.nativeOrder() == >>>>> ByteOrder.BIG_ENDIAN) { >>>>> > crc = Integer.reverseBytes(crc); >>>>> > } >>>>> > >>>>> > // slicing-by-8 >>>>> > for (; adr < (end - Long.BYTES); adr += >>>>> Long.BYTES) { >>>>> > int firstHalf; >>>>> > int secondHalf; >>>>> > if (Unsafe.ADDRESS_SIZE == 4) { >>>>> > // On 32 bit platforms read two ints >>>>> instead of >>>>> > a single 64bit long firstHalf = UNSAFE.getInt(adr); >>>>> > secondHalf = UNSAFE.getInt(adr + >>>>> Integer.BYTES); >>>>> > } else { >>>>> > long value = UNSAFE.getLong(adr); >>>>> > if (ByteOrder.nativeOrder() == >>>>> > ByteOrder.LITTLE_ENDIAN) { firstHalf = (int) value; >>>>> > secondHalf = (int) (value >>> 32); >>>>> > } else { // ByteOrder.BIG_ENDIAN >>>>> > firstHalf = (int) (value >>> 32); >>>>> > secondHalf = (int) value; >>>>> > } >>>>> > } >>>>> > crc ^= firstHalf; >>>>> > if (ByteOrder.nativeOrder() == >>>>> > ByteOrder.LITTLE_ENDIAN) { crc = byteTable7[crc & 0xFF] >>>>> > ^ byteTable6[(crc >>> 8) & 0xFF] >>>>> > ^ byteTable5[(crc >>> 16) & 0xFF] >>>>> > ^ byteTable4[crc >>> 24] >>>>> > ^ byteTable3[secondHalf & 0xFF] >>>>> > ^ byteTable2[(secondHalf >>> >>>>> 8) & 0xFF] >>>>> > ^ byteTable1[(secondHalf >>> >>>>> 16) & 0xFF] >>>>> > ^ byteTable0[secondHalf >>> 24]; >>>>> > } else { // ByteOrder.BIG_ENDIAN >>>>> > crc = byteTable0[secondHalf & 0xFF] >>>>> > ^ byteTable1[(secondHalf >>> >>>>> 8) & 0xFF] >>>>> > ^ byteTable2[(secondHalf >>> >>>>> 16) & 0xFF] >>>>> > ^ byteTable3[secondHalf >>> 24] >>>>> > ^ byteTable4[crc & 0xFF] >>>>> > ^ byteTable5[(crc >>> 8) & 0xFF] >>>>> > ^ byteTable6[(crc >>> 16) & 0xFF] >>>>> > ^ byteTable7[crc >>> 24]; >>>>> > } >>>>> > } >>>>> > >>>>> > if (ByteOrder.nativeOrder() == >>>>> ByteOrder.BIG_ENDIAN) { >>>>> > crc = Integer.reverseBytes(crc); >>>>> > } >>>>> > } >>>>> > >>>>> > // Tail >>>>> > for (; adr < end; adr++) { >>>>> > crc = (crc >>> 8) >>>>> > ^ byteTable[(crc ^ >>>>> UNSAFE.getByte(adr)) & 0xFF]; >>>>> > } >>>>> > >>>>> > return crc; >>>>> > } >>>>> > >>>>> > >>>>> > > >>>>> > > Also, in updateBytes, the usage of >>>>> > > Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to >>>>> index a byte >>>>> > > array sounds a little scary. To be ultra portable you >>>>> could check >>>>> > > that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to use >>>>> Unsafe for >>>>> > > byte arrays if it is not 1. Then use >>>>> Integer.BYTES/Long.BYTES to >>>>> > > manipulate 'offsets' instead. In updateDirectByteBuffer >>>>> it would be >>>>> > > more appropriate to use Integer.BYTES/Long.BYTES too. >>>>> > Good idea. Added a check in the initial if statement and it >>>>> will get >>>>> > automatically optimized away. >>>>> > >>>>> > > 225 firstHalf = (int) (value & >>>>> > > 0xFFFFFFFF); 226 secondHalf = (int) (value >>>>> > > >>> 32); 227 } else { // ByteOrder.BIG_ENDIAN >>>>> > > 228 firstHalf = (int) (value >>> 32); >>>>> > > 229 secondHalf = (int) (value & >>>>> > > 0xFFFFFFFF); >>>>> > > >>>>> > > firstHalf = (int) value; // this is equivalent for line 225 >>>>> > > secondHalf = (int) value; // this is equivalent for line 229 >>>>> > Done. >>>>> > >>>>> > Here is the latest webrev, >>>>> > http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>>>> >>>>> > >>>>> > Cheers, >>>>> > Staffan >>>>> >>>>> >>>>> >>>> From paul.sandoz at oracle.com Thu Oct 23 09:08:21 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 23 Oct 2014 11:08:21 +0200 Subject: RFR: 8061830: [asm] refresh internal ASM version v5.0.3 In-Reply-To: <5447C892.6040009@oracle.com> References: <5447C892.6040009@oracle.com> Message-ID: <9F5259FD-EDB5-4F99-8008-9670DD2FD676@oracle.com> On Oct 22, 2014, at 5:09 PM, Kumar Srinivasan wrote: > Hello, > > Please review fix for JDK-8061830, this is merely a refresh of the existing source > base from upstream ObjectWeb/ASM, the webrev is here: > http://cr.openjdk.java.net/~ksrini/8061830/webrev.00/ > +1 Paul. From aleksey.shipilev at oracle.com Thu Oct 23 09:54:34 2014 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Thu, 23 Oct 2014 13:54:34 +0400 Subject: Loading classes with many methods is very expensive In-Reply-To: References: Message-ID: <5448D05A.2090703@oracle.com> Hi Martin, On 23.10.2014 02:53, Martin Buchholz wrote: > If you have a class with ~64k methods with a superclass that also has ~64k > methods, class loading that single class will cost you ~30sec and calling > Class.getMethods another ~10sec. Both are unacceptably slow. I think both > are due to O(N^2) algorithms, the first in hotspot, and the second in > Class.java. Interesting, this is the profile: http://cr.openjdk.java.net/~shade/8061949/calltree-1.txt ...and I submitted two issues as the result of this quick performance investigation. We also need better benchmarks for this. https://bugs.openjdk.java.net/browse/JDK-8061949 https://bugs.openjdk.java.net/browse/JDK-8061950 Nashorn also generates the mammoth classes on many cases, and therefore solving both should (at least marginally) help there as well. -Aleksey. From konstantin.shefov at oracle.com Thu Oct 23 11:25:22 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Thu, 23 Oct 2014 15:25:22 +0400 Subject: [9] Review request : JDK-8059070: [TESTBUG] java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java failed - timeout In-Reply-To: <5440E39C.8070001@oracle.com> References: <543D1DEE.8030206@oracle.com> <543F8520.9090408@oracle.com> <8F9DD322-1793-4739-8155-61CE7D2C5AAB@oracle.com> <543F9800.7040406@oracle.com> <543FC71F.8020504@oracle.com> <5440E39C.8070001@oracle.com> Message-ID: <5448E5A2.9030804@oracle.com> Gently reminder On 17.10.2014 13:38, Konstantin Shefov wrote: > Hi, > > I have updated the webrev: > http://cr.openjdk.java.net/~kshefov/8059070/webrev.01/ > > -Konstantin > > 16.10.2014 17:24, Igor Ignatyev ?????: >> Konstantin, >> >> I haven't looked at code religiously, so I wouldn't say that I have >> reviewed it. however I have some comments, please see them inline. >> >> On 10/16/2014 02:03 PM, Konstantin Shefov wrote: >>> Paul, >>> >>> Thanks for reviewing >>> >>> In the jtreg scripts of the three existing LFCaching tests timeout is >>> set explicitly to 300 seconds. The file currently being changed is >>> not a >>> test itself, it is parent class of tests. >>> In fact we can unset this explicit timeout and use the current fix >>> together with default JTREG timeout and jtreg timeout factor option. >>> These test cases are randomly generated, so the more iterations, the >>> better, but in fact we need at least one iteration. >>> >>> As for "if (avgIterTime > 2 * remainTime)", I think 2 is enough. >>> >>> -Konstantin >>> >>> On 16.10.2014 13:30, Paul Sandoz wrote: >>>> On Oct 16, 2014, at 10:43 AM, Konstantin Shefov >>>> wrote: >>>> >>>>> Gently reminder >>>>> >>>>> On 14.10.2014 16:58, Konstantin Shefov wrote: >>>>>> Hello, >>>>>> >>>>>> Please review the test bug fix >>>>>> https://bugs.openjdk.java.net/browse/JDK-8059070 >>>>>> Webrev is http://cr.openjdk.java.net/~kshefov/8059070/webrev.00/ >>>>>> >>>> 45 private static final long TIMEOUT = 300000; >>>> >>>> Does jtreg define a system property for this value? and is 300s the >>>> same as what jtreg defines as the default? >> unfortunately, jtreg doesn't define a property for timeout, but I >> think it should do. we need to file an RFE against jtreg to add such >> a property and an RFE against these tests/testlibrary to use this >> property. could you please file them? >>>> >>>> The online documentation (jtreg -onlineHelp) says the default is 2 >>>> minutes, but that might be out of date. >>>> >>>> Might be more readable to use: >>>> >>>> TimeUnit.SECONDS.toMillis(300); >>>> >>>> >>>> 143 long passedTime = new Date().getTime() - startTime; >>>> >>>> Why don't you use System.currentTimeMillis() instead of "new >>>> Date().getTime()" ? >>>> >>>> >>>> 145 double timeoutFactor = new >>>> Double(System.getProperty("test.timeout.factor", "1.0")); >>>> >>>> You can that pull out into a static and perhaps merge with TIMEOUT. >> + you should use jdk.testlibrary.Utils::adjustTimeout instead of >> writing this code again. >>>> >>>> >>>> 147 if (avgIterTime > 2 * remainTime) { >>>> >>>> That seems sufficient but it will be interesting to see if >>>> intermittent failures still occur due to high variance. >>>> >>>> Paul. >>> >> >> >> Igor > From claes.redestad at oracle.com Thu Oct 23 13:26:38 2014 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 23 Oct 2014 15:26:38 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <544851C4.70508@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> <544662EB.2040907@oracle.com> <54482324.3060306@oracle.com> <54484497.3090705@oracle.com> <544851C4.70508@oracle.com> Message-ID: <5449020E.9010803@oracle.com> On 10/23/2014 02:54 AM, Mandy Chung wrote: > > On 10/22/2014 4:58 PM, Claes Redestad wrote: >> >>> >>> This test uses a special class loader that delegates to null class >>> loader only. Since you have the verification in place, it'd be good >>> to also call Package.getPackage and Package.getPackages to verify >>> that the same "package2" instance is returned. As a sanity check, >>> you could check "java.lang" package must be present. >> >> I've added some sanity checks as suggested. Sadly, it seems that >> since the application classloader will define and load package2 first >> in this test, there'll always be a Package defined in the >> ClassLoader.pkgs that will mask the Package instance in Package.pkgs >> when retrieved via the public methods in Package. > > Can you remove package2/Class2.class after you create the jar files? Sorry for the confusion. I realized I did some of my test development on an unpatched JDK and got caught up in a subtle issue. Prior to the changes proposed, calling into Package.getSystemPackages() actually created new Package objects on each call(!!), breaking the assumption that only one Package object will ever be defined. The proposed patch ensures we don't create new objects and that only one Package object can ever be created for a system package. This bug(?) was partially hidden by the fact that calling Package.getPackage() cached Package objects in the ClassLoader package maps, thus subsequent calls to Package.getPackages() would provide identical objects on subsequent calls. I've updated the test to verify Package identity (which it fails to do on an unpatched JDK). > >> If JDK-8061804 is resolved, we could change to check for identity in >> the Package.getPackages() case, which would improve the specificness >> of the test... For now, perhaps we could trick things in this test >> and put our dummy class into java.lang in our test here and ensure >> that the package retrieved is identical. Worth the hassle? > > What I meant is to check if the returned Package contains "java.lang" > package that always exists in the system packages. You don't need to > put a dummy class in java.lang to get "java.lang" Package since it > must be defined in the running VM. e.g. you can refactor line 169-176 > to a findPackage method that returns Package matching the given > package name such that in line 164 you can call > findPackage("java.lang") that should return non-null. > http://cr.openjdk.java.net/~redestad/8060130/webrev.10 /Claes From chris.hegarty at oracle.com Thu Oct 23 13:28:20 2014 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Thu, 23 Oct 2014 14:28:20 +0100 Subject: Review request: JDK-8043277: Update jdk regression tests to extend the default security policy instead of override In-Reply-To: <54485505.4030002@oracle.com> References: <54485505.4030002@oracle.com> Message-ID: This looks good to me Mandy, and nice to see the superfluous grants being removed. -Chris. On 23 Oct 2014, at 02:08, Mandy Chung wrote: > jtreg policy option overrides the system security policy file and hence > some existing test policy files have to duplicate the entries to grant > permissions for JDK. > > jtreg has been enhanced to provide "java.security.policy" option to > specify using the specified policy file in the same way as > -Djava.security.policy= to extend the system security > policy. The current jtreg "policy" option actually translates > to -Djava.security.policy== (double equals) to > override the system security policy. > > This patch updates several tests to use the new java.security.policy > options along with removing the duplicated entries from the test policy files. > > Webrev: > http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8043277/webrev.00/ > > thanks > Mandy > [1] https://bugs.openjdk.java.net/browse/CODETOOLS-7900898 > From peter.levart at gmail.com Thu Oct 23 13:37:02 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 23 Oct 2014 15:37:02 +0200 Subject: Loading classes with many methods is very expensive In-Reply-To: References: Message-ID: <5449047E.4030004@gmail.com> On 10/23/2014 01:57 AM, Stanimir Simeonoff wrote: > Class.java can easily be improved by adding an auxiliary HasMap Integer/int[]> indexing the position in the array by name and then checking > only few overloaded signatures in case of a match. > The auxiliary map can be deployed only past some threshold of methods, so > it should not affect the common case. > > Alternatively sorting the array and using binary search is quite trivial to > implement as well. Java Class.getMethods() implementation is complicated by the fact that, although not specified, the order of methods in returned array is important. Once it changed, if I remember correctly, and broke many programs, so it had to be restored... Peter > > Btw, really nice benchmark. > > Stanimir > > > On Thu, Oct 23, 2014 at 1:53 AM, Martin Buchholz > wrote: > >> Here at Google we have both kinds of scalability problems - loading classes >> from a classpath with 10,000 jars, and loading a single class file packed >> with the maximal number of methods. This message is about the latter. >> >> If you have a class with ~64k methods with a superclass that also has ~64k >> methods, class loading that single class will cost you ~30sec and calling >> Class.getMethods another ~10sec. Both are unacceptably slow. I think both >> are due to O(N^2) algorithms, the first in hotspot, and the second in >> Class.java. >> >> I have the start of a fix for Class.java, but it makes the common case >> slower. A really good fix is harder to find. In general, I think >> Class.java could benefit from some performance-oriented rework. Is anyone >> else working on class loading performance, especially in hotspot? >> >> Here's the benchmark (that could perhaps be integrated into openjdk even >> without a fix) >> >> >> http://cr.openjdk.java.net/~martin/webrevs/openjdk9/Class.getMethods-benchmark/test/java/lang/Class/getMethods/ManyMethodsBenchmark.java.html >> >> Base class load time: 186.44 ms >> getDeclaredMethods: Methods: 65521, Total time: 43.27 ms, Time per method: >> 0.0007 ms >> getMethods : Methods: 65530, Total time: 60.82 ms, Time per method: >> 0.0009 ms >> Derived class load time: 33440.13 ms >> getDeclaredMethods: Methods: 65521, Total time: 39.71 ms, Time per method: >> 0.0006 ms >> getMethods : Methods: 65530, Total time: 11582.54 ms, Time per >> method: 0.1768 ms >> From Alan.Bateman at oracle.com Thu Oct 23 13:40:47 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 23 Oct 2014 14:40:47 +0100 Subject: Review request: JDK-8043277: Update jdk regression tests to extend the default security policy instead of override In-Reply-To: <54485505.4030002@oracle.com> References: <54485505.4030002@oracle.com> Message-ID: <5449055F.30305@oracle.com> On 23/10/2014 02:08, Mandy Chung wrote: > jtreg policy option overrides the system security policy file and hence > some existing test policy files have to duplicate the entries to grant > permissions for JDK. > This looks okay to me too. I think this will be the first use of a jtreg4.1-b10 feature and maybe someone should send a note to jdk9-dev to tell folks that they will need an up-to-date jtreg in order to test jdk9/dev. -Alan From karen.kinnear at oracle.com Thu Oct 23 13:48:13 2014 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Thu, 23 Oct 2014 09:48:13 -0400 Subject: Loading classes with many methods is very expensive In-Reply-To: <5449047E.4030004@gmail.com> References: <5449047E.4030004@gmail.com> Message-ID: <23F1EECE-57CA-4EAA-909C-54FE727BD932@oracle.com> Peter, Which hotspot algorithm is the one you identified as slow? Would that be for loading the class or for Class.getMethods? thanks, Karen On Oct 23, 2014, at 9:37 AM, Peter Levart wrote: > On 10/23/2014 01:57 AM, Stanimir Simeonoff wrote: >> Class.java can easily be improved by adding an auxiliary HasMap> Integer/int[]> indexing the position in the array by name and then checking >> only few overloaded signatures in case of a match. >> The auxiliary map can be deployed only past some threshold of methods, so >> it should not affect the common case. >> >> Alternatively sorting the array and using binary search is quite trivial to >> implement as well. > > Java Class.getMethods() implementation is complicated by the fact that, although not specified, the order of methods in returned array is important. Once it changed, if I remember correctly, and broke many programs, so it had to be restored... > > Peter > >> >> Btw, really nice benchmark. >> >> Stanimir >> >> >> On Thu, Oct 23, 2014 at 1:53 AM, Martin Buchholz >> wrote: >> >>> Here at Google we have both kinds of scalability problems - loading classes >>> from a classpath with 10,000 jars, and loading a single class file packed >>> with the maximal number of methods. This message is about the latter. >>> >>> If you have a class with ~64k methods with a superclass that also has ~64k >>> methods, class loading that single class will cost you ~30sec and calling >>> Class.getMethods another ~10sec. Both are unacceptably slow. I think both >>> are due to O(N^2) algorithms, the first in hotspot, and the second in >>> Class.java. >>> >>> I have the start of a fix for Class.java, but it makes the common case >>> slower. A really good fix is harder to find. In general, I think >>> Class.java could benefit from some performance-oriented rework. Is anyone >>> else working on class loading performance, especially in hotspot? >>> >>> Here's the benchmark (that could perhaps be integrated into openjdk even >>> without a fix) >>> >>> >>> http://cr.openjdk.java.net/~martin/webrevs/openjdk9/Class.getMethods-benchmark/test/java/lang/Class/getMethods/ManyMethodsBenchmark.java.html >>> >>> Base class load time: 186.44 ms >>> getDeclaredMethods: Methods: 65521, Total time: 43.27 ms, Time per method: >>> 0.0007 ms >>> getMethods : Methods: 65530, Total time: 60.82 ms, Time per method: >>> 0.0009 ms >>> Derived class load time: 33440.13 ms >>> getDeclaredMethods: Methods: 65521, Total time: 39.71 ms, Time per method: >>> 0.0006 ms >>> getMethods : Methods: 65530, Total time: 11582.54 ms, Time per >>> method: 0.1768 ms >>> > From stanimir at riflexo.com Thu Oct 23 14:17:07 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Thu, 23 Oct 2014 17:17:07 +0300 Subject: Loading classes with many methods is very expensive In-Reply-To: <5449047E.4030004@gmail.com> References: <5449047E.4030004@gmail.com> Message-ID: I was under the impression the declaring order has been abandoned in 1.7 which I considered quite a let down as allowed ordering the function calls in JMX in a non-chaotic way. On Thu, Oct 23, 2014 at 4:37 PM, Peter Levart wrote: > On 10/23/2014 01:57 AM, Stanimir Simeonoff wrote: > >> Class.java can easily be improved by adding an auxiliary HasMap> Integer/int[]> indexing the position in the array by name and then >> checking >> only few overloaded signatures in case of a match. >> The auxiliary map can be deployed only past some threshold of methods, so >> it should not affect the common case. >> >> Alternatively sorting the array and using binary search is quite trivial >> to >> implement as well. >> > > Java Class.getMethods() implementation is complicated by the fact that, > although not specified, the order of methods in returned array is > important. Once it changed, if I remember correctly, and broke many > programs, so it had to be restored... > > Peter > > > >> Btw, really nice benchmark. >> >> Stanimir >> >> >> On Thu, Oct 23, 2014 at 1:53 AM, Martin Buchholz >> wrote: >> >> Here at Google we have both kinds of scalability problems - loading >>> classes >>> from a classpath with 10,000 jars, and loading a single class file packed >>> with the maximal number of methods. This message is about the latter. >>> >>> If you have a class with ~64k methods with a superclass that also has >>> ~64k >>> methods, class loading that single class will cost you ~30sec and calling >>> Class.getMethods another ~10sec. Both are unacceptably slow. I think >>> both >>> are due to O(N^2) algorithms, the first in hotspot, and the second in >>> Class.java. >>> >>> I have the start of a fix for Class.java, but it makes the common case >>> slower. A really good fix is harder to find. In general, I think >>> Class.java could benefit from some performance-oriented rework. Is >>> anyone >>> else working on class loading performance, especially in hotspot? >>> >>> Here's the benchmark (that could perhaps be integrated into openjdk even >>> without a fix) >>> >>> >>> http://cr.openjdk.java.net/~martin/webrevs/openjdk9/Class. >>> getMethods-benchmark/test/java/lang/Class/getMethods/ >>> ManyMethodsBenchmark.java.html >>> >>> Base class load time: 186.44 ms >>> getDeclaredMethods: Methods: 65521, Total time: 43.27 ms, Time per >>> method: >>> 0.0007 ms >>> getMethods : Methods: 65530, Total time: 60.82 ms, Time per >>> method: >>> 0.0009 ms >>> Derived class load time: 33440.13 ms >>> getDeclaredMethods: Methods: 65521, Total time: 39.71 ms, Time per >>> method: >>> 0.0006 ms >>> getMethods : Methods: 65530, Total time: 11582.54 ms, Time per >>> method: 0.1768 ms >>> >>> > From joel.franck at oracle.com Thu Oct 23 15:06:17 2014 From: joel.franck at oracle.com (=?windows-1252?Q?Joel_Borggr=E9n-Franck?=) Date: Thu, 23 Oct 2014 17:06:17 +0200 Subject: Loading classes with many methods is very expensive In-Reply-To: References: Message-ID: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> Hi Martin, On 23 okt 2014, at 00:53, Martin Buchholz wrote: > Here at Google we have both kinds of scalability problems - loading classes > from a classpath with 10,000 jars, and loading a single class file packed > with the maximal number of methods. This message is about the latter. > > If you have a class with ~64k methods with a superclass that also has ~64k > methods, class loading that single class will cost you ~30sec and calling > Class.getMethods another ~10sec. Both are unacceptably slow. I think both > are due to O(N^2) algorithms, the first in hotspot, and the second in > Class.java. Throw in lots of interfaces with lots of default methods and i suspect this can get even worse. I spent some time thinking about this when fixing an issue with reflection for default methods, reviewed here [1]. > I have the start of a fix for Class.java, but it makes the common case > slower. A really good fix is harder to find. In general, I think > Class.java could benefit from some performance-oriented rework. Is anyone > else working on class loading performance, especially in hotspot? > We have been thinking about replacing the duplication of the method lookup logic in j.l.Class with a call to the VM which should already have the information needed. I?m not sure why the logic was duplicated on the library side way back when this was written. This isn?t something we are actively working on though. As an aside, I often found myself wanting for the actual method descriptor when working with this, but considering there can be *a lot* of instances of Method/Constructor adding a descriptor field to Executable wasn?t an obvious win to me. cheers /Joel [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-May/026782.html From peter.levart at gmail.com Thu Oct 23 15:15:49 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 23 Oct 2014 17:15:49 +0200 Subject: Loading classes with many methods is very expensive In-Reply-To: <23F1EECE-57CA-4EAA-909C-54FE727BD932@oracle.com> References: <5449047E.4030004@gmail.com> <23F1EECE-57CA-4EAA-909C-54FE727BD932@oracle.com> Message-ID: <54491BA5.5030902@gmail.com> On 10/23/2014 03:48 PM, Karen Kinnear wrote: > Peter, > > Which hotspot algorithm is the one you identified as slow? Would that be > for loading the class or for Class.getMethods? > > thanks, > Karen Martin did it. And Alexey profiled it. I just noted that Java part of Class.getMethods(), should it be rewritten, might be required to keep the order of Method objects returned in the array although it is not specified. Class.getMethods() is based on native Class methods which return declared methods. They are not slow. The Java algorithm that combines those into a compiled list of public methods (which includes inherited from supertypes) is slow for large number of methods since it is O(n^2). Regards, Peter > > On Oct 23, 2014, at 9:37 AM, Peter Levart wrote: > >> On 10/23/2014 01:57 AM, Stanimir Simeonoff wrote: >>> Class.java can easily be improved by adding an auxiliary HasMap>> Integer/int[]> indexing the position in the array by name and then checking >>> only few overloaded signatures in case of a match. >>> The auxiliary map can be deployed only past some threshold of methods, so >>> it should not affect the common case. >>> >>> Alternatively sorting the array and using binary search is quite trivial to >>> implement as well. >> Java Class.getMethods() implementation is complicated by the fact that, although not specified, the order of methods in returned array is important. Once it changed, if I remember correctly, and broke many programs, so it had to be restored... >> >> Peter >> >>> Btw, really nice benchmark. >>> >>> Stanimir >>> >>> >>> On Thu, Oct 23, 2014 at 1:53 AM, Martin Buchholz >>> wrote: >>> >>>> Here at Google we have both kinds of scalability problems - loading classes >>>> from a classpath with 10,000 jars, and loading a single class file packed >>>> with the maximal number of methods. This message is about the latter. >>>> >>>> If you have a class with ~64k methods with a superclass that also has ~64k >>>> methods, class loading that single class will cost you ~30sec and calling >>>> Class.getMethods another ~10sec. Both are unacceptably slow. I think both >>>> are due to O(N^2) algorithms, the first in hotspot, and the second in >>>> Class.java. >>>> >>>> I have the start of a fix for Class.java, but it makes the common case >>>> slower. A really good fix is harder to find. In general, I think >>>> Class.java could benefit from some performance-oriented rework. Is anyone >>>> else working on class loading performance, especially in hotspot? >>>> >>>> Here's the benchmark (that could perhaps be integrated into openjdk even >>>> without a fix) >>>> >>>> >>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk9/Class.getMethods-benchmark/test/java/lang/Class/getMethods/ManyMethodsBenchmark.java.html >>>> >>>> Base class load time: 186.44 ms >>>> getDeclaredMethods: Methods: 65521, Total time: 43.27 ms, Time per method: >>>> 0.0007 ms >>>> getMethods : Methods: 65530, Total time: 60.82 ms, Time per method: >>>> 0.0009 ms >>>> Derived class load time: 33440.13 ms >>>> getDeclaredMethods: Methods: 65521, Total time: 39.71 ms, Time per method: >>>> 0.0006 ms >>>> getMethods : Methods: 65530, Total time: 11582.54 ms, Time per >>>> method: 0.1768 ms >>>> From peter.levart at gmail.com Thu Oct 23 15:44:21 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 23 Oct 2014 17:44:21 +0200 Subject: Loading classes with many methods is very expensive In-Reply-To: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> Message-ID: <54492255.3040108@gmail.com> On 10/23/2014 05:06 PM, Joel Borggr?n-Franck wrote: > Hi Martin, > > On 23 okt 2014, at 00:53, Martin Buchholz wrote: > >> Here at Google we have both kinds of scalability problems - loading classes >> from a classpath with 10,000 jars, and loading a single class file packed >> with the maximal number of methods. This message is about the latter. >> >> If you have a class with ~64k methods with a superclass that also has ~64k >> methods, class loading that single class will cost you ~30sec and calling >> Class.getMethods another ~10sec. Both are unacceptably slow. I think both >> are due to O(N^2) algorithms, the first in hotspot, and the second in >> Class.java. > Throw in lots of interfaces with lots of default methods and i suspect this can get even worse. I spent some time thinking about this when fixing an issue with reflection for default methods, reviewed here [1]. Hi Joel, I may have found another issue: interface A4 extends B4, C4 {} interface B4 extends D4 { void m(); } interface C4 extends D4 {} interface D4 { void m(); } Calling A4.class.getMethods() returns B4.m, D4.m - this is supposed to be OK as per JDK 7 spec. Changing both methods to default methods: interface A5 extends B5, C5 {} interface B5 extends D5 { default void m() {} } interface C5 extends D5 {} interface D5 { default void m() {}; } A5.class.getMethods() returns B5.m - this is new in JDK 8 spec for default methods. Now see the following two examples (just one method is default, the other is abstract): interface A6 extends B6, C6 {} interface B6 extends D6 { void m(); } interface C6 extends D6 {} interface D6 { default void m() {}; } A6.class.getMethods() returns B6.m, D6.m // B.m, D.m interface A7 extends B7, C7 {} interface B7 extends D7 { default void m() {} } interface C7 extends D7 {} interface D7 { void m(); } A7.class.getMethods() returns B7.m Do last two examples give expected result? Why are A6 and A7 different? What is the rule here? I would expect A6.class.getMethods() only return the D6.m default method. This is the non-abstract method that gets used when implementing an interface. If A6 example is really showing a bug, then I may have a solution that fixes it *and* is faster than current code for getMethods() + it is O(n)... Is there a test that validates correctness of getMethods() or at least a set of interfaces and/or classes to exercise the algorithm and compare it to a different implementation? > >> I have the start of a fix for Class.java, but it makes the common case >> slower. A really good fix is harder to find. In general, I think >> Class.java could benefit from some performance-oriented rework. Is anyone >> else working on class loading performance, especially in hotspot? >> > We have been thinking about replacing the duplication of the method lookup logic in j.l.Class with a call to the VM which should already have the information needed. I?m not sure why the logic was duplicated on the library side way back when this was written. This isn?t something we are actively working on though. Does VM have enough information to quickly compile the list of public methods (getMethods() equivalent) or only to look-up the public method (getMethod() equivalent)? Regards, Peter > > As an aside, I often found myself wanting for the actual method descriptor when working with this, but considering there can be *a lot* of instances of Method/Constructor adding a descriptor field to Executable wasn?t an obvious win to me. > > cheers > /Joel > > [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-May/026782.html From peter.levart at gmail.com Thu Oct 23 16:01:32 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 23 Oct 2014 18:01:32 +0200 Subject: Loading classes with many methods is very expensive In-Reply-To: <54492255.3040108@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> Message-ID: <5449265C.2050307@gmail.com> On 10/23/2014 05:44 PM, Peter Levart wrote: > interface A6 extends B6, C6 {} > interface B6 extends D6 { void m(); } > interface C6 extends D6 {} > interface D6 { default void m() {}; } > > A6.class.getMethods() returns B6.m, D6.m Ah, B6.m re-abstracts the default method D6.m. I can see the rule here. Never mind my previous question. Regards, Peter From paul.sandoz at oracle.com Thu Oct 23 16:04:08 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 23 Oct 2014 18:04:08 +0200 Subject: [9] Review request : JDK-8059070: [TESTBUG] java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java failed - timeout In-Reply-To: <5448E5A2.9030804@oracle.com> References: <543D1DEE.8030206@oracle.com> <543F8520.9090408@oracle.com> <8F9DD322-1793-4739-8155-61CE7D2C5AAB@oracle.com> <543F9800.7040406@oracle.com> <543FC71F.8020504@oracle.com> <5440E39C.8070001@oracle.com> <5448E5A2.9030804@oracle.com> Message-ID: On Oct 23, 2014, at 1:25 PM, Konstantin Shefov wrote: > Gently reminder > > On 17.10.2014 13:38, Konstantin Shefov wrote: >> Hi, >> >> I have updated the webrev: >> http://cr.openjdk.java.net/~kshefov/8059070/webrev.01/ >> +1 Sorry for the delay, Paul. From joel.franck at oracle.com Thu Oct 23 17:56:09 2014 From: joel.franck at oracle.com (=?windows-1252?Q?Joel_Borggr=E9n-Franck?=) Date: Thu, 23 Oct 2014 19:56:09 +0200 Subject: Loading classes with many methods is very expensive In-Reply-To: <54492255.3040108@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> Message-ID: On 23 Oct 2014, at 17:44, Peter Levart wrote: > > Is there a test that validates correctness of getMethods() or at least a set of interfaces and/or classes to exercise the algorithm and compare it to a different implementation? > There is :) http://hg.openjdk.java.net/jdk9/dev/jdk/file/8b4aa51c8744/test/java/lang/reflect/DefaultMethodMembers/FilterNotMostSpecific.java IIRC 75% or so of the cases passes both before and after the change. I have highlighted a number of interesting cases with line comments. cheers /Joel From mandy.chung at oracle.com Thu Oct 23 18:10:27 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Thu, 23 Oct 2014 11:10:27 -0700 Subject: Review request: JDK-8043277: Update jdk regression tests to extend the default security policy instead of override In-Reply-To: <54485505.4030002@oracle.com> References: <54485505.4030002@oracle.com> Message-ID: <54494493.8000002@oracle.com> Sean, I have included a few security tests in this patch: http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8043277/webrev.01/ Mandy On 10/22/14 6:08 PM, Mandy Chung wrote: > jtreg policy option overrides the system security policy file and hence > some existing test policy files have to duplicate the entries to grant > permissions for JDK. > > jtreg has been enhanced to provide "java.security.policy" option to > specify using the specified policy file in the same way as > -Djava.security.policy= to extend the system security > policy. The current jtreg "policy" option actually translates > to -Djava.security.policy== (double equals) to > override the system security policy. > > This patch updates several tests to use the new java.security.policy > options along with removing the duplicated entries from the test > policy files. > > Webrev: > http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8043277/webrev.00/ > > thanks > Mandy > [1] https://bugs.openjdk.java.net/browse/CODETOOLS-7900898 > From sean.mullan at oracle.com Thu Oct 23 21:06:11 2014 From: sean.mullan at oracle.com (Sean Mullan) Date: Thu, 23 Oct 2014 17:06:11 -0400 Subject: Review request: JDK-8043277: Update jdk regression tests to extend the default security policy instead of override In-Reply-To: <54494493.8000002@oracle.com> References: <54485505.4030002@oracle.com> <54494493.8000002@oracle.com> Message-ID: <54496DC3.1060405@oracle.com> On 10/23/2014 02:10 PM, Mandy Chung wrote: > Sean, > > I have included a few security tests in this patch: > http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8043277/webrev.01/ Looks good. --Sean From staffan.friberg at oracle.com Thu Oct 23 21:40:07 2014 From: staffan.friberg at oracle.com (Staffan Friberg) Date: Thu, 23 Oct 2014 14:40:07 -0700 Subject: RFR JDK-6321472: Add CRC-32C API In-Reply-To: <5448C4CE.2080107@gmail.com> References: <544073EA.3060304@oracle.com> <5440F803.2000406@oracle.com> <544166B8.8090103@oracle.com> <5441A192.8090602@gmail.com> <544697D2.6080301@oracle.com> <20141022231025.00007607.ecki@zusammenkunft.net> <54484679.80402@oracle.com> <54485F5C.5000200@oracle.com> <5448B6AC.5060206@gmail.com> <5448C4CE.2080107@gmail.com> Message-ID: <544975B7.7050501@oracle.com> Hi, Using unsafe to read fields will make the code very brittle and require us to further detect and buffer types and which fields to read and handle. Currently this seems to be a rather uncommon case, as the code in Adler32 and CRC32 has done a full allocation in JDK 8, and by far either wrapped ByteBuffers or DirectByteBuffers are expected to be used. So for now I will keep the code as is without further complications. The performance with the copying looks reasonable. The result is multiplied with array length (@OperationsPerInvocation(65536 or 1024)) so score ends up being bytes/ms. 64k buffer length Benchmark Mode Samples Score Score error Units o.c.CRC32C.directByteBuffer_64K thrpt 5 998151.406 1539.451 ops/ms o.c.CRC32C.readonlyByteBuffer_64K thrpt 5 961665.219 36823.059 ops/ms o.c.CRC32C.wrappedByteBuffer_64K thrpt 5 1030445.833 9069.889 ops/ms 1k buffer length Benchmark Mode Samples Score Score error Units o.c.CRC32C.directByteBuffer_1K thrpt 5 987614.289 3506.829 ops/ms o.c.CRC32C.readonlyByteBuffer_1K thrpt 5 691888.488 217080.205 ops/ms o.c.CRC32C.wrappedByteBuffer_1K thrpt 5 974676.434 463.487 ops/ms //Staffan On 10/23/2014 02:05 AM, Peter Levart wrote: > On 10/23/2014 10:16 AM, Stanimir Simeonoff wrote: >> Unsafe is available, so the fields (array, offset) can be read directly >> UNSAFE.getObject(buffer, hbOffset), UNSAFE.getObject(buffer, >> offsetOffset). >> No need for MethodHandlers. >> During class init the offsets have to be resolved, pretty much like >> any CAS >> utilizing algorithm. >> >> I didn't propose it as readOnlyBuffers are very, very rarely used and >> even >> more unlikely to be used to calculate checksums. It just makes the code >> ugly. > > Agreed. And when Staffan introduces intrinsic, he could pass the > ByteBuffer instance to it and extract the byte[] there... > > Peter > >> >> Stanimir >> >> On Thu, Oct 23, 2014 at 11:05 AM, Peter Levart >> wrote: >> >>> On 10/23/2014 03:52 AM, Staffan Friberg wrote: >>> >>>> Webrev with these last updates. Added more tests to make sure CRC32C, >>>> CRC32 and Checksum default methods all are covered. >>>> >>>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.07 >>>> >>> Hi Staffan, >>> >>> Regarding default case: >>> >>> 168 } else { >>> 169 byte[] b = new byte[Math.min(buffer.remaining(), >>> 4096)]; >>> 170 while (buffer.hasRemaining()) { >>> 171 int length = Math.min(buffer.remaining(), >>> b.length); >>> 172 buffer.get(b, 0, length); >>> 173 update(b, 0, length); >>> 174 } >>> 175 } >>> >>> >>> Have you tried using get()/getInt() directly on the (ro) ByteBuffer >>> instead of copying to byte[] chunks? Intuitively one would expect it >>> perform faster if a redundant copy is avoided. Ah, you already told >>> us that >>> you plan to use intrinsic for CRC32C in the future, so you want to have >>> "addresses" at hand. >>> >>> A hackish way to avoid copying in this case is to access the byte[] and >>> offset using reflection. But this would have to be wrapped with >>> doPrivileged() which would worsen performance for small buffers. A >>> way to >>> avoid repeated access checks is to do them at class initialization >>> time, >>> using MethodHandle(s). For example, something like: >>> >>> >>> private static final MethodHandle bbArrayGetter; >>> private static final MethodHandle bbArrayOffsetGetter; >>> >>> static { >>> MethodHandle hbGetter; >>> MethodHandle offsetGetter; >>> try { >>> Field hbField = ByteBuffer.class.getDeclaredField("hb"); >>> Field offsetField = ByteBuffer.class. >>> getDeclaredField("offset"); >>> AccessController.doPrivileged(new >>> PrivilegedAction() { >>> @Override >>> public Void run() { >>> hbField.setAccessible(true); >>> offsetField.setAccessible(true); >>> return null; >>> } >>> }); >>> hbGetter = >>> MethodHandles.lookup().unreflectGetter(hbField); >>> offsetGetter = MethodHandles.lookup(). >>> unreflectGetter(offsetField); >>> } catch (NoSuchFieldException | IllegalAccessException e) { >>> hbGetter = null; >>> offsetGetter = null; >>> } >>> bbArrayGetter = hbGetter; >>> bbArrayOffsetGetter = offsetGetter; >>> } >>> >>> private static byte[] getArrayOrNull(ByteBuffer bb) { >>> if (bb.hasArray()) return bb.array(); >>> if (bbArrayGetter != null) { >>> try { >>> return (byte[]) bbArrayGetter.invokeExact(bb); >>> } catch (Throwable e) { >>> throw new InternalError(e); >>> } >>> } >>> return null; >>> } >>> >>> private static int getArrayOffset(ByteBuffer bb) { >>> if (bb.hasArray()) return bb.arrayOffset(); >>> if (bbArrayOffsetGetter != null) { >>> try { >>> return (int) bbArrayOffsetGetter.invokeExact(bb); >>> } catch (Throwable e) { >>> throw new InternalError(e); >>> } >>> } >>> throw new UnsupportedOperationException(); >>> } >>> >>> >>> >>> Regards, Peter >>> >>> >>>> //Staffan >>>> >>>> On 10/22/2014 05:37 PM, Stanimir Simeonoff wrote: >>>> >>>>> Hi Staffan, >>>>> >>>>> The readonly buffer (ByteBuffer.asReadOnlyBuffer()) don't have >>>>> array() >>>>> "working". >>>>> You can use "int length = Math.min(buffer.remaining, b.length)" >>>>> instead, >>>>> same with new byte[Math.min(4096, buffer.remaining)]. Using >>>>> smaller chunks >>>>> will be more performance friendly than allocating/eating up a huge >>>>> byte[]. >>>>> If you feel like, add a test with a heap >>>>> bytebuffer.asReadOnlyBuffer(). >>>>> >>>>> Stanimir >>>>> >>>>> >>>>> On Thu, Oct 23, 2014 at 3:06 AM, Staffan Friberg < >>>>> staffan.friberg at oracle.com > >>>>> wrote: >>>>> >>>>> Hi, >>>>> >>>>> I was thinking about this earlier when I started writing the >>>>> patch >>>>> and then I forgot about it again. I haven't been able to figure >>>>> out when the code will be executed. ByteBuffer is implemented in >>>>> such a way that only the JDK can extend it and as far as I can >>>>> tell you can only create 3 types of ByteBuffers (Direct, Mapped >>>>> and Heap), all of which will be handled by the more efficient >>>>> calls above. >>>>> >>>>> That said just to make the code a bit safer from OOM it is >>>>> probably best to update the default method and all current >>>>> implementations which all use the same pattern. >>>>> >>>>> A reasonable solution should be the following code >>>>> >>>>> byte[] b = new byte[(buffer.remaining() < 4096) >>>>> ? buffer.remaining() : 4096]; >>>>> while (buffer.hasRemaining()) { >>>>> int length = (buffer.remaining() < b.length) >>>>> ? buffer.remaining() : b.length; >>>>> buffer.get(b, 0, length); >>>>> update(b, 0, length); >>>>> } >>>>> >>>>> Xueming, do you have any further comment? >>>>> >>>>> Regards, >>>>> Staffan >>>>> >>>>> On 10/22/2014 03:04 PM, Stanimir Simeonoff wrote: >>>>> >>>>>> >>>>>> On Thu, Oct 23, 2014 at 12:10 AM, Bernd Eckenfels >>>>>> > wrote: >>>>>> >>>>>> Hello, >>>>>> >>>>>> just a question in the default impl: >>>>>> >>>>>> + } else { >>>>>> + byte[] b = new byte[rem]; >>>>>> + buffer.get(b); >>>>>> + update(b, 0, b.length); >>>>>> + } >>>>>> >>>>>> would it be a good idea to actually put a ceiling on the >>>>>> size >>>>>> of the >>>>>> array which is processed at once? >>>>>> This is an excellent catch. >>>>>> Should not be too large, probably 4k or so. >>>>>> >>>>>> Stanimir >>>>>> >>>>>> >>>>>> Am Tue, 21 Oct 2014 10:28:50 -0700 >>>>>> schrieb Staffan Friberg >>>>> >: >>>>>> >>>>>> >>>>>> > Hi Peter, >>>>>> > >>>>>> > Thanks for the comments.. >>>>>> > > >>>>>> > > 217 if (Unsafe.ADDRESS_SIZE == 4) { >>>>>> > > 218 // On 32 bit platforms >>>>>> read two >>>>>> ints >>>>>> > > instead of a single 64bit long >>>>>> > > >>>>>> > > When you're reading from byte[] using Unsafe >>>>>> (updateBytes), you >>>>>> > > have the option of reading 64bit values on 64bit >>>>>> platforms. When >>>>>> > > you're reading from DirectByteBuffer memory >>>>>> > > (updateDirectByteBuffer), you're only using 32bit >>>>>> reads. >>>>>> > I will add a comment in the code for this decision. The >>>>>> reason is >>>>>> > that read a long results in slightly worse performance in >>>>>> this case, >>>>>> > in updateBytes it is faster. I was able to get it to run >>>>>> slightly >>>>>> > faster by working directly with the address instead of >>>>>> always adding >>>>>> > address + off, but this makes things worse in the 32bit >>>>>> case since >>>>>> > all calculation will now be using long variables. So >>>>>> using >>>>>> the getInt >>>>>> > as in the current code feels like the best solution as it >>>>>> strikes the >>>>>> > best balance between 32 and 64bit. Below is how >>>>>> updateByteBuffer >>>>>> > looked with the rewrite I mentioned. >>>>>> > >>>>>> > >>>>>> > ong address = ((DirectBuffer) buffer).address(); >>>>>> > crc = updateDirectByteBuffer(crc, address + pos, >>>>>> address >>>>>> + limit); >>>>>> > >>>>>> > >>>>>> > private static int updateDirectByteBuffer(int crc, >>>>>> long adr, >>>>>> > long end) { >>>>>> > >>>>>> > // Do only byte reads for arrays so short they >>>>>> can't be >>>>>> > aligned if (end - adr >= 8) { >>>>>> > >>>>>> > // align on 8 bytes >>>>>> > int alignLength = (8 - (int) (adr & 0x7)) >>>>>> & 0x7; >>>>>> > for (long alignEnd = adr + alignLength; >>>>>> adr < >>>>>> alignEnd; >>>>>> > adr++) { crc = (crc >>> 8) >>>>>> > ^ byteTable[(crc ^ >>>>>> UNSAFE.getByte(adr)) & >>>>>> > 0xFF]; } >>>>>> > >>>>>> > if (ByteOrder.nativeOrder() == >>>>>> ByteOrder.BIG_ENDIAN) { >>>>>> > crc = Integer.reverseBytes(crc); >>>>>> > } >>>>>> > >>>>>> > // slicing-by-8 >>>>>> > for (; adr < (end - Long.BYTES); adr += >>>>>> Long.BYTES) { >>>>>> > int firstHalf; >>>>>> > int secondHalf; >>>>>> > if (Unsafe.ADDRESS_SIZE == 4) { >>>>>> > // On 32 bit platforms read two ints >>>>>> instead of >>>>>> > a single 64bit long firstHalf = UNSAFE.getInt(adr); >>>>>> > secondHalf = UNSAFE.getInt(adr + >>>>>> Integer.BYTES); >>>>>> > } else { >>>>>> > long value = UNSAFE.getLong(adr); >>>>>> > if (ByteOrder.nativeOrder() == >>>>>> > ByteOrder.LITTLE_ENDIAN) { firstHalf = (int) value; >>>>>> > secondHalf = (int) (value >>> >>>>>> 32); >>>>>> > } else { // ByteOrder.BIG_ENDIAN >>>>>> > firstHalf = (int) (value >>> >>>>>> 32); >>>>>> > secondHalf = (int) value; >>>>>> > } >>>>>> > } >>>>>> > crc ^= firstHalf; >>>>>> > if (ByteOrder.nativeOrder() == >>>>>> > ByteOrder.LITTLE_ENDIAN) { crc = byteTable7[crc & 0xFF] >>>>>> > ^ byteTable6[(crc >>> 8) >>>>>> & 0xFF] >>>>>> > ^ byteTable5[(crc >>> 16) >>>>>> & 0xFF] >>>>>> > ^ byteTable4[crc >>> 24] >>>>>> > ^ byteTable3[secondHalf & >>>>>> 0xFF] >>>>>> > ^ byteTable2[(secondHalf >>> >>>>>> 8) & 0xFF] >>>>>> > ^ byteTable1[(secondHalf >>> >>>>>> 16) & 0xFF] >>>>>> > ^ byteTable0[secondHalf >>>>>> >>> 24]; >>>>>> > } else { // ByteOrder.BIG_ENDIAN >>>>>> > crc = byteTable0[secondHalf & 0xFF] >>>>>> > ^ byteTable1[(secondHalf >>> >>>>>> 8) & 0xFF] >>>>>> > ^ byteTable2[(secondHalf >>> >>>>>> 16) & 0xFF] >>>>>> > ^ byteTable3[secondHalf >>>>>> >>> 24] >>>>>> > ^ byteTable4[crc & 0xFF] >>>>>> > ^ byteTable5[(crc >>> 8) >>>>>> & 0xFF] >>>>>> > ^ byteTable6[(crc >>> 16) >>>>>> & 0xFF] >>>>>> > ^ byteTable7[crc >>> 24]; >>>>>> > } >>>>>> > } >>>>>> > >>>>>> > if (ByteOrder.nativeOrder() == >>>>>> ByteOrder.BIG_ENDIAN) { >>>>>> > crc = Integer.reverseBytes(crc); >>>>>> > } >>>>>> > } >>>>>> > >>>>>> > // Tail >>>>>> > for (; adr < end; adr++) { >>>>>> > crc = (crc >>> 8) >>>>>> > ^ byteTable[(crc ^ >>>>>> UNSAFE.getByte(adr)) & 0xFF]; >>>>>> > } >>>>>> > >>>>>> > return crc; >>>>>> > } >>>>>> > >>>>>> > >>>>>> > > >>>>>> > > Also, in updateBytes, the usage of >>>>>> > > Unsafe.ARRAY_INT_INDEX_SCALE/ARRAY_LONG_INDEX_SCALE to >>>>>> index a byte >>>>>> > > array sounds a little scary. To be ultra portable you >>>>>> could check >>>>>> > > that ARRAY_BYTE_INDEX_SCALE == 1 first and refuse to >>>>>> use >>>>>> Unsafe for >>>>>> > > byte arrays if it is not 1. Then use >>>>>> Integer.BYTES/Long.BYTES to >>>>>> > > manipulate 'offsets' instead. In updateDirectByteBuffer >>>>>> it would be >>>>>> > > more appropriate to use Integer.BYTES/Long.BYTES too. >>>>>> > Good idea. Added a check in the initial if statement >>>>>> and it >>>>>> will get >>>>>> > automatically optimized away. >>>>>> > >>>>>> > > 225 firstHalf = (int) (value & >>>>>> > > 0xFFFFFFFF); 226 secondHalf = (int) (value >>>>>> > > >>> 32); 227 } else { // >>>>>> ByteOrder.BIG_ENDIAN >>>>>> > > 228 firstHalf = (int) (value >>> 32); >>>>>> > > 229 secondHalf = (int) (value & >>>>>> > > 0xFFFFFFFF); >>>>>> > > >>>>>> > > firstHalf = (int) value; // this is equivalent for >>>>>> line 225 >>>>>> > > secondHalf = (int) value; // this is equivalent for >>>>>> line 229 >>>>>> > Done. >>>>>> > >>>>>> > Here is the latest webrev, >>>>>> > >>>>>> http://cr.openjdk.java.net/~sfriberg/JDK-6321472/webrev.03 >>>>>> >>>>>> > >>>>>> > Cheers, >>>>>> > Staffan >>>>>> >>>>>> >>>>>> >>>>> > From mark.sheppard at oracle.com Thu Oct 23 23:05:27 2014 From: mark.sheppard at oracle.com (Mark Sheppard) Date: Fri, 24 Oct 2014 00:05:27 +0100 Subject: RFR: JDK-8049522 - Move @implNote in org.omg.CORBA.ORB to init method Message-ID: <544989B7.80203@oracle.com> Hi, please oblige and review the change http://cr.openjdk.java.net/~msheppar/8049522/webrev/ to address the issue https://bugs.openjdk.java.net/browse/JDK-8049522 this is javadoc change, which amends the implNote in ORB.java, relating to the ORBSingleton class loading strategy in JDK9. regards Mark From ivan.gerasimov at oracle.com Fri Oct 24 02:52:08 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Fri, 24 Oct 2014 06:52:08 +0400 Subject: [7u-dev ONLY] RFR: [8057530] (process) Runtime.exec throws garbled message in jp locale In-Reply-To: <54490B99.4060604@oracle.com> References: <5445FEFC.9040406@oracle.com> <54490B99.4060604@oracle.com> Message-ID: <5449BED8.7030905@oracle.com> Thanks Dalibor! Could someone with the Reviewer status review this please? Sincerely yours, Ivan On 23.10.2014 18:07, dalibor topic wrote: > Approved pending positive review. > > On 21.10.2014 08:36, Ivan Gerasimov wrote: >> Hello everybody! >> >> This is a request for review of a fix which is applicable to 7u only. >> The issue has already been addressed in 8 and later releases. >> >> The fix is a combined backport of >> https://bugs.openjdk.java.net/browse/JDK-8016579 , which addresses the >> problem with the encoding in windows console >> and partial backport of >> https://bugs.openjdk.java.net/browse/JDK-8001334 , which reorganizes the >> code at the files of our interest. >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8057530 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8057530/0/webrev/ >> >> The fix has been verified on the localized versions of Windows (jp, >> rus). >> >> Thanks in advance, >> Ivan > From ioi.lam at oracle.com Fri Oct 24 04:34:51 2014 From: ioi.lam at oracle.com (Ioi Lam) Date: Thu, 23 Oct 2014 21:34:51 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 2) In-Reply-To: <5446BA6B.5030803@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> Message-ID: <5449D6EB.8010105@oracle.com> Hi Mandy, Thanks for the review. I have updated the patch: http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v2/ Please see comments in-line. On 10/21/14, 12:56 PM, Mandy Chung wrote: > Hi Ioi, > > On 10/21/14 10:27 AM, Ioi Lam wrote: >> Please review this fix: >> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v1/ > This looks better than the preliminary webrev you sent me offline > earlier. I only review the jdk repo change. > > > > Launcher.java > line 290: it can be made a final field. > line 297: this.ucp = .... Done > line 317-319: I think they are meant to be two sentences. > I have the following suggested text: > > // The class of the given name is not found in the parent > // class loader as well as its local URLClassPath. > // Check if this class has already been defined dynamically; > // if so, return the loaded class; otherwise, skip the parent > // delegation and findClass. I have used your comment and removed the old one. > URLClassPath.java > line 76: this long line should be broken into multiple line. > Maybe you can addsun.security.action.GetPropertyAction in the > import and update line 72, 74, 76, 78. Done > line 319-326: Is this LoaderType enum necessary? I think it can > simply pass the ClassLoader instance to VM rather than having > this enum type just for this purpose. I suggest to get rid > of the LoaderType enum type. I changed the API to pass the ClassLoader instance and removed the LoaderType. > line 398: what happens if loaders.size() > maxindex? Shouldn't > it return null? In this case, all the loaders that's needed by the cache[] have been opened. So we should return cache[]. > 404 if (getNextLoader(null, maxindex) == null || > 405 !lookupCacheEnabled) { > > line 405 should indent to the right for better readability. > > The comment helps as I was initially confused why lookupCacheEnabled > is not checked first. Am I right to say line 398-415 is equivalent > to (excluding the debugging statements): > if (loaders.size() <= maxindex &&getLoader(maxindex) != null) { > returnlookupCacheEnabled ? cache : null; > } > return null; > I think that is easier to understand. I changed the code to this. What do you think? if (loaders.size() <= maxindex) { boolean failed = false; // Call getNextLoader() with a null cache to open all // Loaders up to, and including, maxindex. if (getNextLoader(null, maxindex) == null) { failed = true; } else if (!lookupCacheEnabled) { // As a side effect of the getNextLoader call, // The cache has been invalidated. failed = true; } if (failed) { if (DEBUG_LOOKUP_CACHE) { System.out.println("Expanded loaders FAILED " + loaders.size() + " for maxindex=" + maxindex); } return null; } if (DEBUG_LOOKUP_CACHE) { System.out.println("Expanded loaders " + loaders.size() + " to maxindex=" + maxindex); } } > > 432 urlNoFragString.equals( > 433 URLUtil.urlNoFragString(lookupCacheURLs[index]))) { > > Should you store URLUtil.urlNoFragString form of URL in > lookupCacheURLs such that they can be compared with equals? urlNoFragString is called exactly once for every URL in the lookupCacheURLs so they live very shortly. In contrast, the URLs stored in the lookupCacheURLs live forever (HotSpot has an internal reference to them and use them for other purposes). So for memory footprint, it's better to not cache the urlNoFragString. > line 423-426: formatting nit: these lines look a little long > and would be good to rewrap them. Fixed > jvm.h > 1394: typo s/Retruns/Returns > As suggested above, pass the classloader instance instead of > defining a new loader_type interface Fixed. Now the class loader instance is passed. > URLClassPath.c > line 42: nit: align the parameters Fixed > There are several lines calling > 49JNU_ThrowNullPointerException(env, 0). > 55 JNU_ThrowOutOfMemoryError(env, NULL); > > The msg argument probably better to be consistent and pass NULL. > ClassLoader.c is a bit inconsistent. Fixed. > Can you add regression tests in the jdk repo? Sanity tests > like with the lookup cache enabled but invalidated at startup > or due to addURL call. Added. > Mandy > From ioi.lam at oracle.com Fri Oct 24 04:34:57 2014 From: ioi.lam at oracle.com (Ioi Lam) Date: Thu, 23 Oct 2014 21:34:57 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 2) In-Reply-To: <5446CA6B.5090204@oracle.com> References: <54469778.8090008@oracle.com> <5446CA6B.5090204@oracle.com> Message-ID: <5449D6F1.1030209@oracle.com> Hi Jiangli, Thanks for the review. Please see comments in-line: On 10/21/14, 2:04 PM, Jiangli Zhou wrote: > Hi Ioi, > > Here are some comments from me: > > -src/share/vm/classfile/classLoader.cpp > In ClassLoader::setup_search_path, if canonicalize is true it's not > necessary to allocate the 'path' and copy the 'class_path' to 'path'. > we need to allocate path[] because we need to copy only a part of the classpath[] into it. E.g. classpath[] = "foo.jar:bar.jar" path[] = "foo.jar" <- need to be zero-terminated > -src/share/vm/memory/metadataFactory.hpp > In free_array, is it possible to disable it only when > PrintSharedSpaces is enabled, instead of disabling it for all? > I am not sure. For safety, I have filed a bug and will fix that separately: https://bugs.openjdk.java.net/browse/JDK-8062016 > -jdk/src/share/native/sun/misc/URLClassPath.c > Is verifying class name needed in > Java_sun_misc_URLClassPath_knownToNotExist0? The class name will be > verified when the class loader loads the class. > I coped the code from Java_java_lang_ClassLoader_findBootstrapClass. VerifyFixClassname is needed, as it translate "." -> "/". I am not sure if VerifyClassname is needed, but I guess it doesn't hurt. > -jdk/src/share/classes/sun/misc/URLClassPath.java > Can lookupCacheEnabled flag change during runtime? In getLookupCache() > the flag is checked more than once. > Yes, it can change if disableAllLookupCaches() is called in the middle of getLookupCache(). I have added more comments in the new webrev. Please take a look to see if it makes sense. http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v2/ Thanks - Ioi > Thanks, > Jiangli > > On 10/21/2014 10:27 AM, Ioi Lam wrote: >> Please review this fix: >> >> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v1/ >> >> Bug: Add an interface to the JVM's Class/Resource Lookup Index Cache >> for improving sun.misc.URLClassPath search time >> >> https://bugs.openjdk.java.net/browse/JDK-8061651 >> >> Summary of fix: >> >> Some J2EE environments have lots of JAR files in the >> classpath. However, during run-time, most classes are loaded by >> custom classloaders which delegate to the system loader. As a >> result, each class loaded by a custom classloader will cause many >> JAR search failures (in sun.misc.URLClassPath). >> >> To limit the number of searches in URLClassPath, the 8uX HotSpot >> VM is going to include a Class/Resource Lookup Index Cache that >> records information about the class/resource entries in the JAR >> files in the classpath. This can be used to improve >> sun.misc.URLClassPath search time. >> >> This is part 1 of the REF -- we are adding appropriate interfaces >> in both the JDK code and the HotSpot code to access this cache. >> >> URLClassPath.java is modified to use JNI to call into the HotSpot >> JVM_XXX APIs to access the cache. >> >> The implementation of this cache is done in part 2 of this RFE. >> >> Note that this enhancement is for JDK 8uX only. In JDK9 and >> beyond, we are considering an alternative implementation where the >> cache is maintained in the core libs code, outside of HotSpot. >> >> Tests: >> >> JPRT >> Adhoc SQE tests >> >> Thanks >> - Ioi > From otaviojava at java.net Fri Oct 24 05:25:31 2014 From: otaviojava at java.net (=?UTF-8?Q?Ot=C3=A1vio_Gon=C3=A7alves_de_Santana?=) Date: Fri, 24 Oct 2014 03:25:31 -0200 Subject: Review request: JDK-8055723 Replace concat String to append in StringBuilder parameters In-Reply-To: <5445A836.8090005@CoSoCo.de> References: <5445A836.8090005@CoSoCo.de> Message-ID: Thank you Ulf. I removed the fix in toString method and in debug classes: http://cr.openjdk.java.net/~weijun/8055723/webrev.00/ On Mon, Oct 20, 2014 at 10:26 PM, Ulf Zibis wrote: > > Am 21.10.2014 um 01:02 schrieb Ot?vio Gon?alves de Santana: > >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8055723 >> >> >> WEBREV: http://cr.openjdk.java.net/~weijun/8055723/client/webrev.02/ >> WEBREV: http://cr.openjdk.java.net/~weijun/8055723/core/webrev.03/ >> > > I did not look through all sources. > In Scanner.java I discovered: > 1307 sb.append("[delimiters=").append(delimPattern).append(']'); > 1308 sb.append("[position=").append(position).append(']'); > ... > Maybe better: > 1307 sb.append("[delimiters=").append(delimPattern); > 1308 sb.append("][position=").append(position); > ... > > -Ulf > > -- Ot?vio Gon?alves de Santana blog: http://otaviosantana.blogspot.com.br/ twitter: http://twitter.com/otaviojava site: *http://about.me/otaviojava * 55 (11) 98255-3513 From Alan.Bateman at oracle.com Fri Oct 24 08:04:28 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 24 Oct 2014 09:04:28 +0100 Subject: RFR: JDK-8049522 - Move @implNote in org.omg.CORBA.ORB to init method In-Reply-To: <544989B7.80203@oracle.com> References: <544989B7.80203@oracle.com> Message-ID: <544A080C.7070406@oracle.com> On 24/10/2014 00:05, Mark Sheppard wrote: > Hi, > please oblige and review the change > http://cr.openjdk.java.net/~msheppar/8049522/webrev/ > The note in the ORB.init methods looks good. I think it will read a bit more smoother if you drop the comma after "When configured". For the note in the class description "When a singleton ORB .." should probably be "When the singleton ORB ...". I wonder if this statement could be re-worded or even dropped: "Thus, where appropriate, it is necessary that an application's CLASSPATH includes the classes for this alternative ORBSingleton. It should be noted the singleton ORB is system wide." It hints of the CLASSPATH env variable and also not clear what this means for applications running in a container. How about: "An application started on the command line with the java launcher will put the classes for the alternative ORB implementation on the class path for example". -Alan. From Alan.Bateman at oracle.com Fri Oct 24 08:33:24 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 24 Oct 2014 09:33:24 +0100 Subject: [7u-dev ONLY] RFR: [8057530] (process) Runtime.exec throws garbled message in jp locale In-Reply-To: <5449BED8.7030905@oracle.com> References: <5445FEFC.9040406@oracle.com> <54490B99.4060604@oracle.com> <5449BED8.7030905@oracle.com> Message-ID: <544A0ED4.9010702@oracle.com> On 24/10/2014 03:52, Ivan Gerasimov wrote: > Thanks Dalibor! > > Could someone with the Reviewer status review this please Skimming through the changes then I don't see any issues, except overly long lines in win32Error which makes it hard to look at the changes side-by-side. It would be nice not to have #ifdef WIN32 in the shared code but that isn't your doing, it's in the original change too. -Alan. From ivan.gerasimov at oracle.com Fri Oct 24 09:46:10 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Fri, 24 Oct 2014 13:46:10 +0400 Subject: [7u-dev ONLY] RFR: [8057530] (process) Runtime.exec throws garbled message in jp locale In-Reply-To: <544A0ED4.9010702@oracle.com> References: <5445FEFC.9040406@oracle.com> <54490B99.4060604@oracle.com> <5449BED8.7030905@oracle.com> <544A0ED4.9010702@oracle.com> Message-ID: <544A1FE2.6090406@oracle.com> Thanks Alan! On 24.10.2014 12:33, Alan Bateman wrote: > On 24/10/2014 03:52, Ivan Gerasimov wrote: >> Thanks Dalibor! >> >> Could someone with the Reviewer status review this please > Skimming through the changes then I don't see any issues, except > overly long lines in win32Error which makes it hard to look at the > changes side-by-side. > It would be nice not to have #ifdef WIN32 in the shared code but that > isn't your doing, it's in the original change too. > Yes. I thought it's better to keep it the way it has been formatted in 8. Do you want me to change this to make lines shorter? Sincerely yours, Ivan From Alan.Bateman at oracle.com Fri Oct 24 10:01:17 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 24 Oct 2014 11:01:17 +0100 Subject: [7u-dev ONLY] RFR: [8057530] (process) Runtime.exec throws garbled message in jp locale In-Reply-To: <544A1FE2.6090406@oracle.com> References: <5445FEFC.9040406@oracle.com> <54490B99.4060604@oracle.com> <5449BED8.7030905@oracle.com> <544A0ED4.9010702@oracle.com> <544A1FE2.6090406@oracle.com> Message-ID: <544A236D.4020002@oracle.com> On 24/10/2014 10:46, Ivan Gerasimov wrote: > Yes. I thought it's better to keep it the way it has been formatted in 8. > Do you want me to change this to make lines shorter? No need for that, the inconsistencies were in the original changes, not your doing. -Alan. From markus.gronlund at oracle.com Fri Oct 24 10:04:27 2014 From: markus.gronlund at oracle.com (=?iso-8859-1?B?TWFya3VzIEdy9m5sdW5k?=) Date: Fri, 24 Oct 2014 03:04:27 -0700 (PDT) Subject: FW: RFR(L): 8056049: getProcessCpuLoad() stops working in one process when a different process exits Message-ID: <7ad8c0fe-debc-4c2a-acb5-8cc6834af38a@default> Also sending this to core-libs. ? Thanks in advance Markus ? From: Markus Gr?nlund Sent: den 22 oktober 2014 11:44 To: serviceability-dev at openjdk.java.net; jmx-dev at openjdk.java.net Subject: RFR(L): 8056049: getProcessCpuLoad() stops working in one process when a different process exits ? Greetings, ? Kindly asking for reviews for the following changeset. ? Bug: https://bugs.openjdk.java.net/browse/JDK-8056049 Webrev: http://cr.openjdk.java.net/~mgronlun/8056049/webrev01/ ? Description: ? The issue is ?Windows specific. And the problem relates to using the Performance Data Helper API (PDH), more specifically how to use the "Process" PDH object in PDH queries: ? // code comment extract ? /* * Working against the Process object and it's related counters is inherently problematic * when using the PDH API: * * For PDH, a process is not primarily identified by it's process id, * but with a sequential number, for example \Process(java#0), \Process(java#1), .... * The really bad part is that this list is reset as soon as one process exits: * If \Process(java#1) exits, \Process(java#3) now becomes \Process(java#2) etc. * * The PDH query api requires a process identifier to be submitted when registering * a query, but as soon as the list resets, the query is invalidated (since the name * changed). * * Solution: * The #number identifier for a Process query can only decrease after process creation. * * Therefore we create an array of counter queries for all process object instances * up to and including ourselves: * * Ex. we come in as third process instance (java#2), we then create and register * queries for the following Process object instances: * java#0, java#1, java#2 * * currentQueryIndexForProcess() keeps track of the current "correct" query * (in order to keep this index valid when the list resets from underneath, * ensure to call getCurrentQueryIndexForProcess() before every query involving * Process object instance data). */ ? I have already fixed this in the VM as of https://bugs.openjdk.java.net/browse/JDK-8019921 ? In the process of fixing this issue now in the JDK, I realized that the previous implementation of using PDH in the JDK was a bit convoluted - especially if you would like to reuse functionality / add new counters. ? Therefore this change also includes an overall rewrite of the how the JDK will interface with the PDH library, a rewrite of which (hopefully) improves both readability and extensibility. ? I can do a code walkthrough live if anyone is interested to know the exact details of this change. ? Testing completed : Testset SVC (includes jdk_instrument, jdk_management, jdk_jmx, jdk_jdi) ? Thanks in advance Markus ? From claes.redestad at oracle.com Fri Oct 24 10:45:05 2014 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 24 Oct 2014 12:45:05 +0200 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 2) In-Reply-To: <5449D6F1.1030209@oracle.com> References: <54469778.8090008@oracle.com> <5446CA6B.5090204@oracle.com> <5449D6F1.1030209@oracle.com> Message-ID: <544A2DB1.3040807@oracle.com> On 10/24/2014 06:34 AM, Ioi Lam wrote: >> Can lookupCacheEnabled flag change during runtime? In >> getLookupCache() the flag is checked more than once. >> > Yes, it can change if disableAllLookupCaches() is called in the middle > of getLookupCache(). I have added more comments in the new webrev. > Please take a look to see if it makes sense. > > http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v2/ What is the reason to have lookupCacheEnabled disabled globally when for example calling addURL on *any* URLClassLoader? Couldn't the disabling of cache lookups be per URLClassPath rather than global? /Claes From staffan.larsen at oracle.com Fri Oct 24 13:33:29 2014 From: staffan.larsen at oracle.com (Staffan Larsen) Date: Fri, 24 Oct 2014 15:33:29 +0200 Subject: Review request: JDK-8043277: Update jdk regression tests to extend the default security policy instead of override In-Reply-To: <5449055F.30305@oracle.com> References: <54485505.4030002@oracle.com> <5449055F.30305@oracle.com> Message-ID: <10EB71A5-E389-4639-917D-2C52417354DF@oracle.com> Since this is the first use of jtreg 4.1b10 features, this would also be good time to tag the jdk test suite to require at least 4.1b10. This latest version of jtreg has support for checking which version of jtreg the test suite requires. So you can add a line saying: requiredVersion=4.1 b10 to TEST.ROOT and jtreg will verify that its version number is higher than ?requiredVersion" when it runs. It?s not until we move from b10 to b11 that this will actually be useful, but it could be a good time to introduce it. Thanks, /Staffan On 23 okt 2014, at 15:40, Alan Bateman wrote: > On 23/10/2014 02:08, Mandy Chung wrote: >> jtreg policy option overrides the system security policy file and hence >> some existing test policy files have to duplicate the entries to grant >> permissions for JDK. >> > This looks okay to me too. I think this will be the first use of a jtreg4.1-b10 feature and maybe someone should send a note to jdk9-dev to tell folks that they will need an up-to-date jtreg in order to test jdk9/dev. > > -Alan > From mandy.chung at oracle.com Fri Oct 24 16:16:46 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Fri, 24 Oct 2014 09:16:46 -0700 Subject: Review request: JDK-8043277: Update jdk regression tests to extend the default security policy instead of override In-Reply-To: <10EB71A5-E389-4639-917D-2C52417354DF@oracle.com> References: <54485505.4030002@oracle.com> <5449055F.30305@oracle.com> <10EB71A5-E389-4639-917D-2C52417354DF@oracle.com> Message-ID: <544A7B6E.1070208@oracle.com> On 10/24/2014 6:33 AM, Staffan Larsen wrote: > Since this is the first use of jtreg 4.1b10 features, this would also be good time to tag the jdk test suite to require at least 4.1b10. > > This latest version of jtreg has support for checking which version of jtreg the test suite requires. So you can add a line saying: > requiredVersion=4.1 b10 > to TEST.ROOT and jtreg will verify that its version number is higher than ?requiredVersion" when it runs. > > It?s not until we move from b10 to b11 that this will actually be useful, but it could be a good time to introduce it. Good point since now it depends on b10 feature. Here is the patch. diff --git a/test/TEST.ROOT b/test/TEST.ROOT --- a/test/TEST.ROOT +++ b/test/TEST.ROOT @@ -12,3 +12,6 @@ # Group definitions groups=TEST.groups [closed/TEST.groups] + +# Tests using jtreg 4.1 b10 features +requiredVersion=4.1 b10 Mandy > > Thanks, > /Staffan > > On 23 okt 2014, at 15:40, Alan Bateman wrote: > >> On 23/10/2014 02:08, Mandy Chung wrote: >>> jtreg policy option overrides the system security policy file and hence >>> some existing test policy files have to duplicate the entries to grant >>> permissions for JDK. >>> >> This looks okay to me too. I think this will be the first use of a jtreg4.1-b10 feature and maybe someone should send a note to jdk9-dev to tell folks that they will need an up-to-date jtreg in order to test jdk9/dev. >> >> -Alan >> From peter.levart at gmail.com Fri Oct 24 16:27:38 2014 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 24 Oct 2014 18:27:38 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <20141023032730.00000ae4.ecki@zusammenkunft.net> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> <544662EB.2040907@oracle.com> <20141021230858.00006471.ecki@zusammenkunft.net> <5448282B.1010900@oracle.com> <20141023032730.00000ae4.ecki@zusammenkunft.net> Message-ID: <544A7DFA.9000204@gmail.com> On 10/23/2014 03:27 AM, Bernd Eckenfels wrote: > Am Wed, 22 Oct 2014 14:56:59 -0700 > schrieb Mandy Chung : >> I guess your question is related to my comment about two class loaders >> can define classes in a package of the same name (two different >> runtime packages). ClassLoader.getPackage(s) assumes there is only >> one Package for each name in the class loader chain which seems wrong >> to me. Claes has filed a bug to track this: >> https://bugs.openjdk.java.net/browse/JDK-8061804 > Yes, I think thats the same, Mandy. > > One option for solving that in a still performant (lockless on hot > path) way would be a "ConcurrentSet" of package names used for the > initial decision if the hierachy needs traversed (and why may define a > package). With a set of strings it would not keep the packages alive so > it can be global. Not sure if it would need a cleanup mechanism.. hmm. > > Gruss > Bernd Hi Bernd, As it is perfectly legal for two unrelated classloaders (for example peers sharing common parent) to each define it's own distinct class with the same name (imagine two J2EE apps each using it's own version of the same library bundled with them), so should two unrelated classloaders be able to define two distinct Packages with same name - and they can do that. Standard delegation model makes sure that a class with a particular name can only be defined by one classloader in the delegation chain from initiating to the bootstrap classloader, but not all classloaders follow this rule (for example WAR classloader in web containers). Packages also "wish" to follow this rule, but fail, since the existence of a package is established only when 1st class from that package is loaded. Something similar is achieved by making packages "sealed", but not all packages are sealed, and I think that even distinct "sealed" packages with same name can exist in unrelated classloaders. So the most consistent thing to do would be to allow each classloader to define it's own packages (unless ancestors define a sealed package with same name) and to consistently return the Package defined by the Class' defining classloader from the Class.getPackage() method. ClassLoader.getPackages() method should then return a concatenation of defined packages from the invoked classloader up through ancestors to the bootstrap classloader and this list may contain Packages with non-unique names. Regards, Peter From mandy.chung at oracle.com Fri Oct 24 16:41:39 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Fri, 24 Oct 2014 09:41:39 -0700 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <5449020E.9010803@oracle.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> <544662EB.2040907@oracle.com> <54482324.3060306@oracle.com> <54484497.3090705@oracle.com> <544851C4.70508@oracle.com> <5449020E.9010803@oracle.com> Message-ID: <544A8143.4000401@oracle.com> On 10/23/2014 6:26 AM, Claes Redestad wrote: > http://cr.openjdk.java.net/~redestad/8060130/webrev.10 Looks good. Mandy From ecki at zusammenkunft.net Fri Oct 24 18:25:23 2014 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Fri, 24 Oct 2014 20:25:23 +0200 Subject: RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package In-Reply-To: <544A7DFA.9000204@gmail.com> References: <5437F6EB.4080506@oracle.com> <54387A6D.90402@oracle.com> <5439E2DA.1040309@oracle.com> <543BE299.9070906@gmail.com> <543BEA8A.6090901@oracle.com> <543BEC8E.6050309@gmail.com> <543BEFD4.40707@gmail.com> <543BF29E.70303@oracle.com> <543DC8D9.8010709@oracle.com> <544662EB.2040907@oracle.com> <20141021230858.00006471.ecki@zusammenkunft.net> <5448282B.1010900@oracle.com> <20141023032730.00000ae4.ecki@zusammenkunft.net> <544A7DFA.9000204@gmail.com> Message-ID: <20141024202523.000072c3.ecki@zusammenkunft.net> Hello Peter, Am Fri, 24 Oct 2014 18:27:38 +0200 schrieb Peter Levart : > > One option for solving that in a still performant (lockless on hot > > path) way would be a "ConcurrentSet" of package names used for the > > initial decision if the hierachy needs traversed (and why may > > define a package). With a set of strings it would not keep the > > packages alive so it can be global. Not sure if it would need a > > cleanup mechanism.. hmm. > As it is perfectly legal for two unrelated classloaders (for example > peers sharing common parent) to each define it's own distinct class > with the same name (imagine two J2EE apps each using it's own version > of the same library bundled with them), so should two unrelated > classloaders be able to define two distinct Packages with same name - > and they can do that. Yes, the set is only about determine with an atomic operation if you need to traverse the tree or not. So for the case that a package is homed by a single class loader, that class loader will make an entry into the set (and suceed) and then does not need to do more parent traversal. All other class loaders will see there is already the package name reserved, and then they will need to coordinate with their parents. But its just an idea after inspecting the changes, not a real analysis of all usage models. Maybe it is enough to do it for sealed packages. Gruss Bernd Standard delegation model makes sure that a > class with a particular name can only be defined by one classloader > in the delegation chain from initiating to the bootstrap classloader, > but not all classloaders follow this rule (for example WAR > classloader in web containers). Packages also "wish" to follow this > rule, but fail, since the existence of a package is established only > when 1st class from that package is loaded. Something similar is > achieved by making packages "sealed", but not all packages are > sealed, and I think that even distinct "sealed" packages with same > name can exist in unrelated classloaders. So the most consistent > thing to do would be to allow each classloader to define it's own > packages (unless ancestors define a sealed package with same name) > and to consistently return the Package defined by the Class' defining > classloader from the Class.getPackage() method. > ClassLoader.getPackages() method should then return a concatenation > of defined packages from the invoked classloader up through ancestors > to the bootstrap classloader and this list may contain Packages with > non-unique names. > > Regards, Peter > > From mandy.chung at oracle.com Fri Oct 24 18:31:50 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Fri, 24 Oct 2014 11:31:50 -0700 Subject: RFR: 8060132: Handlers configured on abstract nodes in logging.properties are not always properly closed In-Reply-To: <5437FDCB.30803@oracle.com> References: <5437F268.9020600@oracle.com> <5437FDCB.30803@oracle.com> Message-ID: <544A9B16.6030500@oracle.com> On 10/10/2014 8:39 AM, Daniel Fuchs wrote: > http://cr.openjdk.java.net/~dfuchs/webrev_8060132/webrev.01 Sorry for the delay. I have been pondering if there is a better alternative and looks like you have considered a few other options that none of them is a good one. typos: 174 explicitely 925: persitentLoggers Is this only problem to the abstract node of Loggers (i.e. the ancestor is in the logging configuration but the library/app never creates such a logger)? Your patch will keep all loggers defined in the configuration strong reference. What if the application really wants the loggers say com.foo.FooLogger to get GC'ed (e.g. it wants the logger class and its defining class loader to be garbage collected) but the configuration does name com.foo.FooLogger.handler = .... Would that cause memory leak? Mandy From jason_mehrens at hotmail.com Fri Oct 24 19:50:32 2014 From: jason_mehrens at hotmail.com (Jason Mehrens) Date: Fri, 24 Oct 2014 14:50:32 -0500 Subject: RFR: 8060132: Handlers configured on abstract nodes in logging.properties are not always properly closed In-Reply-To: <544A9B16.6030500@oracle.com> References: <5437F268.9020600@oracle.com> , <5437FDCB.30803@oracle.com>, <544A9B16.6030500@oracle.com> Message-ID: The strong reference is not changed to weak if later on all handlers are removed from the logger. The only other solution I can think of to satisfy all of the previous pain points is to go back to keeping a reference to Logger.handlers in LogManager.LogNode and create a LogManager.orphanedHandlers map. On dispose, if the handlers list is not empty, place it in the orphan handler map. Every time we demand a Logger, remove the orphaned handlers list for that logger name and directly place the reference into the new logger.handlers. Then the loggers can be GC'ed but the handlers can't. On LogManager.reset walk the orphaned handlers map and close all handlers. That fixes issues with same handler being added multiple loggers and allows weak references to the logger. The new pain point of this is what do you do about loading the logger handlers from the config file if you have an orphan handler list. Do you skip loading them or just add those plus the orphan list? Jason ---------------------------------------- > Date: Fri, 24 Oct 2014 11:31:50 -0700 > From: mandy.chung at oracle.com > To: daniel.fuchs at oracle.com; core-libs-dev at openjdk.java.net > Subject: Re: RFR: 8060132: Handlers configured on abstract nodes in logging.properties are not always properly closed > > > On 10/10/2014 8:39 AM, Daniel Fuchs wrote: >> http://cr.openjdk.java.net/~dfuchs/webrev_8060132/webrev.01 > > Sorry for the delay. I have been pondering if there is a better > alternative and looks like you have considered a few other options that > none of them is a good one. > > typos: > > 174 explicitely > 925: persitentLoggers > > Is this only problem to the abstract node of Loggers (i.e. the ancestor > is in the logging configuration but the library/app never creates such > a logger)? > > Your patch will keep all loggers defined in the configuration strong > reference. What if the application really wants the loggers say > com.foo.FooLogger to get GC'ed (e.g. it wants the logger class and > its defining class loader to be garbage collected) but the configuration > does name com.foo.FooLogger.handler = .... > > Would that cause memory leak? > > Mandy From peter.levart at gmail.com Fri Oct 24 21:18:17 2014 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 24 Oct 2014 23:18:17 +0200 Subject: RFR: 8061244 Use of stack-less ClassNotFoundException thrown from (URL)ClassLoader.findClass() In-Reply-To: <544832CE.4020203@oracle.com> References: <543EF592.3030409@gmail.com> <543F754B.4020001@gmail.com> <543F8558.2030401@gmail.com> <543FD0A6.3080207@gmail.com> <54463760.6090809@gmail.com> <544832CE.4020203@oracle.com> Message-ID: <544AC219.6080007@gmail.com> Hi Mandy, Thanks for taking a look. I've wondered myself that now it might not be the right time to change things in ClassLoader(s) as greater changes are pending. Perhaps we can revisit this after they are over if it still matters then. Regards, Peter On 10/23/2014 12:42 AM, Mandy Chung wrote: > Hi Peter, > > On 10/21/2014 3:37 AM, Peter Levart wrote: >> http://cr.openjdk.java.net/~plevart/jdk9-dev/ClassLoader.CNFE/webrev.03/ > > I skimmed through this webrev. I would suggest to hold off this > patch and there are various ideas of the optimization for class > loading performance with modules. > > Throwing CNFE attributes to one part of the class loading cost that > hasn't proven to be significant in real-world applications. Recently I > have instrumented the class loading code to add more fine-grained > performance counters to determine the overhead of CNFE with and > without stacktrace and again the applications I used to measure shows > the CNFE stack trace isn't the focus. A class lookup cost would > depend on the class loader hierarchy, the search path of each class > loader and what classes are being looked up from a class loader. The > cost of looking up a class local in the class loader's search path > involves the parent delegation lookup time + CNFE + findClass (lookup > class in its local search path). In a typical real-world application, > the parent delegation lookup time would be much significant than > CNFE. CNFE is thrown by loadClass for class lookup that is one > typical suspect for class loading performance issue. On the other > hand, resource lookup actually has the parent delegation performance > cost in which CNFE is not involved. > > With modules, this would give the opportunity to consider skipping > parent delegation, direct class lookup when the class is known to be > local. That'd avoid CNFE creation completely. > > Talking about exceptions and fillInStackTrace, it's known to be > significant cost. It'd be interesting to have the VM flag that can > measure the time it spends in filling in the backtrace of each > exception type (and perhaps the mean and max stack depth) that will > give a better idea of the performance distribution. In addition, > doPrivileged wraps checked exception with PrivilegedActionException > that essentially has the same stack trace and it doubles the cost even > in the absence of security manager. I have exchanged some mail with > the security team to see if this is a low-hanging fruit to improve the > performance. > > Mandy From mandy.chung at oracle.com Fri Oct 24 21:33:49 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Fri, 24 Oct 2014 14:33:49 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 2) In-Reply-To: <5449D6EB.8010105@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> Message-ID: <544AC5BD.4010407@oracle.com> On 10/23/2014 9:34 PM, Ioi Lam wrote: > Hi Mandy, > > Thanks for the review. I have updated the patch: > > http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v2/ > > Thanks for removing the LoaderType enum. Two questions - do you need the new hasLookupCacheLoader variable? Should lookupCAcheURLs be always be non-null if it has the lookup cache? Most methods referencinglookupCacheURLs and lookupCacheLoader are synchronized except initLookupCache and knowToNotExist. Should they? Or volatile? > On 10/21/14, 12:56 PM, Mandy Chung wrote: > >> line 398: what happens if loaders.size() > maxindex? Shouldn't >> it return null? > In this case, all the loaders that's needed by the cache[] have been > opened. So we should return cache[]. I forget about that, sorry. I'm thinking how to make it more obvious to those who doesn't know much of the details. Every time I read this and I need to reload what I know about and miss something. > I changed the code to this. What do you think? It seems to me that it would help if you refactor and add a method "ensureLoadersInited" that will make it clear what it attempts to do. The side effect invalidating the cache can be checked after it's called and no need to worry about lookupCacheEnabled must be checked in any order. Something like this if (cache != null && cache.length > 0) { int maxindex = cache[cache.length - 1]; ensureLoaderOpened(maxindex); if (loaders.get(maxindex) == null || !lookupCacheEnabled) { if (DEBUG_LOOKUP_CACHE) { System.out.println("Expanded loaders FAILED " + loaders.size() + " for maxindex=" + maxindex); } return null; } ... } return cache; The code is getting further complicated with this lookup cache and bear with me for being picky. > if (loaders.size() <= maxindex) { > boolean failed = false; > > // Call getNextLoader() with a null cache to open all > // Loaders up to, and including, maxindex. > if (getNextLoader(null, maxindex) == null) { Can this call getLoader(maxindex)? They are essentially the same. I think getLoader(maxindex) makes it explicit that it forces to open the loader. Mandy From daniel.fuchs at oracle.com Fri Oct 24 21:50:43 2014 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 24 Oct 2014 23:50:43 +0200 Subject: RFR: 8060132: Handlers configured on abstract nodes in logging.properties are not always properly closed In-Reply-To: <544A9B16.6030500@oracle.com> References: <5437F268.9020600@oracle.com> <5437FDCB.30803@oracle.com> <544A9B16.6030500@oracle.com> Message-ID: <544AC9B3.8090202@oracle.com> Hi Mandy, > Is this only problem to the abstract node of Loggers (i.e. the ancestor > is in the logging configuration but the library/app never creates such > a logger)? No - the problem is with any logger that has handlers configured from the logging.properties, and which the application creates and releases before the Cleaner thread is run. > Your patch will keep all loggers defined in the configuration strong > reference. Not all loggers defined in the configuration. Only those loggers for which a handler and is explicitly defined in the configuration and which have been created at least once - directly or indirectly (= through a child) by the application. > Would that cause memory leak? The main source of memory leak - and probably the only one we should care about is when a Logger that we strong reference has a reference to an object whose class would be otherwise garbage collected. In other words - if the logger is the only thing that prevents an object, and its class, and its class loader, from being garbage collected. If I'm not mistaken - there are only three objects that could cause such an issue: - Instances of Level - Instances of Handler - Instances of ResourceBundle. Instances of Level are already held by Level.knownLevel - this is a known bug, and until that is fixed Logger won't be the only thing preventing a custom instance of Level from being garbage collected. In addition such a custom instance of Level (an instance of a custom Level subclass) can't be set directly from the configuration - so this can only happen if the application has set this level programmatically on the Logger. If I remember well Handlers created from the configuration are looked up from the System ClassLoader - so that shouldn't cause a memory leak either. Remains resource bundles - which might be an issue. However - the set of loggers for which a Handler is configured from the configuration file is by nature bounded. Therefore - it is my opinion that the proposed patch does not create a memory leak per-se: A memory leak can only happen if an application constantly (and programmatically) adds new Handler to the existing logger, believing that it will get a new instance of Logger each time because the old one should have been gc'ed. In that case - I believe the fault would be in the application, not in the Logger... If you think that we should still leave the door open for an application to explicitly request the old behavior - we could define a new property for the configuration file. e.g. something like: .handlers = // no changes here .handlers.ensureCloseOnReset = false // new property // True by default when a logger has handlers configured from logging.properties. // Can be explicitly turned off for a given logger, in the configuration. // Ignored if the logger has no handler configured. // Not inherited by child loggers If .handlers.ensureCloseOnReset is explicitly set to false then the LogManager will not add the logger to the persistentLoggers list. Do you think we should do that? best regards, -- daniel On 10/24/14 8:31 PM, Mandy Chung wrote: > > On 10/10/2014 8:39 AM, Daniel Fuchs wrote: >> http://cr.openjdk.java.net/~dfuchs/webrev_8060132/webrev.01 > > Sorry for the delay. I have been pondering if there is a better > alternative and looks like you have considered a few other options > that none of them is a good one. > > typos: > > 174 explicitely > 925: persitentLoggers > > Is this only problem to the abstract node of Loggers (i.e. the ancestor > is in the logging configuration but the library/app never creates such > a logger)? > > Your patch will keep all loggers defined in the configuration strong > reference. What if the application really wants the loggers say > com.foo.FooLogger to get GC'ed (e.g. it wants the logger class and > its defining class loader to be garbage collected) but the configuration > does name com.foo.FooLogger.handler = .... > > Would that cause memory leak? > > Mandy From peter.levart at gmail.com Fri Oct 24 22:07:01 2014 From: peter.levart at gmail.com (Peter Levart) Date: Sat, 25 Oct 2014 00:07:01 +0200 Subject: RFR: 8061244 Use of stack-less ClassNotFoundException thrown from (URL)ClassLoader.findClass() In-Reply-To: <544832CE.4020203@oracle.com> References: <543EF592.3030409@gmail.com> <543F754B.4020001@gmail.com> <543F8558.2030401@gmail.com> <543FD0A6.3080207@gmail.com> <54463760.6090809@gmail.com> <544832CE.4020203@oracle.com> Message-ID: <544ACD85.1030606@gmail.com> On 10/23/2014 12:42 AM, Mandy Chung wrote: > Talking about exceptions and fillInStackTrace, it's known to be > significant cost. It'd be interesting to have the VM flag that can > measure the time it spends in filling in the backtrace of each > exception type (and perhaps the mean and max stack depth) that will > give a better idea of the performance distribution. In addition, > doPrivileged wraps checked exception with PrivilegedActionException > that essentially has the same stack trace and it doubles the cost even > in the absence of security manager. I have exchanged some mail with > the security team to see if this is a low-hanging fruit to improve the > performance. > > Mandy For such cases, where the purpose is to just change the type of exception, a Throwable constructor (+ Exception, RuntimeException and Error constructors chained to it) like the following would be helpful: protected Throwable(Throwable cause, boolean poseAsCause) { if (poseAsCause && cause != null) { backtrace = cause.backtrace; stackTrace = cause.stackTrace; suppressedExceptions = cause.suppressedExceptions; detailMessage = "Posing as: " + cause; } else { fillInStackTrace(); detailMessage = (cause==null ? null : cause.toString()); } this.cause = cause; } Such exceptions would inherit the stack-trace from their cause, eliminating the need to construct their own stack-trace that would be basically a suffix of the stack-trace of the cause. Regards, Peter From ioi.lam at oracle.com Fri Oct 24 23:38:04 2014 From: ioi.lam at oracle.com (Ioi Lam) Date: Fri, 24 Oct 2014 16:38:04 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 2) In-Reply-To: <544AC5BD.4010407@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> Message-ID: <544AE2DC.2030107@oracle.com> Hi Mandy, Thanks for the review. please see comments in-line On 10/24/14, 2:33 PM, Mandy Chung wrote: > > On 10/23/2014 9:34 PM, Ioi Lam wrote: >> Hi Mandy, >> >> Thanks for the review. I have updated the patch: >> >> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v2/ >> >> > Thanks for removing the LoaderType enum. Two questions - > do you need the new hasLookupCacheLoader variable? Should > lookupCAcheURLs be always be non-null if it has the lookup > cache? I removed hasLookupCacheLoader and changed the condition check to (lookupCacheURLs != null) > > Most methods referencinglookupCacheURLs and lookupCacheLoader > are synchronized except initLookupCache and knowToNotExist. > Should they? Or volatile? > I changed both to synchronized. >> On 10/21/14, 12:56 PM, Mandy Chung wrote: >> >>> line 398: what happens if loaders.size() > maxindex? Shouldn't >>> it return null? >> In this case, all the loaders that's needed by the cache[] have been >> opened. So we should return cache[]. > > I forget about that, sorry. I'm thinking how to make it more > obvious to those who doesn't know much of the details. Every time I > read this and I need to reload what I know about and miss something. > >> I changed the code to this. What do you think? > > It seems to me that it would help if you refactor and add a method > "ensureLoadersInited" that will make it clear what it attempts to do. > The side effect invalidating the cache can be checked after it's > called and no need to worry about lookupCacheEnabled must be checked > in any order. Something like this > if (cache != null && cache.length > 0) { > int maxindex = cache[cache.length - 1]; > ensureLoaderOpened(maxindex); > if (loaders.get(maxindex) == null || !lookupCacheEnabled) { > if (DEBUG_LOOKUP_CACHE) { > System.out.println("Expanded loaders FAILED " + > loaders.size() + " for maxindex=" + maxindex); > } > return null; > } > ... > } > return cache; I changed the code to private synchronized int[] getLookupCache(String name) { if (lookupCacheURLs == null || !lookupCacheEnabled) { return null; } int cache[] = getLookupCacheForClassLoader(lookupCacheLoader, name); if (cache != null && cache.length > 0) { int maxindex = cache[cache.length - 1]; // cache[] is strictly ascending. if (!ensureLoaderOpened(maxindex)) { if (DEBUG_LOOKUP_CACHE) { System.out.println("Expanded loaders FAILED " + loaders.size() + " for maxindex=" + maxindex); } return null; } } return cache; } private boolean ensureLoaderOpened(int index) { if (loaders.size() <= index) { // Open all Loaders up to, and including, index if (getLoader(index) == null) { return false; } if (!lookupCacheEnabled) { // cache was invalidated as the result of the above call. return false; } if (DEBUG_LOOKUP_CACHE) { System.out.println("Expanded loaders " + loaders.size() + " to index=" + index); } } return true; } > The code is getting further complicated with this lookup cache and > bear with me for being picky. > >> if (loaders.size() <= maxindex) { >> boolean failed = false; >> >> // Call getNextLoader() with a null cache to open all >> // Loaders up to, and including, maxindex. >> if (getNextLoader(null, maxindex) == null) { > > Can this call getLoader(maxindex)? They are essentially the same. > I think getLoader(maxindex) makes it explicit that it forces to > open the loader. Changed. > Mandy From ioi.lam at oracle.com Fri Oct 24 23:37:05 2014 From: ioi.lam at oracle.com (Ioi Lam) Date: Fri, 24 Oct 2014 16:37:05 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 2) In-Reply-To: <544A2DB1.3040807@oracle.com> References: <54469778.8090008@oracle.com> <5446CA6B.5090204@oracle.com> <5449D6F1.1030209@oracle.com> <544A2DB1.3040807@oracle.com> Message-ID: <544AE2A1.3040204@oracle.com> On 10/24/14, 3:45 AM, Claes Redestad wrote: > On 10/24/2014 06:34 AM, Ioi Lam wrote: >>> Can lookupCacheEnabled flag change during runtime? In >>> getLookupCache() the flag is checked more than once. >>> >> Yes, it can change if disableAllLookupCaches() is called in the >> middle of getLookupCache(). I have added more comments in the new >> webrev. Please take a look to see if it makes sense. >> >> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v2/ > > What is the reason to have lookupCacheEnabled disabled globally when > for example calling addURL on *any* URLClassLoader? Couldn't the > disabling of cache lookups be per URLClassPath rather than global? > > /Claes Claes, Thanks for pointing that out. Here's the new code public synchronized void addURL(URL url) { if (closed) return; synchronized (urls) { if (url == null || path.contains(url)) return; urls.add(0, url); path.add(url); + + if (lookupCacheURLs != null) { + // The lookup cache is no longer valid, since getLookupCache() + // does not consider the newly added url. + disableAllLookupCaches(); + } } } There are dependencies in the caches: Currently the cache is supported only for the boot, ext and app loaders. If the boot classpath is appended via addURL, then we need to disable the caches for ext and app loaders as well. If the app classpath is appended, then there's no need to disable the boot or ext caches. However, the app lookup cache is typically the largest, so keeping the other two caches alive don't buy you that much. So instead of trying to do it "right", I decided to go for simplicity. If any one of the 3 loaders are changed, I disable the cache. URLClassLoaders that are not these 3 loaders won't cause the cache to be disabled. Thanks - Ioi From ivan.gerasimov at oracle.com Sat Oct 25 18:14:49 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sat, 25 Oct 2014 22:14:49 +0400 Subject: RFR 8023173: FileDescriptor should respect append flag In-Reply-To: <543271F1.8040505@oracle.com> References: <543271F1.8040505@oracle.com> Message-ID: <544BE899.5090503@oracle.com> Hello everyone! I've changed the fix in order to address the concerns Alan had mentioned. Now, both the Unix and Windows implementations of FileDescriptor class have the append flag. First, it allows such querying the file descriptor in FileChannelImpl.position() that does not involve JNI calls. Second, this flag is passed to the write functions as an argument, so there's no need to retrieve it from the native code. The fix was built on all available platforms. All the tests from io, nio pass. BUGURL: https://bugs.openjdk.java.net/browse/JDK-8023173 WEBREV: http://cr.openjdk.java.net/~igerasim/8023173/3/webrev/ Would you please help review this? Sincerely yours, Ivan From peter.levart at gmail.com Sun Oct 26 20:25:56 2014 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 26 Oct 2014 21:25:56 +0100 Subject: Loading classes with many methods is very expensive In-Reply-To: References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> Message-ID: <544D58D4.7020909@gmail.com> Hi all, I revamped the Class.getMethods() implementation so that it is faster for common cases and O(n) at the same time, which makes Martin's test happy (at least in part that measures getMethods() speed - the class loading / linkage in VM is a separate issue). With the following test that loads all classes from rt.jar and calls getMethods() on each of them: http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/GetAllRtMethods.java And system property 'sun.reflect.noCaches=true' (so that we exercise the logic in every loop - not just 1st), original code prints: 19657 classes loaded in 1.987373401 seconds. 494141 methods obtained in 1.02493941 seconds. 494141 methods obtained in 0.905235658 seconds. 494141 methods obtained in 0.914434303 seconds. 494141 methods obtained in 0.887212805 seconds. 494141 methods obtained in 0.888929483 seconds. 494141 methods obtained in 0.883309141 seconds. 494141 methods obtained in 0.88341098 seconds. 494141 methods obtained in 0.897397146 seconds. 494141 methods obtained in 0.885677466 seconds. 494141 methods obtained in 0.895834176 seconds. Patched code does the same about 10% faster: 19657 classes loaded in 2.084409717 seconds. 494124 methods obtained in 0.915928578 seconds. 494124 methods obtained in 0.785342465 seconds. 494124 methods obtained in 0.784852619 seconds. 494124 methods obtained in 0.793450205 seconds. 494124 methods obtained in 0.849915078 seconds. 494124 methods obtained in 0.77835511 seconds. 494124 methods obtained in 0.764144701 seconds. 494124 methods obtained in 0.754122383 seconds. 494124 methods obtained in 0.747961897 seconds. 494124 methods obtained in 0.7489937 seconds. Martin's test prints on my computer with original code the following: Base class load time: 177.80 ms getDeclaredMethods: Methods: 65521, Total time: 35.79 ms, Time per method: 0.0005 ms getMethods : Methods: 65530, Total time: 50.15 ms, Time per method: 0.0008 ms Derived class load time: 34015.70 ms getDeclaredMethods: Methods: 65521, Total time: 33.82 ms, Time per method: 0.0005 ms getMethods : Methods: 65530, Total time: 8122.00 ms, Time per method: 0.1239 ms And with patched code this: Base class load time: 157.16 ms getDeclaredMethods: Methods: 65521, Total time: 65.77 ms, Time per method: 0.0010 ms getMethods : Methods: 65530, Total time: 44.64 ms, Time per method: 0.0007 ms Derived class load time: 33996.69 ms getDeclaredMethods: Methods: 65521, Total time: 32.63 ms, Time per method: 0.0005 ms getMethods : Methods: 65530, Total time: 92.12 ms, Time per method: 0.0014 ms Here's a webrev of the patch: http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.01/ Patched code is simpler (65 lines gone) and I hope, easier to understand and change (I think a change in spec is coming in JDK9 which will handle abstract interface methods the same way as default, right Joel?) I also took the liberty to eliminate some redundant array and Field/Method/Constructor copies. get[Method0,Field0,Counstuctor0] now return 'root' objects. Copying is performed in methods that call them and expose the objects to any code outside java.lang.Class. Also, findFields() and findMethods() don't do copying of Field/Method objects themselves, but rather live that to methods that call them. getInterfaces() method now delegates to getInterfaces(boolean copyArray) so that internally, not array copying is performed. All 55 java/lang/reflect jtreg tests pass with this patch. Regards, Peter From richard.warburton at gmail.com Sun Oct 26 21:10:25 2014 From: richard.warburton at gmail.com (Richard Warburton) Date: Sun, 26 Oct 2014 21:10:25 +0000 Subject: Lower overhead String encoding/decoding In-Reply-To: <5444BB17.8080708@oracle.com> References: <54200F07.4070604@oracle.com> <542441BB.600@oracle.com> <5444BB17.8080708@oracle.com> Message-ID: Hi Alan, I think this looks better but I have a few comments on the API. > Thanks for taking the time to look at this - most appreciated. I've pushed the latest iteration to http://cr.openjdk.java.net/~rwarburton/string-patch-webrev-8/. For String(ByteBuffer, Charset) then it's still inconsistent to read from > the buffer position but not advance it. I think the constructor needs to > work like a regular decode in that respect. Related to this is the > underflow case where there are insufficient remaining bytes to complete. If > you don't advance the position then there is no way to detect this. > I've modified the Javadoc and tests. The implementation was actually behaving this way already. The statement about the length of the String ".. may not be equal to the > length of the subarray" might be there from a previous iteration. There > isn't any array in the method signature so I think this statement needs to > be make a bit clearer. > I've rephrased this to refer to the ByteBuffer. For getBytes(byte[], int, int, Charset) then I think the javadoc could say > a bit more. It will encode to a maximum of destBuffer.length - destOffset > for example. The @return should probably say that it's the number of bytes > written to the array rather than "copied". Minor nits is that you probably > don't want the starting

. Also the finals in the signature seem > noisy/not needed. > The getBytes(ByteBuffer, Charset) method needs a bit more javadoc. You > should be able to borrow from text from the CharsetEncoder#encode methods > to help with that. > I've updated the Javadoc with more information about the encoding and made these changes. I'm not sure if there's anything else that's missing in this case. regards, Richard Warburton http://insightfullogic.com @RichardWarburto From stanimir at riflexo.com Sun Oct 26 22:21:31 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Mon, 27 Oct 2014 00:21:31 +0200 Subject: Loading classes with many methods is very expensive In-Reply-To: <544D58D4.7020909@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> Message-ID: Great effort. >From first glance: the hashCode and equals of MethodList use m.getParameterTypes() which is cloned. I'd rather pay the collision costs and rely on the default hashCode/equals of Method itself (hashCode ignores the parameters). Possibly hashCode can include the returnType but equals should be direct call to Method.equals. Stanimir On Sun, Oct 26, 2014 at 10:25 PM, Peter Levart wrote: > Hi all, > > I revamped the Class.getMethods() implementation so that it is faster for > common cases and O(n) at the same time, which makes Martin's test happy (at > least in part that measures getMethods() speed - the class loading / > linkage in VM is a separate issue). > > With the following test that loads all classes from rt.jar and calls > getMethods() on each of them: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class. > getMethods/GetAllRtMethods.java > > And system property 'sun.reflect.noCaches=true' (so that we exercise the > logic in every loop - not just 1st), original code prints: > > 19657 classes loaded in 1.987373401 seconds. > 494141 methods obtained in 1.02493941 seconds. > 494141 methods obtained in 0.905235658 seconds. > 494141 methods obtained in 0.914434303 seconds. > 494141 methods obtained in 0.887212805 seconds. > 494141 methods obtained in 0.888929483 seconds. > 494141 methods obtained in 0.883309141 seconds. > 494141 methods obtained in 0.88341098 seconds. > 494141 methods obtained in 0.897397146 seconds. > 494141 methods obtained in 0.885677466 seconds. > 494141 methods obtained in 0.895834176 seconds. > > Patched code does the same about 10% faster: > > 19657 classes loaded in 2.084409717 seconds. > 494124 methods obtained in 0.915928578 seconds. > 494124 methods obtained in 0.785342465 seconds. > 494124 methods obtained in 0.784852619 seconds. > 494124 methods obtained in 0.793450205 seconds. > 494124 methods obtained in 0.849915078 seconds. > 494124 methods obtained in 0.77835511 seconds. > 494124 methods obtained in 0.764144701 seconds. > 494124 methods obtained in 0.754122383 seconds. > 494124 methods obtained in 0.747961897 seconds. > 494124 methods obtained in 0.7489937 seconds. > > Martin's test prints on my computer with original code the following: > > Base class load time: 177.80 ms > getDeclaredMethods: Methods: 65521, Total time: 35.79 ms, Time per method: > 0.0005 ms > getMethods : Methods: 65530, Total time: 50.15 ms, Time per method: > 0.0008 ms > Derived class load time: 34015.70 ms > getDeclaredMethods: Methods: 65521, Total time: 33.82 ms, Time per method: > 0.0005 ms > getMethods : Methods: 65530, Total time: 8122.00 ms, Time per > method: 0.1239 ms > > And with patched code this: > > Base class load time: 157.16 ms > getDeclaredMethods: Methods: 65521, Total time: 65.77 ms, Time per method: > 0.0010 ms > getMethods : Methods: 65530, Total time: 44.64 ms, Time per method: > 0.0007 ms > Derived class load time: 33996.69 ms > getDeclaredMethods: Methods: 65521, Total time: 32.63 ms, Time per method: > 0.0005 ms > getMethods : Methods: 65530, Total time: 92.12 ms, Time per method: > 0.0014 ms > > > Here's a webrev of the patch: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.01/ > > Patched code is simpler (65 lines gone) and I hope, easier to understand > and change (I think a change in spec is coming in JDK9 which will handle > abstract interface methods the same way as default, right Joel?) > > I also took the liberty to eliminate some redundant array and > Field/Method/Constructor copies. get[Method0,Field0,Counstuctor0] now > return 'root' objects. Copying is performed in methods that call them and > expose the objects to any code outside java.lang.Class. Also, findFields() > and findMethods() don't do copying of Field/Method objects themselves, but > rather live that to methods that call them. getInterfaces() method now > delegates to getInterfaces(boolean copyArray) so that internally, not array > copying is performed. > > All 55 java/lang/reflect jtreg tests pass with this patch. > > > Regards, Peter > > From peter.levart at gmail.com Sun Oct 26 22:36:11 2014 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 26 Oct 2014 23:36:11 +0100 Subject: Loading classes with many methods is very expensive In-Reply-To: References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> Message-ID: <544D775B.6060408@gmail.com> On 10/26/2014 11:21 PM, Stanimir Simeonoff wrote: > Great effort. > > From first glance: the hashCode and equals of MethodList use > m.getParameterTypes() which is cloned. I'd rather pay the collision > costs and rely on the default hashCode/equals of Method itself > (hashCode ignores the parameters). Possibly hashCode can include the > returnType but equals should be direct call to Method.equals. Can't do that as Method.equals also compares declaringClass, which is not part of method signature. We could use SharedSecrets to access the internal array of parameterTypes directly. Regards, Peter > > Stanimir > > > > > On Sun, Oct 26, 2014 at 10:25 PM, Peter Levart > wrote: > > Hi all, > > I revamped the Class.getMethods() implementation so that it is > faster for common cases and O(n) at the same time, which makes > Martin's test happy (at least in part that measures getMethods() > speed - the class loading / linkage in VM is a separate issue). > > With the following test that loads all classes from rt.jar and > calls getMethods() on each of them: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/GetAllRtMethods.java > > > And system property 'sun.reflect.noCaches=true' (so that we > exercise the logic in every loop - not just 1st), original code > prints: > > 19657 classes loaded in 1.987373401 seconds. > 494141 methods obtained in 1.02493941 seconds. > 494141 methods obtained in 0.905235658 seconds. > 494141 methods obtained in 0.914434303 seconds. > 494141 methods obtained in 0.887212805 seconds. > 494141 methods obtained in 0.888929483 seconds. > 494141 methods obtained in 0.883309141 seconds. > 494141 methods obtained in 0.88341098 seconds. > 494141 methods obtained in 0.897397146 seconds. > 494141 methods obtained in 0.885677466 seconds. > 494141 methods obtained in 0.895834176 seconds. > > Patched code does the same about 10% faster: > > 19657 classes loaded in 2.084409717 seconds. > 494124 methods obtained in 0.915928578 seconds. > 494124 methods obtained in 0.785342465 seconds. > 494124 methods obtained in 0.784852619 seconds. > 494124 methods obtained in 0.793450205 seconds. > 494124 methods obtained in 0.849915078 seconds. > 494124 methods obtained in 0.77835511 seconds. > 494124 methods obtained in 0.764144701 seconds. > 494124 methods obtained in 0.754122383 seconds. > 494124 methods obtained in 0.747961897 seconds. > 494124 methods obtained in 0.7489937 seconds. > > Martin's test prints on my computer with original code the following: > > Base class load time: 177.80 ms > getDeclaredMethods: Methods: 65521, Total time: 35.79 ms, Time per > method: 0.0005 ms > getMethods : Methods: 65530, Total time: 50.15 ms, Time per > method: 0.0008 ms > Derived class load time: 34015.70 ms > getDeclaredMethods: Methods: 65521, Total time: 33.82 ms, Time per > method: 0.0005 ms > getMethods : Methods: 65530, Total time: 8122.00 ms, Time > per method: 0.1239 ms > > And with patched code this: > > Base class load time: 157.16 ms > getDeclaredMethods: Methods: 65521, Total time: 65.77 ms, Time per > method: 0.0010 ms > getMethods : Methods: 65530, Total time: 44.64 ms, Time per > method: 0.0007 ms > Derived class load time: 33996.69 ms > getDeclaredMethods: Methods: 65521, Total time: 32.63 ms, Time per > method: 0.0005 ms > getMethods : Methods: 65530, Total time: 92.12 ms, Time per > method: 0.0014 ms > > > Here's a webrev of the patch: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.01/ > > > Patched code is simpler (65 lines gone) and I hope, easier to > understand and change (I think a change in spec is coming in JDK9 > which will handle abstract interface methods the same way as > default, right Joel?) > > I also took the liberty to eliminate some redundant array and > Field/Method/Constructor copies. get[Method0,Field0,Counstuctor0] > now return 'root' objects. Copying is performed in methods that > call them and expose the objects to any code outside > java.lang.Class. Also, findFields() and findMethods() don't do > copying of Field/Method objects themselves, but rather live that > to methods that call them. getInterfaces() method now delegates to > getInterfaces(boolean copyArray) so that internally, not array > copying is performed. > > All 55 java/lang/reflect jtreg tests pass with this patch. > > > Regards, Peter > > From stanimir at riflexo.com Sun Oct 26 22:48:14 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Mon, 27 Oct 2014 00:48:14 +0200 Subject: Loading classes with many methods is very expensive In-Reply-To: <544D775B.6060408@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D775B.6060408@gmail.com> Message-ID: On Mon, Oct 27, 2014 at 12:36 AM, Peter Levart wrote: > > On 10/26/2014 11:21 PM, Stanimir Simeonoff wrote: > > Great effort. > > From first glance: the hashCode and equals of MethodList use > m.getParameterTypes() which is cloned. I'd rather pay the collision costs > and rely on the default hashCode/equals of Method itself (hashCode ignores > the parameters). Possibly hashCode can include the returnType but equals > should be direct call to Method.equals. > > > Can't do that as Method.equals also compares declaringClass, which is not > part of method signature. > > We could use SharedSecrets to access the internal array of parameterTypes > directly. > > Opps, very true. If SharedSecrets is not available, get the parameters in the constructor, so clone happens once only. Method.clone() should be comparable to the cost of a LHM node, so the overhead is not so high. I doubt the JIT can EA clone() which would be the best case scenario. I was wondering if the computation of size is better than just array copy (as LHM.iterator is effectively linked list), however for small number of methods it would keep all the references in L1 so that would be better in the common case. Stanimir > Regards, Peter > > > > Stanimir > > > > > On Sun, Oct 26, 2014 at 10:25 PM, Peter Levart > wrote: > >> Hi all, >> >> I revamped the Class.getMethods() implementation so that it is faster for >> common cases and O(n) at the same time, which makes Martin's test happy (at >> least in part that measures getMethods() speed - the class loading / >> linkage in VM is a separate issue). >> >> With the following test that loads all classes from rt.jar and calls >> getMethods() on each of them: >> >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/GetAllRtMethods.java >> >> And system property 'sun.reflect.noCaches=true' (so that we exercise the >> logic in every loop - not just 1st), original code prints: >> >> 19657 classes loaded in 1.987373401 seconds. >> 494141 methods obtained in 1.02493941 seconds. >> 494141 methods obtained in 0.905235658 seconds. >> 494141 methods obtained in 0.914434303 seconds. >> 494141 methods obtained in 0.887212805 seconds. >> 494141 methods obtained in 0.888929483 seconds. >> 494141 methods obtained in 0.883309141 seconds. >> 494141 methods obtained in 0.88341098 seconds. >> 494141 methods obtained in 0.897397146 seconds. >> 494141 methods obtained in 0.885677466 seconds. >> 494141 methods obtained in 0.895834176 seconds. >> >> Patched code does the same about 10% faster: >> >> 19657 classes loaded in 2.084409717 seconds. >> 494124 methods obtained in 0.915928578 seconds. >> 494124 methods obtained in 0.785342465 seconds. >> 494124 methods obtained in 0.784852619 seconds. >> 494124 methods obtained in 0.793450205 seconds. >> 494124 methods obtained in 0.849915078 seconds. >> 494124 methods obtained in 0.77835511 seconds. >> 494124 methods obtained in 0.764144701 seconds. >> 494124 methods obtained in 0.754122383 seconds. >> 494124 methods obtained in 0.747961897 seconds. >> 494124 methods obtained in 0.7489937 seconds. >> >> Martin's test prints on my computer with original code the following: >> >> Base class load time: 177.80 ms >> getDeclaredMethods: Methods: 65521, Total time: 35.79 ms, Time per >> method: 0.0005 ms >> getMethods : Methods: 65530, Total time: 50.15 ms, Time per >> method: 0.0008 ms >> Derived class load time: 34015.70 ms >> getDeclaredMethods: Methods: 65521, Total time: 33.82 ms, Time per >> method: 0.0005 ms >> getMethods : Methods: 65530, Total time: 8122.00 ms, Time per >> method: 0.1239 ms >> >> And with patched code this: >> >> Base class load time: 157.16 ms >> getDeclaredMethods: Methods: 65521, Total time: 65.77 ms, Time per >> method: 0.0010 ms >> getMethods : Methods: 65530, Total time: 44.64 ms, Time per >> method: 0.0007 ms >> Derived class load time: 33996.69 ms >> getDeclaredMethods: Methods: 65521, Total time: 32.63 ms, Time per >> method: 0.0005 ms >> getMethods : Methods: 65530, Total time: 92.12 ms, Time per >> method: 0.0014 ms >> >> >> Here's a webrev of the patch: >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.01/ >> >> Patched code is simpler (65 lines gone) and I hope, easier to understand >> and change (I think a change in spec is coming in JDK9 which will handle >> abstract interface methods the same way as default, right Joel?) >> >> I also took the liberty to eliminate some redundant array and >> Field/Method/Constructor copies. get[Method0,Field0,Counstuctor0] now >> return 'root' objects. Copying is performed in methods that call them and >> expose the objects to any code outside java.lang.Class. Also, findFields() >> and findMethods() don't do copying of Field/Method objects themselves, but >> rather live that to methods that call them. getInterfaces() method now >> delegates to getInterfaces(boolean copyArray) so that internally, not array >> copying is performed. >> >> All 55 java/lang/reflect jtreg tests pass with this patch. >> >> >> Regards, Peter >> >> > > From peter.levart at gmail.com Sun Oct 26 22:53:40 2014 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 26 Oct 2014 23:53:40 +0100 Subject: Loading classes with many methods is very expensive In-Reply-To: <544D58D4.7020909@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> Message-ID: <544D7B74.5060607@gmail.com> On 10/26/2014 09:25 PM, Peter Levart wrote: > 19657 classes loaded in 1.987373401 seconds. > 494141 methods obtained in 1.02493941 seconds. > > vs. > > 19657 classes loaded in 2.084409717 seconds. > 494124 methods obtained in 0.915928578 seconds. Hi, As you might have noticed, the number of methods obtained from patched code differed from original code. I have investigated this and found that original code treats abstract class methods the same as abstract interface methods as far as multiple inheritance is concerned (it keeps them together in the returned array). So I fixed this and here's new webrev which behaves the same as original code: http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.02/ Comparing original vs. patched code still shows speed-up: Original: 19657 classes loaded in 1.980493029 seconds. 494141 methods obtained in 0.976318927 seconds. 494141 methods obtained in 0.886504437 seconds. 494141 methods obtained in 0.911153722 seconds. 494141 methods obtained in 0.880550509 seconds. 494141 methods obtained in 0.875526704 seconds. 494141 methods obtained in 0.877258894 seconds. 494141 methods obtained in 0.871794344 seconds. 494141 methods obtained in 0.884159644 seconds. 494141 methods obtained in 0.892648522 seconds. 494141 methods obtained in 0.884581841 seconds. Patched: 19657 classes loaded in 2.055697675 seconds. 494141 methods obtained in 0.853922188 seconds. 494141 methods obtained in 0.776203794 seconds. 494141 methods obtained in 0.858774803 seconds. 494141 methods obtained in 0.778178867 seconds. 494141 methods obtained in 0.760043997 seconds. 494141 methods obtained in 0.756352444 seconds. 494141 methods obtained in 0.740826372 seconds. 494141 methods obtained in 0.744264782 seconds. 494141 methods obtained in 0.73805894 seconds. 494141 methods obtained in 0.746852752 seconds. 55 java/lang/reflect jtreg tests still pass. As they did before, which means that we don't have a coverage for such cases. I'll see where I can add such a case (EnumSet for example, which inherits from Set interface and AbstractColection class via two different paths, so Set.size()/iterator() and AbstractCollection.size()/iterator() are both returned from getMethods())... Regards, Peter From stanimir at riflexo.com Sun Oct 26 23:19:47 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Mon, 27 Oct 2014 01:19:47 +0200 Subject: Loading classes with many methods is very expensive In-Reply-To: <544D7B74.5060607@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> Message-ID: > > 55 java/lang/reflect jtreg tests still pass. As they did before, which > means that we don't have a coverage for such cases. I'll see where I can > add such a case (EnumSet for example, which inherits from Set interface and > AbstractColection class via two different paths, so Set.size()/iterator() > and AbstractCollection.size()/iterator() are both returned from > getMethods())... > Reminds me the case when a package private class implementing a public interface cannot have its methods invoked via object.getClass().getMethod(name, classes).invoke(object, args) outside the package. Also I can't find any spec. on how multiple equivalent methods should be returned. > > Regards, Peter > > From david.holmes at oracle.com Sun Oct 26 23:27:45 2014 From: david.holmes at oracle.com (David Holmes) Date: Mon, 27 Oct 2014 09:27:45 +1000 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 2) In-Reply-To: <544AE2DC.2030107@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> Message-ID: <544D8371.3000606@oracle.com> Style nit: all the int cache[] should be int[] cache Also not clear if 8061651-lookup-index-open-v2 is latest webrev ?? Thanks, David On 25/10/2014 9:38 AM, Ioi Lam wrote: > Hi Mandy, > > Thanks for the review. please see comments in-line > > On 10/24/14, 2:33 PM, Mandy Chung wrote: >> >> On 10/23/2014 9:34 PM, Ioi Lam wrote: >>> Hi Mandy, >>> >>> Thanks for the review. I have updated the patch: >>> >>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v2/ >>> >>> >> Thanks for removing the LoaderType enum. Two questions - >> do you need the new hasLookupCacheLoader variable? Should >> lookupCAcheURLs be always be non-null if it has the lookup >> cache? > I removed hasLookupCacheLoader and changed the condition check to > (lookupCacheURLs != null) >> >> Most methods referencinglookupCacheURLs and lookupCacheLoader >> are synchronized except initLookupCache and knowToNotExist. >> Should they? Or volatile? >> > I changed both to synchronized. >>> On 10/21/14, 12:56 PM, Mandy Chung wrote: >>> >>>> line 398: what happens if loaders.size() > maxindex? Shouldn't >>>> it return null? >>> In this case, all the loaders that's needed by the cache[] have been >>> opened. So we should return cache[]. >> >> I forget about that, sorry. I'm thinking how to make it more >> obvious to those who doesn't know much of the details. Every time I >> read this and I need to reload what I know about and miss something. >> >>> I changed the code to this. What do you think? >> >> It seems to me that it would help if you refactor and add a method >> "ensureLoadersInited" that will make it clear what it attempts to do. >> The side effect invalidating the cache can be checked after it's >> called and no need to worry about lookupCacheEnabled must be checked >> in any order. Something like this >> if (cache != null && cache.length > 0) { >> int maxindex = cache[cache.length - 1]; >> ensureLoaderOpened(maxindex); >> if (loaders.get(maxindex) == null || !lookupCacheEnabled) { >> if (DEBUG_LOOKUP_CACHE) { >> System.out.println("Expanded loaders FAILED " + >> loaders.size() + " for maxindex=" + >> maxindex); >> } >> return null; >> } >> ... >> } >> return cache; > I changed the code to > > private synchronized int[] getLookupCache(String name) { > if (lookupCacheURLs == null || !lookupCacheEnabled) { > return null; > } > > int cache[] = getLookupCacheForClassLoader(lookupCacheLoader, > name); > if (cache != null && cache.length > 0) { > int maxindex = cache[cache.length - 1]; // cache[] is > strictly ascending. > if (!ensureLoaderOpened(maxindex)) { > if (DEBUG_LOOKUP_CACHE) { > System.out.println("Expanded loaders FAILED " + > loaders.size() + " for > maxindex=" + maxindex); > } > return null; > } > } > > return cache; > } > > private boolean ensureLoaderOpened(int index) { > if (loaders.size() <= index) { > // Open all Loaders up to, and including, index > if (getLoader(index) == null) { > return false; > } > if (!lookupCacheEnabled) { > // cache was invalidated as the result of the above call. > return false; > } > if (DEBUG_LOOKUP_CACHE) { > System.out.println("Expanded loaders " + loaders.size() + > " to index=" + index); > } > } > return true; > } > >> The code is getting further complicated with this lookup cache and >> bear with me for being picky. >> >>> if (loaders.size() <= maxindex) { >>> boolean failed = false; >>> >>> // Call getNextLoader() with a null cache to open all >>> // Loaders up to, and including, maxindex. >>> if (getNextLoader(null, maxindex) == null) { >> >> Can this call getLoader(maxindex)? They are essentially the same. >> I think getLoader(maxindex) makes it explicit that it forces to >> open the loader. > Changed. > >> Mandy > From staffan.larsen at oracle.com Mon Oct 27 07:26:58 2014 From: staffan.larsen at oracle.com (Staffan Larsen) Date: Mon, 27 Oct 2014 08:26:58 +0100 Subject: Review request: JDK-8043277: Update jdk regression tests to extend the default security policy instead of override In-Reply-To: <544A7B6E.1070208@oracle.com> References: <54485505.4030002@oracle.com> <5449055F.30305@oracle.com> <10EB71A5-E389-4639-917D-2C52417354DF@oracle.com> <544A7B6E.1070208@oracle.com> Message-ID: On 24 okt 2014, at 18:16, Mandy Chung wrote: > On 10/24/2014 6:33 AM, Staffan Larsen wrote: > >> Since this is the first use of jtreg 4.1b10 features, this would also be good time to tag the jdk test suite to require at least 4.1b10. >> >> This latest version of jtreg has support for checking which version of jtreg the test suite requires. So you can add a line saying: >> requiredVersion=4.1 b10 >> to TEST.ROOT and jtreg will verify that its version number is higher than ?requiredVersion" when it runs. >> >> It?s not until we move from b10 to b11 that this will actually be useful, but it could be a good time to introduce it. > > Good point since now it depends on b10 feature. Here is > the patch. > > diff --git a/test/TEST.ROOT b/test/TEST.ROOT > --- a/test/TEST.ROOT > +++ b/test/TEST.ROOT > @@ -12,3 +12,6 @@ > # Group definitions > groups=TEST.groups [closed/TEST.groups] > + > +# Tests using jtreg 4.1 b10 features > +requiredVersion=4.1 b10 > > Mandy Looks good! Thanks, /Staffan > > >> >> Thanks, >> /Staffan >> >> On 23 okt 2014, at 15:40, Alan Bateman wrote: >> >>> On 23/10/2014 02:08, Mandy Chung wrote: >>>> jtreg policy option overrides the system security policy file and hence >>>> some existing test policy files have to duplicate the entries to grant >>>> permissions for JDK. >>>> >>> This looks okay to me too. I think this will be the first use of a jtreg4.1-b10 feature and maybe someone should send a note to jdk9-dev to tell folks that they will need an up-to-date jtreg in order to test jdk9/dev. >>> >>> -Alan >>> > From Alan.Bateman at oracle.com Mon Oct 27 07:50:51 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 27 Oct 2014 07:50:51 +0000 Subject: RFR 8023173: FileDescriptor should respect append flag In-Reply-To: <544BE899.5090503@oracle.com> References: <543271F1.8040505@oracle.com> <544BE899.5090503@oracle.com> Message-ID: <544DF95B.8020309@oracle.com> On 25/10/2014 19:14, Ivan Gerasimov wrote: > Hello everyone! > > I've changed the fix in order to address the concerns Alan had mentioned. > > Now, both the Unix and Windows implementations of FileDescriptor class > have the append flag. > First, it allows such querying the file descriptor in > FileChannelImpl.position() that does not involve JNI calls. > Second, this flag is passed to the write functions as an argument, so > there's no need to retrieve it from the native code. > > The fix was built on all available platforms. > All the tests from io, nio pass. > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8023173 > WEBREV: http://cr.openjdk.java.net/~igerasim/8023173/3/webrev/ > > Would you please help review this? Thanks, this looks much better and cleaner than the previous iterations. You can probably drop the setting of append in the no-arg FileDescriptor constructor. Also the "final" in FileChannelImpl.position isn't needed. Otherwise this looks good to me and good to have this long standing corner case addressed. -Alan From ivan.gerasimov at oracle.com Mon Oct 27 08:53:49 2014 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Mon, 27 Oct 2014 12:53:49 +0400 Subject: RFR 8023173: FileDescriptor should respect append flag In-Reply-To: <544DF95B.8020309@oracle.com> References: <543271F1.8040505@oracle.com> <544BE899.5090503@oracle.com> <544DF95B.8020309@oracle.com> Message-ID: <544E081D.9030501@oracle.com> Thanks Alan! I'll remove redundant initialization and final word before pushing. Sincerely yours, Ivan On 27.10.2014 11:50, Alan Bateman wrote: > On 25/10/2014 19:14, Ivan Gerasimov wrote: >> Hello everyone! >> >> I've changed the fix in order to address the concerns Alan had >> mentioned. >> >> Now, both the Unix and Windows implementations of FileDescriptor >> class have the append flag. >> First, it allows such querying the file descriptor in >> FileChannelImpl.position() that does not involve JNI calls. >> Second, this flag is passed to the write functions as an argument, so >> there's no need to retrieve it from the native code. >> >> The fix was built on all available platforms. >> All the tests from io, nio pass. >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8023173 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8023173/3/webrev/ >> >> Would you please help review this? > > Thanks, this looks much better and cleaner than the previous iterations. > > You can probably drop the setting of append in the no-arg > FileDescriptor constructor. Also the "final" in > FileChannelImpl.position isn't needed. > > Otherwise this looks good to me and good to have this long standing > corner case addressed. > > -Alan > > > > From paul.sandoz at oracle.com Mon Oct 27 09:12:11 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 27 Oct 2014 10:12:11 +0100 Subject: Request for review/advice from langtools team Re: Covariant overrides on the Buffer Hierarchy redux In-Reply-To: <35FE2B2C-7BA2-4A11-AE9D-B5E12C7B5729@oracle.com> References: <3D27B84B-20F1-486C-954F-E908DD443DA9@oracle.com> <35FE2B2C-7BA2-4A11-AE9D-B5E12C7B5729@oracle.com> Message-ID: Hi, Can someone from langtools kindly chime in with how to move this forward? https://bugs.openjdk.java.net/browse/JDK-4774077 http://cr.openjdk.java.net/~rwarburton/buffer-overrides-3/ http://cr.openjdk.java.net/~rwarburton/buffer-overrides-langtools-0/langtools.patch On Oct 17, 2014, at 11:37 AM, Paul Sandoz wrote: > Hi, > > [Including compiler-dev, i am not on that list so please CC me if replying to just that list] > > ... > So Richard has a patch for that too: > > http://cr.openjdk.java.net/~rwarburton/buffer-overrides-langtools-0/langtools.patch > > This is required because in the bootstrap compilation phase a JDK without the co-variant overrides can be used. So the current solution is to suppress the warnings. Reviews from langtools gurus are very much appreciated. > ? > Ideally it would be nice to push all this under one issue, is that possible? If not i will have to create another issue and of course push to langtools before jdk. > > A internal CCC is also underway. > This has be approved, with the comment that "@since 1.9" should be added to the doc of the new methods, which i have done in my copy of the patch. Thanks, Paul. From konstantin.shefov at oracle.com Mon Oct 27 10:16:05 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Mon, 27 Oct 2014 13:16:05 +0300 Subject: [9] Review request : JDK-8059070: [TESTBUG] java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java failed - timeout In-Reply-To: References: <543D1DEE.8030206@oracle.com> <543F8520.9090408@oracle.com> <8F9DD322-1793-4739-8155-61CE7D2C5AAB@oracle.com> <543F9800.7040406@oracle.com> <543FC71F.8020504@oracle.com> <5440E39C.8070001@oracle.com> <5448E5A2.9030804@oracle.com> Message-ID: <544E1B65.1090400@oracle.com> Kindly reminder On 23.10.2014 19:04, Paul Sandoz wrote: > On Oct 23, 2014, at 1:25 PM, Konstantin Shefov wrote: >> Gently reminder >> >> On 17.10.2014 13:38, Konstantin Shefov wrote: >>> Hi, >>> >>> I have updated the webrev: >>> http://cr.openjdk.java.net/~kshefov/8059070/webrev.01/ >>> > +1 > > Sorry for the delay, > Paul. From aleksey.shipilev at oracle.com Mon Oct 27 11:23:45 2014 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Mon, 27 Oct 2014 14:23:45 +0300 Subject: Loading classes with many methods is very expensive In-Reply-To: <544D7B74.5060607@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> Message-ID: <544E2B41.3080604@oracle.com> On 10/27/2014 01:53 AM, Peter Levart wrote: > As you might have noticed, the number of methods obtained from patched > code differed from original code. I have investigated this and found > that original code treats abstract class methods the same as abstract > interface methods as far as multiple inheritance is concerned (it keeps > them together in the returned array). So I fixed this and here's new > webrev which behaves the same as original code: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.02/ This seems to be a candidate fix for https://bugs.openjdk.java.net/browse/JDK-8061950, right? If so, please assign yourself there. It might be advisable to start the separate RFR thread for a fix? My comments for the first reading of the patch: * Why MethodList maintains the linked list? Doesn't O(n) MethodList.add() lead to quadratic complexity again? Should we instead use the ArrayList for storing method synonyms? * Please convert some of the indexed loops into for-each loops for better readability? E.g: for (int i = 0; i < intfcsMethods.length; i++) { for (Method m : intfcsMethods[i]) { ...to: for (Method[] ms : intfcsMethods) { for (Method m : ms) { * I would think the code would be more readable if MethodList.m was having a more readable name, e.g. MethodList.base or MethodList.image or MethodList.primary? * Formatting and logic in MethodList.consolidateWith gives me chills. I think at very least introducing variables for m.getDeclaringClass() and ml.m.getDeclaringClass() improve readability. Also, moving the comments at the end of the line should improve readability and better highlight the boolean expression you are spelling out. Below is the straight-forward rewrite: > MethodList consolidateWith(MethodList ml) { > Method mineM = m; > Method otherM = ml.m; > Class mine = mineM.getDeclaringClass(); > Class other = otherM.getDeclaringClass(); > > if (other == mine // other is same method as mine > || !Modifier.isAbstract(mineM.getModifiers()) // OR, mine is non-abstract method... > && (other.isAssignableFrom(mine) // ...which overrides other > || other.isInterface() && !mine.isInterface())) { // ...class method which wins over interface > // just return > return this; > } > if (!Modifier.isAbstract(otherM.getModifiers()) // other is non-abstract method... > && (mine.isAssignableFrom(other) // ...which overrides mine > || mine.isInterface() && !other.isInterface())) { // ...class method which wins over interface > // knock m out and continue > return (next == null) ? ml : next.consolidateWith(ml); > } > > // else leave m in and continue > next = (next == null) ? ml : next.consolidateWith(ml); > return this; > } * Should we use just methods.put() here? 2851 MethodList ml0 = methods.putIfAbsent(ml, ml); * I wonder if the code would be simpler if we push the Map maintenance to some internal utility class? That would probably simplify the loops in privateGetPublicMethods? Thanks, -Aleksey. From stanimir at riflexo.com Mon Oct 27 11:41:46 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Mon, 27 Oct 2014 13:41:46 +0200 Subject: Loading classes with many methods is very expensive In-Reply-To: <544E2B41.3080604@oracle.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <544E2B41.3080604@oracle.com> Message-ID: On Mon, Oct 27, 2014 at 1:23 PM, Aleksey Shipilev < aleksey.shipilev at oracle.com> wrote: > On 10/27/2014 01:53 AM, Peter Levart wrote: > > As you might have noticed, the number of methods obtained from patched > > code differed from original code. I have investigated this and found > > that original code treats abstract class methods the same as abstract > > interface methods as far as multiple inheritance is concerned (it keeps > > them together in the returned array). So I fixed this and here's new > > webrev which behaves the same as original code: > > > > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.02/ > > This seems to be a candidate fix for > https://bugs.openjdk.java.net/browse/JDK-8061950, right? If so, please > assign yourself there. It might be advisable to start the separate RFR > thread for a fix? > > My comments for the first reading of the patch: > > * Why MethodList maintains the linked list? Doesn't O(n) > MethodList.add() lead to quadratic complexity again? Should we instead > use the ArrayList for storing method synonyms? > But N would be the amount of exactly the same overridden methods from superclasses and declared in interfaces. Usually there would be zero or 1-2. So the in-place linked list conserves memory, the extra indirection of ArrayList for n=1 would also be slower. IMO, it's a well designed approach. The only case where it'd actually matter is hundreds of superclasses each overriding all of the their methods. Stanimir > * Please convert some of the indexed loops into for-each loops for > better readability? E.g: > > for (int i = 0; i < intfcsMethods.length; i++) { > for (Method m : intfcsMethods[i]) { > > ...to: > > for (Method[] ms : intfcsMethods) { > for (Method m : ms) { > > * I would think the code would be more readable if MethodList.m was > having a more readable name, e.g. MethodList.base or MethodList.image or > MethodList.primary? > > * Formatting and logic in MethodList.consolidateWith gives me chills. I > think at very least introducing variables for m.getDeclaringClass() and > ml.m.getDeclaringClass() improve readability. Also, moving the comments > at the end of the line should improve readability and better highlight > the boolean expression you are spelling out. Below is the > straight-forward rewrite: > > > MethodList consolidateWith(MethodList ml) { > > Method mineM = m; > > Method otherM = ml.m; > > Class mine = mineM.getDeclaringClass(); > > Class other = otherM.getDeclaringClass(); > > > > if (other == mine // > other is same method as mine > > || !Modifier.isAbstract(mineM.getModifiers()) // > OR, mine is non-abstract method... > > && (other.isAssignableFrom(mine) // > ...which overrides other > > || other.isInterface() && !mine.isInterface())) { // > ...class method which wins over interface > > // just return > > return this; > > } > > if (!Modifier.isAbstract(otherM.getModifiers()) // > other is non-abstract method... > > && (mine.isAssignableFrom(other) // > ...which overrides mine > > || mine.isInterface() && !other.isInterface())) { // > ...class method which wins over interface > > // knock m out and continue > > return (next == null) ? ml : next.consolidateWith(ml); > > } > > > > // else leave m in and continue > > next = (next == null) ? ml : next.consolidateWith(ml); > > return this; > > } > > > * Should we use just methods.put() here? > 2851 MethodList ml0 = methods.putIfAbsent(ml, ml); > > * I wonder if the code would be simpler if we push the Map MethodList> maintenance to some internal utility class? That would > probably simplify the loops in privateGetPublicMethods? > > Thanks, > -Aleksey. > > From peter.levart at gmail.com Mon Oct 27 12:45:47 2014 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 27 Oct 2014 13:45:47 +0100 Subject: Loading classes with many methods is very expensive In-Reply-To: <544E2B41.3080604@oracle.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <544E2B41.3080604@oracle.com> Message-ID: <544E3E7B.9020305@gmail.com> Hi Aleksey, On 10/27/2014 12:23 PM, Aleksey Shipilev wrote: > On 10/27/2014 01:53 AM, Peter Levart wrote: >> As you might have noticed, the number of methods obtained from patched >> code differed from original code. I have investigated this and found >> that original code treats abstract class methods the same as abstract >> interface methods as far as multiple inheritance is concerned (it keeps >> them together in the returned array). So I fixed this and here's new >> webrev which behaves the same as original code: >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.02/ > This seems to be a candidate fix for > https://bugs.openjdk.java.net/browse/JDK-8061950, right? If so, please > assign yourself there. It might be advisable to start the separate RFR > thread for a fix? That's exactly the issue I was looking for. I assigned it to myself. Thanks for looking at the code... > > My comments for the first reading of the patch: > > * Why MethodList maintains the linked list? Doesn't O(n) > MethodList.add() lead to quadratic complexity again? Should we instead > use the ArrayList for storing method synonyms? It's not quadratic, but more O(n*m) where n is the number of methods and m is the number of methods with same signature inherited via different paths from abstract class and/or (super)interfaces. This is typically 1, rarely 2, almost never 3 or more. For example: abstract class A implements I, J, K {} interface I { void m(); } interface J { void m(); } interface K { void m(); } Here the linked list with signature 'void m()' will contain 3 elements. When a particular method for a particular signature is found in a (super)interface, it has to be compared with potentially all methods having same signature and modifications performed while traversing are: do nothing, remove element, append element. So linked-list is perfect for that purpose. LinkedList.add() is only called when an abstract superclass brings multiple methods with same signature and all of them are inherited by abstract subclass - very very rarely is there more than 1 method with same signature inherited from superclass. I merged the functionality of the method-signature-key with the linked-list node, holding just a reference to Method object and a link to 'next' node. I think this is the most compact temporary datastructure representation for that purpose that leverages standard LinkedHashMap. > > * Please convert some of the indexed loops into for-each loops for > better readability? E.g: > > for (int i = 0; i < intfcsMethods.length; i++) { > for (Method m : intfcsMethods[i]) { > > ...to: > > for (Method[] ms : intfcsMethods) { > for (Method m : ms) { Good catch. I'll do this. > * I would think the code would be more readable if MethodList.m was > having a more readable name, e.g. MethodList.base or MethodList.image or > MethodList.primary? Just MethodList.method will be ok - it's nothing special with this method. It just happens to be 1st in list of methods with same signature. With introduction of local variables (later down), the conditions will be shortened in MethodList.consolidateWith() and short field name is not needed. > > * Formatting and logic in MethodList.consolidateWith gives me chills. I > think at very least introducing variables for m.getDeclaringClass() and > ml.m.getDeclaringClass() improve readability. Also, moving the comments > at the end of the line should improve readability and better highlight > the boolean expression you are spelling out. Below is the > straight-forward rewrite: > >> MethodList consolidateWith(MethodList ml) { >> Method mineM = m; >> Method otherM = ml.m; >> Class mine = mineM.getDeclaringClass(); >> Class other = otherM.getDeclaringClass(); >> >> if (other == mine // other is same method as mine >> || !Modifier.isAbstract(mineM.getModifiers()) // OR, mine is non-abstract method... >> && (other.isAssignableFrom(mine) // ...which overrides other >> || other.isInterface() && !mine.isInterface())) { // ...class method which wins over interface >> // just return >> return this; >> } >> if (!Modifier.isAbstract(otherM.getModifiers()) // other is non-abstract method... >> && (mine.isAssignableFrom(other) // ...which overrides mine >> || mine.isInterface() && !other.isInterface())) { // ...class method which wins over interface >> // knock m out and continue >> return (next == null) ? ml : next.consolidateWith(ml); >> } >> >> // else leave m in and continue >> next = (next == null) ? ml : next.consolidateWith(ml); >> return this; >> } Excellent. I'll take your formatting if you don't mind ;-) > > * Should we use just methods.put() here? > 2851 MethodList ml0 = methods.putIfAbsent(ml, ml); It really doesn't matter as the exception is thrown if (ml0 != null) and LinkedHashMap is forgotten... if (ml0 == null), put and putIfAbsent are equivalent. I used putIfAbsent to make the 3 loops (declared methods, superclass methods, (super)interface methods) more uniform. > > * I wonder if the code would be simpler if we push the Map MethodList> maintenance to some internal utility class? That would > probably simplify the loops in privateGetPublicMethods? I thought MethodList.add()/consolidateWith() were close to those utility methods. I could extract the logic in each of 3 loops to 3 void methods taking 'methods' Map and a Method instance, but I don't want to pollute the method namespace in j.l.Class any more than necessary and making a special inner class for that is an overkill. Previously the holder for such methods was MethodArray, but it's gone now. I could subclass LinkedHashMap if I wanted to avoid an unnecessary indirection, but that's not a good practice. It's not that bad as it is - 38 lines of code for 3 loops with comments and spacing. I could improve comments though... > > Thanks, > -Aleksey. > From joel.franck at oracle.com Mon Oct 27 13:45:40 2014 From: joel.franck at oracle.com (=?windows-1252?Q?Joel_Borggr=E9n-Franck?=) Date: Mon, 27 Oct 2014 14:45:40 +0100 Subject: Loading classes with many methods is very expensive In-Reply-To: <544D7B74.5060607@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> Message-ID: Hi Peter, As always, thanks for doing this! It has been on my todolist for a while but never quite bubbling up to the top. I don?t have time to look att his right now, but I expect to have some free time next week, but i have two short comments First, I have been thinking about moving MethodArray to its?s own top-level class, isn?t it about time? Second I would expect testing for the missing cases you uncovered (good catch!). I?ll try to get back to you asap. cheers /Joel On 26 okt 2014, at 23:53, Peter Levart wrote: > > On 10/26/2014 09:25 PM, Peter Levart wrote: >> 19657 classes loaded in 1.987373401 seconds. >> 494141 methods obtained in 1.02493941 seconds. >> >> vs. >> >> 19657 classes loaded in 2.084409717 seconds. >> 494124 methods obtained in 0.915928578 seconds. > > Hi, > > As you might have noticed, the number of methods obtained from patched code differed from original code. I have investigated this and found that original code treats abstract class methods the same as abstract interface methods as far as multiple inheritance is concerned (it keeps them together in the returned array). So I fixed this and here's new webrev which behaves the same as original code: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.02/ > > Comparing original vs. patched code still shows speed-up: > > Original: > > 19657 classes loaded in 1.980493029 seconds. > 494141 methods obtained in 0.976318927 seconds. > 494141 methods obtained in 0.886504437 seconds. > 494141 methods obtained in 0.911153722 seconds. > 494141 methods obtained in 0.880550509 seconds. > 494141 methods obtained in 0.875526704 seconds. > 494141 methods obtained in 0.877258894 seconds. > 494141 methods obtained in 0.871794344 seconds. > 494141 methods obtained in 0.884159644 seconds. > 494141 methods obtained in 0.892648522 seconds. > 494141 methods obtained in 0.884581841 seconds. > > Patched: > > 19657 classes loaded in 2.055697675 seconds. > 494141 methods obtained in 0.853922188 seconds. > 494141 methods obtained in 0.776203794 seconds. > 494141 methods obtained in 0.858774803 seconds. > 494141 methods obtained in 0.778178867 seconds. > 494141 methods obtained in 0.760043997 seconds. > 494141 methods obtained in 0.756352444 seconds. > 494141 methods obtained in 0.740826372 seconds. > 494141 methods obtained in 0.744264782 seconds. > 494141 methods obtained in 0.73805894 seconds. > 494141 methods obtained in 0.746852752 seconds. > > > 55 java/lang/reflect jtreg tests still pass. As they did before, which means that we don't have a coverage for such cases. I'll see where I can add such a case (EnumSet for example, which inherits from Set interface and AbstractColection class via two different paths, so Set.size()/iterator() and AbstractCollection.size()/iterator() are both returned from getMethods())... > > > Regards, Peter > From peter.levart at gmail.com Mon Oct 27 14:19:21 2014 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 27 Oct 2014 15:19:21 +0100 Subject: Loading classes with many methods is very expensive In-Reply-To: References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> Message-ID: <544E5469.7020208@gmail.com> Hi Joel, Thanks for peeking into the code. On 10/27/2014 02:45 PM, Joel Borggr?n-Franck wrote: > Hi Peter, > > As always, thanks for doing this! It has been on my todolist for a while but never quite bubbling up to the top. > > I don?t have time to look att his right now, but I expect to have some free time next week, but i have two short comments > > First, I have been thinking about moving MethodArray to its?s own top-level class, isn?t it about time? Well, you're the second (first was Aleksey) to comment on factoring away the logic into a separate class. I'll do that then. > > Second I would expect testing for the missing cases you uncovered (good catch!). I plan to add a case or two to appropriate test. I'm thinking about test/java/lang/Class/getMethods/StarInheritance.java ... > > I?ll try to get back to you asap. Thank you, Peter > > cheers > /Joel > > > On 26 okt 2014, at 23:53, Peter Levart wrote: > >> On 10/26/2014 09:25 PM, Peter Levart wrote: >>> 19657 classes loaded in 1.987373401 seconds. >>> 494141 methods obtained in 1.02493941 seconds. >>> >>> vs. >>> >>> 19657 classes loaded in 2.084409717 seconds. >>> 494124 methods obtained in 0.915928578 seconds. >> Hi, >> >> As you might have noticed, the number of methods obtained from patched code differed from original code. I have investigated this and found that original code treats abstract class methods the same as abstract interface methods as far as multiple inheritance is concerned (it keeps them together in the returned array). So I fixed this and here's new webrev which behaves the same as original code: >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.02/ >> >> Comparing original vs. patched code still shows speed-up: >> >> Original: >> >> 19657 classes loaded in 1.980493029 seconds. >> 494141 methods obtained in 0.976318927 seconds. >> 494141 methods obtained in 0.886504437 seconds. >> 494141 methods obtained in 0.911153722 seconds. >> 494141 methods obtained in 0.880550509 seconds. >> 494141 methods obtained in 0.875526704 seconds. >> 494141 methods obtained in 0.877258894 seconds. >> 494141 methods obtained in 0.871794344 seconds. >> 494141 methods obtained in 0.884159644 seconds. >> 494141 methods obtained in 0.892648522 seconds. >> 494141 methods obtained in 0.884581841 seconds. >> >> Patched: >> >> 19657 classes loaded in 2.055697675 seconds. >> 494141 methods obtained in 0.853922188 seconds. >> 494141 methods obtained in 0.776203794 seconds. >> 494141 methods obtained in 0.858774803 seconds. >> 494141 methods obtained in 0.778178867 seconds. >> 494141 methods obtained in 0.760043997 seconds. >> 494141 methods obtained in 0.756352444 seconds. >> 494141 methods obtained in 0.740826372 seconds. >> 494141 methods obtained in 0.744264782 seconds. >> 494141 methods obtained in 0.73805894 seconds. >> 494141 methods obtained in 0.746852752 seconds. >> >> >> 55 java/lang/reflect jtreg tests still pass. As they did before, which means that we don't have a coverage for such cases. I'll see where I can add such a case (EnumSet for example, which inherits from Set interface and AbstractColection class via two different paths, so Set.size()/iterator() and AbstractCollection.size()/iterator() are both returned from getMethods())... >> >> >> Regards, Peter >> From aleksey.shipilev at oracle.com Mon Oct 27 15:48:00 2014 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Mon, 27 Oct 2014 18:48:00 +0300 Subject: Loading classes with many methods is very expensive In-Reply-To: <544E3E7B.9020305@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <544E2B41.3080604@oracle.com> <544E3E7B.9020305@gmail.com> Message-ID: <544E6930.8050103@oracle.com> Hi Peter, On 10/27/2014 03:45 PM, Peter Levart wrote: > I merged the functionality of the method-signature-key with the > linked-list node, holding just a reference to Method object and a link > to 'next' node. I think this is the most compact temporary datastructure > representation for that purpose that leverages standard LinkedHashMap. I see. I wonder when somebody come with a stress test using multiple interfaces with the same signature method :) Seems very unlikely. >> * Formatting and logic in MethodList.consolidateWith gives me chills. I >> think at very least introducing variables for m.getDeclaringClass() and >> ml.m.getDeclaringClass() improve readability. Also, moving the comments >> at the end of the line should improve readability and better highlight >> the boolean expression you are spelling out. Below is the >> straight-forward rewrite: >> ... > > Excellent. I'll take your formatting if you don't mind ;-) Sure. Check if I had captured it right first. I think we need to be more strict with parentheses to avoid precedence overlooks: (A || B && C) should better be ((A || B) && C) or (A || (B && C)) >> * Should we use just methods.put() here? >> 2851 MethodList ml0 = methods.putIfAbsent(ml, ml); > > It really doesn't matter as the exception is thrown if (ml0 != null) and > LinkedHashMap is forgotten... > > if (ml0 == null), put and putIfAbsent are equivalent. I used putIfAbsent > to make the 3 loops (declared methods, superclass methods, > (super)interface methods) more uniform. Okay. >> >> * I wonder if the code would be simpler if we push the Map> MethodList> maintenance to some internal utility class? That would >> probably simplify the loops in privateGetPublicMethods? > > I thought MethodList.add()/consolidateWith() were close to those utility > methods. I could extract the logic in each of 3 loops to 3 void methods > taking 'methods' Map and a Method instance, but I don't want to pollute > the method namespace in j.l.Class any more than necessary and making a > special inner class for that is an overkill. Previously the holder for > such methods was MethodArray, but it's gone now. I could subclass > LinkedHashMap if I wanted to avoid an unnecessary indirection, but > that's not a good practice. It's not that bad as it is - 38 lines of > code for 3 loops with comments and spacing. I could improve comments > though... Yes. I had to read the entire thing a couple of times to understand how this works. Containing most of the logic into MethodList seems like a way to improve this. Not sure though. Thanks, -Aleksey. From xueming.shen at oracle.com Mon Oct 27 16:58:42 2014 From: xueming.shen at oracle.com (Xueming Shen) Date: Mon, 27 Oct 2014 09:58:42 -0700 Subject: Lower overhead String encoding/decoding In-Reply-To: References: <54200F07.4070604@oracle.com> <542441BB.600@oracle.com> <5444BB17.8080708@oracle.com> Message-ID: <544E79C2.4010409@oracle.com> On 10/26/2014 02:10 PM, Richard Warburton wrote: > > >> The getBytes(ByteBuffer, Charset) method needs a bit more javadoc. You >> should be able to borrow from text from the CharsetEncoder#encode methods >> to help with that. >> > I've updated the Javadoc with more information about the encoding and made > these changes. I'm not sure if there's anything else that's missing in this > case. > Hi Richard, You have "...reflect the characters read and the byte written..." for the getBtyes(ByteBuffer), the "characters read and" should be deleted? I'm not that sure if it is necessary to document it clearly that there would be no dangling bytes in case of encoding/getBytes(), when there is no enough room/space to encode a full "char"... -Sherman From lance.andersen at oracle.com Mon Oct 27 18:06:40 2014 From: lance.andersen at oracle.com (Lance Andersen) Date: Mon, 27 Oct 2014 14:06:40 -0400 Subject: RFR 8062198: Add RowSetMetaDataImpl Tests and add column range validation to isdefinitlyWritable Message-ID: <3C972A10-3F79-462A-8FFB-0324BD0E5DCA@oracle.com> Hi all, Need a reviewer for the RowSetMetaDataImpl tests which also includes a fix to isDefinitelyWritable so that it validates the column index ranges Included are some minor housekeeping changes to remove redundant classes The webrev can be found at http://cr.openjdk.java.net/~lancea/8062198/webrev.00/ Best Lance Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From martinrb at google.com Mon Oct 27 19:01:59 2014 From: martinrb at google.com (Martin Buchholz) Date: Mon, 27 Oct 2014 12:01:59 -0700 Subject: Loading classes with many methods is very expensive In-Reply-To: <544E6930.8050103@oracle.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <544E2B41.3080604@oracle.com> <544E3E7B.9020305@gmail.com> <544E6930.8050103@oracle.com> Message-ID: I'm having trouble keeping up with this thread I started, but I did update the test/benchmark http://cr.openjdk.java.net/~martin/webrevs/openjdk9/Class.getMethods-benchmark/ I added a test *LoadAllClassesAndMethods *that does what its name says. Although originally written as just a benchmark, it also checks "en passant" that all classes in all JRE jar files can be loaded. Interestingly, openjdk9 passes this test, but proprietary Oracle JDK fails it. I think this is a useful packaging-level test of the entire JDK as well. java.lang.NoClassDefFoundError: Failed to load jfxrt.jar(com/sun/deploy/uitoolkit/impl/fx/FXApplet2Adapter$1.class) at LoadAllClassesAndMethods.loadAllExtensionClasses(LoadAllClassesAndMethods.java:178) at LoadAllClassesAndMethods.methodsByClass(LoadAllClassesAndMethods.java:198) at LoadAllClassesAndMethods.main(LoadAllClassesAndMethods.java:65) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.sun.javatest.regtest.MainWrapper$MainThread.run(MainWrapper.java:94) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.NoClassDefFoundError: com/sun/deploy/uitoolkit/Applet2Adapter at java.lang.ClassLoader.defineClass1(Native Method) Jeremy is independently working on yet another performance problem exposed by *LoadAllClassesAndMethods* On Mon, Oct 27, 2014 at 8:48 AM, Aleksey Shipilev < aleksey.shipilev at oracle.com> wrote: > Hi Peter, > > On 10/27/2014 03:45 PM, Peter Levart wrote: > > I merged the functionality of the method-signature-key with the > > linked-list node, holding just a reference to Method object and a link > > to 'next' node. I think this is the most compact temporary datastructure > > representation for that purpose that leverages standard LinkedHashMap. > > I see. I wonder when somebody come with a stress test using multiple > interfaces with the same signature method :) Seems very unlikely. > > > >> * Formatting and logic in MethodList.consolidateWith gives me chills. > I > >> think at very least introducing variables for m.getDeclaringClass() and > >> ml.m.getDeclaringClass() improve readability. Also, moving the comments > >> at the end of the line should improve readability and better highlight > >> the boolean expression you are spelling out. Below is the > >> straight-forward rewrite: > >> ... > > > > Excellent. I'll take your formatting if you don't mind ;-) > > Sure. Check if I had captured it right first. I think we need to be more > strict with parentheses to avoid precedence overlooks: > (A || B && C) should better be ((A || B) && C) or (A || (B && C)) > > > >> * Should we use just methods.put() here? > >> 2851 MethodList ml0 = methods.putIfAbsent(ml, ml); > > > > It really doesn't matter as the exception is thrown if (ml0 != null) and > > LinkedHashMap is forgotten... > > > > if (ml0 == null), put and putIfAbsent are equivalent. I used putIfAbsent > > to make the 3 loops (declared methods, superclass methods, > > (super)interface methods) more uniform. > > Okay. > > > >> > >> * I wonder if the code would be simpler if we push the > Map >> MethodList> maintenance to some internal utility class? That would > >> probably simplify the loops in privateGetPublicMethods? > > > > I thought MethodList.add()/consolidateWith() were close to those utility > > methods. I could extract the logic in each of 3 loops to 3 void methods > > taking 'methods' Map and a Method instance, but I don't want to pollute > > the method namespace in j.l.Class any more than necessary and making a > > special inner class for that is an overkill. Previously the holder for > > such methods was MethodArray, but it's gone now. I could subclass > > LinkedHashMap if I wanted to avoid an unnecessary indirection, but > > that's not a good practice. It's not that bad as it is - 38 lines of > > code for 3 loops with comments and spacing. I could improve comments > > though... > > Yes. I had to read the entire thing a couple of times to understand how > this works. Containing most of the logic into MethodList seems like a > way to improve this. Not sure though. > > > Thanks, > -Aleksey. > > > From martinrb at google.com Mon Oct 27 19:15:24 2014 From: martinrb at google.com (Martin Buchholz) Date: Mon, 27 Oct 2014 12:15:24 -0700 Subject: RFR: 8062194: java.util.jar.Attributes should use insertion-ordered iteration In-Reply-To: <544E96AC.90904@oracle.com> References: <544E96AC.90904@oracle.com> Message-ID: [+core-libs-dev oops I forgot to cc: the first time...] On Mon, Oct 27, 2014 at 12:02 PM, Xueming Shen wrote: > On 10/27/2014 11:33 AM, Martin Buchholz wrote: > >> Hello Xueming, Alan, >> >> I'd like you to do a code review. >> >> http://cr.openjdk.java.net/~martin/webrevs/openjdk9/ >> Attributes-iteration-order/ > 7Emartin/webrevs/openjdk9/Attributes-iteration-order/> >> https://bugs.openjdk.java.net/browse/JDK-8062194 >> > > The change looks fine. But guess we might have to go through the CCC for > this one, > given the nature of its "incompatibility"? > > Yes - technically, this is a small incompatibility. (But Attribute iteration order has changed many times) > Btw, is there any "noticeable" performance concern of switching from > hashmap to linkedhashmap? > Guess, we might have use scenario that lots of attributes is being access > when lots of jar get > opened the same time... > LinkedHashMap uses a "little more" cpu and memory. The cost is small enough that some people have suggested simply replacing HashMap's implementation with that of LinkedHashMap, and that is not totally crazy, but we're not going that far. Attributes are unlikely to contain many elements or to be long-lived. From huizhe.wang at oracle.com Mon Oct 27 19:27:06 2014 From: huizhe.wang at oracle.com (huizhe wang) Date: Mon, 27 Oct 2014 12:27:06 -0700 Subject: RFR 8062198: Add RowSetMetaDataImpl Tests and add column range validation to isdefinitlyWritable In-Reply-To: <3C972A10-3F79-462A-8FFB-0324BD0E5DCA@oracle.com> References: <3C972A10-3F79-462A-8FFB-0324BD0E5DCA@oracle.com> Message-ID: <544E9C8A.1080607@oracle.com> Hi Lance, Does test37 needs to loop through all of the columns? There doesn't seem to be a differentiator or different factor between the columns, e.g if one column is set to auto_increment and another not, the results would be different. Also in the test, some of the setters seem to be invalid, for example, whether the column is auto_increment or not shall affect setters such as setPrecision, setScale, setNullable, isReadOnly, isWritable and etc., shouldn't it? -Joe On 10/27/2014 11:06 AM, Lance Andersen wrote: > Hi all, > > Need a reviewer for the RowSetMetaDataImpl tests which also includes a fix to isDefinitelyWritable so that it validates the column index ranges > > Included are some minor housekeeping changes to remove redundant classes > > The webrev can be found at http://cr.openjdk.java.net/~lancea/8062198/webrev.00/ > > Best > Lance > > > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 > Oracle Java Engineering > 1 Network Drive > Burlington, MA 01803 > Lance.Andersen at oracle.com > > > From lance.andersen at oracle.com Mon Oct 27 19:37:51 2014 From: lance.andersen at oracle.com (Lance Andersen) Date: Mon, 27 Oct 2014 15:37:51 -0400 Subject: RFR 8062198: Add RowSetMetaDataImpl Tests and add column range validation to isdefinitlyWritable In-Reply-To: <544E9C8A.1080607@oracle.com> References: <3C972A10-3F79-462A-8FFB-0324BD0E5DCA@oracle.com> <544E9C8A.1080607@oracle.com> Message-ID: Hi Joe, Thank you for taking time to help review. On Oct 27, 2014, at 3:27 PM, huizhe wang wrote: > Hi Lance, > > Does test37 needs to loop through all of the columns? Wanted a test which made sure that for the number of columns in the metadata that the fields can be set. Does it have to, not really, but it wanted to sanity check that they could > There doesn't seem to be a differentiator or different factor between the columns, e.g if one column is set to auto_increment and another not, the results would be different. Also in the test, some of the setters seem to be invalid, for example, whether the column is auto_increment or not shall affect setters such as setPrecision, setScale, setNullable, isReadOnly, isWritable and etc., shouldn't it? For this abstract class it is just a matter of validating the methods can be set for the various columns. in an implementation of a RowSet, the data associated with a given column will have more actual meaning based on the column definition. So yes the values being set are somewhat artificial but that is OK in this instance. Also different databases for example can allow an auto-incrementable column to be writable, others do not so your milage varies as to which fields can and cannot have coresponding values. Best, Lance > > -Joe > > On 10/27/2014 11:06 AM, Lance Andersen wrote: >> Hi all, >> >> Need a reviewer for the RowSetMetaDataImpl tests which also includes a fix to isDefinitelyWritable so that it validates the column index ranges >> >> Included are some minor housekeeping changes to remove redundant classes >> >> The webrev can be found at http://cr.openjdk.java.net/~lancea/8062198/webrev.00/ >> >> Best >> Lance >> >> >> Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 >> Oracle Java Engineering >> 1 Network Drive >> Burlington, MA 01803 >> Lance.Andersen at oracle.com >> >> >> > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From aleksey.shipilev at oracle.com Mon Oct 27 19:45:35 2014 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Mon, 27 Oct 2014 22:45:35 +0300 Subject: Loading classes with many methods is very expensive In-Reply-To: References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <544E2B41.3080604@oracle.com> <544E3E7B.9020305@gmail.com> <544E6930.8050103@oracle.com> Message-ID: <544EA0DF.2040704@oracle.com> On 27.10.2014 22:01, Martin Buchholz wrote: > I'm having trouble keeping up with this thread I started, but I did > update the test/benchmark > http://cr.openjdk.java.net/~martin/webrevs/openjdk9/Class.getMethods-benchmark/ > > > I added a test *LoadAllClassesAndMethods *that does what its name says. > Although originally written as just a benchmark, In our recent Nashorn classloading work, we did this benchmark: http://cr.openjdk.java.net/~shade/8053904/ClassLoaderBenchmark.java ...which, I think can be easily exploded to call getMethods() as well. > Jeremy is independently working on yet another performance problem > exposed by *LoadAllClassesAndMethods* Does Jeremy have a reportable outline? Submit the bug to make this thread short :) Thanks, -Aleksey. From huizhe.wang at oracle.com Mon Oct 27 20:10:07 2014 From: huizhe.wang at oracle.com (huizhe wang) Date: Mon, 27 Oct 2014 13:10:07 -0700 Subject: RFR 8062198: Add RowSetMetaDataImpl Tests and add column range validation to isdefinitlyWritable In-Reply-To: References: <3C972A10-3F79-462A-8FFB-0324BD0E5DCA@oracle.com> <544E9C8A.1080607@oracle.com> Message-ID: <544EA69E.2090106@oracle.com> Hi Lance, Thanks for the explanation, so I learned a bit about these APIs :-) I had thought RowSetMetaDataImpl is The implementation of a RowSet. The changes look good to me. -Joe On 10/27/2014 12:37 PM, Lance Andersen wrote: > Hi Joe, > > Thank you for taking time to help review. > On Oct 27, 2014, at 3:27 PM, huizhe wang > wrote: > >> Hi Lance, >> >> Does test37 needs to loop through all of the columns? > > Wanted a test which made sure that for the number of columns in the > metadata that the fields can be set. Does it have to, not really, but > it wanted to sanity check that they could >> There doesn't seem to be a differentiator or different factor between >> the columns, e.g if one column is set to auto_increment and another >> not, the results would be different. Also in the test, some of the >> setters seem to be invalid, for example, whether the column is >> auto_increment or not shall affect setters such as setPrecision, >> setScale, setNullable, isReadOnly, isWritable and etc., shouldn't it? > > For this abstract class it is just a matter of validating the methods > can be set for the various columns. > > in an implementation of a RowSet, the data associated with a given > column will have more actual meaning based on the column definition. > So yes the values being set are somewhat artificial but that is OK > in this instance. > > Also different databases for example can allow an auto-incrementable > column to be writable, others do not so your milage varies as to which > fields can and cannot have coresponding values. > > Best, > Lance >> >> -Joe >> >> On 10/27/2014 11:06 AM, Lance Andersen wrote: >>> Hi all, >>> >>> Need a reviewer for the RowSetMetaDataImpl tests which also >>> includes a fix to isDefinitelyWritable so that it validates the >>> column index ranges >>> >>> Included are some minor housekeeping changes to remove redundant classes >>> >>> The webrev can be found at >>> http://cr.openjdk.java.net/~lancea/8062198/webrev.00/ >>> >>> >>> Best >>> Lance >>> >>> >>> Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 >>> Oracle Java Engineering >>> 1 Network Drive >>> Burlington, MA 01803 >>> Lance.Andersen at oracle.com >>> >>> >>> >> > > > > Lance > Andersen| Principal Member of Technical Staff | +1.781.442.2037 > Oracle Java Engineering > 1 Network Drive > Burlington, MA 01803 > Lance.Andersen at oracle.com > > > From ioi.lam at oracle.com Mon Oct 27 22:32:26 2014 From: ioi.lam at oracle.com (Ioi Lam) Date: Mon, 27 Oct 2014 15:32:26 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <544D8371.3000606@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> Message-ID: <544EC7FA.8070902@oracle.com> Hi David, I have update the latest webrev at: http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ and fixed the "int cache[]" style you mentioned. This version also contains the JDK test case that Mandy requested: http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html Thanks - Ioi On 10/26/14, 4:27 PM, David Holmes wrote: > Style nit: all the > > int cache[] > > should be > > int[] cache > > Also not clear if 8061651-lookup-index-open-v2 is latest webrev ?? > > Thanks, > David > > On 25/10/2014 9:38 AM, Ioi Lam wrote: >> Hi Mandy, >> >> Thanks for the review. please see comments in-line >> >> On 10/24/14, 2:33 PM, Mandy Chung wrote: >>> >>> On 10/23/2014 9:34 PM, Ioi Lam wrote: >>>> Hi Mandy, >>>> >>>> Thanks for the review. I have updated the patch: >>>> >>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v2/ >>>> >>>> >>> Thanks for removing the LoaderType enum. Two questions - >>> do you need the new hasLookupCacheLoader variable? Should >>> lookupCAcheURLs be always be non-null if it has the lookup >>> cache? >> I removed hasLookupCacheLoader and changed the condition check to >> (lookupCacheURLs != null) >>> >>> Most methods referencinglookupCacheURLs and lookupCacheLoader >>> are synchronized except initLookupCache and knowToNotExist. >>> Should they? Or volatile? >>> >> I changed both to synchronized. >>>> On 10/21/14, 12:56 PM, Mandy Chung wrote: >>>> >>>>> line 398: what happens if loaders.size() > maxindex? Shouldn't >>>>> it return null? >>>> In this case, all the loaders that's needed by the cache[] have been >>>> opened. So we should return cache[]. >>> >>> I forget about that, sorry. I'm thinking how to make it more >>> obvious to those who doesn't know much of the details. Every time I >>> read this and I need to reload what I know about and miss something. >>> >>>> I changed the code to this. What do you think? >>> >>> It seems to me that it would help if you refactor and add a method >>> "ensureLoadersInited" that will make it clear what it attempts to do. >>> The side effect invalidating the cache can be checked after it's >>> called and no need to worry about lookupCacheEnabled must be checked >>> in any order. Something like this >>> if (cache != null && cache.length > 0) { >>> int maxindex = cache[cache.length - 1]; >>> ensureLoaderOpened(maxindex); >>> if (loaders.get(maxindex) == null || !lookupCacheEnabled) { >>> if (DEBUG_LOOKUP_CACHE) { >>> System.out.println("Expanded loaders FAILED " + >>> loaders.size() + " for maxindex=" + >>> maxindex); >>> } >>> return null; >>> } >>> ... >>> } >>> return cache; >> I changed the code to >> >> private synchronized int[] getLookupCache(String name) { >> if (lookupCacheURLs == null || !lookupCacheEnabled) { >> return null; >> } >> >> int cache[] = getLookupCacheForClassLoader(lookupCacheLoader, >> name); >> if (cache != null && cache.length > 0) { >> int maxindex = cache[cache.length - 1]; // cache[] is >> strictly ascending. >> if (!ensureLoaderOpened(maxindex)) { >> if (DEBUG_LOOKUP_CACHE) { >> System.out.println("Expanded loaders FAILED " + >> loaders.size() + " for >> maxindex=" + maxindex); >> } >> return null; >> } >> } >> >> return cache; >> } >> >> private boolean ensureLoaderOpened(int index) { >> if (loaders.size() <= index) { >> // Open all Loaders up to, and including, index >> if (getLoader(index) == null) { >> return false; >> } >> if (!lookupCacheEnabled) { >> // cache was invalidated as the result of the above >> call. >> return false; >> } >> if (DEBUG_LOOKUP_CACHE) { >> System.out.println("Expanded loaders " + >> loaders.size() + >> " to index=" + index); >> } >> } >> return true; >> } >> >>> The code is getting further complicated with this lookup cache and >>> bear with me for being picky. >>> >>>> if (loaders.size() <= maxindex) { >>>> boolean failed = false; >>>> >>>> // Call getNextLoader() with a null cache to open all >>>> // Loaders up to, and including, maxindex. >>>> if (getNextLoader(null, maxindex) == null) { >>> >>> Can this call getLoader(maxindex)? They are essentially the same. >>> I think getLoader(maxindex) makes it explicit that it forces to >>> open the loader. >> Changed. >> >>> Mandy >> From jeremymanson at google.com Mon Oct 27 23:37:37 2014 From: jeremymanson at google.com (Jeremy Manson) Date: Mon, 27 Oct 2014 16:37:37 -0700 Subject: Loading classes with many methods is very expensive In-Reply-To: <544EA0DF.2040704@oracle.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <544E2B41.3080604@oracle.com> <544E3E7B.9020305@gmail.com> <544E6930.8050103@oracle.com> <544EA0DF.2040704@oracle.com> Message-ID: Jeremy has already filed a bug (8062116), and is just finishing up the patch (I jumped the gun a bit by attaching it to the bug - it has a few bugs in it). I'll probably have something in reasonable shape to review tomorrow (I've submitted it internally, and I want to let it spend a day or so having our test infrastructure throw things at it). It's actually a JVMTI performance regression. The data structure that is being used to store jmethodids isn't great. I've refactored it a bit to improve its performance, but it should really be a closed hash table. There isn't a handy one in HS, so I just made it O(1) for writes. It's still O(n) for reads, though, which is nasty. We can have the real conversation when I post the RFR, though. Jeremy On Mon, Oct 27, 2014 at 12:45 PM, Aleksey Shipilev < aleksey.shipilev at oracle.com> wrote: > On 27.10.2014 22:01, Martin Buchholz wrote: > > I'm having trouble keeping up with this thread I started, but I did > > update the test/benchmark > > > http://cr.openjdk.java.net/~martin/webrevs/openjdk9/Class.getMethods-benchmark/ > > < > http://cr.openjdk.java.net/%7Emartin/webrevs/openjdk9/Class.getMethods-benchmark/ > > > > > > I added a test *LoadAllClassesAndMethods *that does what its name says. > > Although originally written as just a benchmark, > > In our recent Nashorn classloading work, we did this benchmark: > http://cr.openjdk.java.net/~shade/8053904/ClassLoaderBenchmark.java > > ...which, I think can be easily exploded to call getMethods() as well. > > > > Jeremy is independently working on yet another performance problem > > exposed by *LoadAllClassesAndMethods* > > Does Jeremy have a reportable outline? Submit the bug to make this > thread short :) > > > Thanks, > -Aleksey. > > > From jeremymanson at google.com Tue Oct 28 00:43:30 2014 From: jeremymanson at google.com (Jeremy Manson) Date: Mon, 27 Oct 2014 17:43:30 -0700 Subject: Loading classes with many methods is very expensive In-Reply-To: References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <544E2B41.3080604@oracle.com> <544E3E7B.9020305@gmail.com> <544E6930.8050103@oracle.com> <544EA0DF.2040704@oracle.com> Message-ID: Just want to reiterate: that patch has a few bugs in it. Don't review it yet. I'll probably follow up tomorrow. Jeremy On Mon, Oct 27, 2014 at 4:37 PM, Jeremy Manson wrote: > Jeremy has already filed a bug (8062116), and is just finishing up the > patch (I jumped the gun a bit by attaching it to the bug - it has a few > bugs in it). I'll probably have something in reasonable shape to review > tomorrow (I've submitted it internally, and I want to let it spend a day or > so having our test infrastructure throw things at it). > > It's actually a JVMTI performance regression. The data structure that is > being used to store jmethodids isn't great. I've refactored it a bit to > improve its performance, but it should really be a closed hash table. > There isn't a handy one in HS, so I just made it O(1) for writes. It's > still O(n) for reads, though, which is nasty. > > We can have the real conversation when I post the RFR, though. > > Jeremy > > On Mon, Oct 27, 2014 at 12:45 PM, Aleksey Shipilev < > aleksey.shipilev at oracle.com> wrote: > >> On 27.10.2014 22:01, Martin Buchholz wrote: >> > I'm having trouble keeping up with this thread I started, but I did >> > update the test/benchmark >> > >> http://cr.openjdk.java.net/~martin/webrevs/openjdk9/Class.getMethods-benchmark/ >> > < >> http://cr.openjdk.java.net/%7Emartin/webrevs/openjdk9/Class.getMethods-benchmark/ >> > >> > >> > I added a test *LoadAllClassesAndMethods *that does what its name says. >> > Although originally written as just a benchmark, >> >> In our recent Nashorn classloading work, we did this benchmark: >> http://cr.openjdk.java.net/~shade/8053904/ClassLoaderBenchmark.java >> >> ...which, I think can be easily exploded to call getMethods() as well. >> >> >> > Jeremy is independently working on yet another performance problem >> > exposed by *LoadAllClassesAndMethods* >> >> Does Jeremy have a reportable outline? Submit the bug to make this >> thread short :) >> >> >> Thanks, >> -Aleksey. >> >> >> > From stuart.marks at oracle.com Tue Oct 28 00:52:02 2014 From: stuart.marks at oracle.com (Stuart Marks) Date: Mon, 27 Oct 2014 17:52:02 -0700 Subject: RFR (xs) 8062233: add java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java Message-ID: <544EE8B2.6060201@oracle.com> Hi all, Quick addition to the problem list. This test has been failing intermittently for a while, but for some reason it seems to be failing a bit more often recently. Please review the patch below. Thanks, s'marks # HG changeset patch # User smarks # Date 1414457168 25200 # Mon Oct 27 17:46:08 2014 -0700 # Node ID ac55626c516fbc4bdf218d22837fc9a74cd2f0b2 # Parent 67a92afb97bc7110edaf49a03c1cc51e04463bd4 8062233: add java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java to problem list Reviewed-by: XXX diff -r 67a92afb97bc -r ac55626c516f test/ProblemList.txt --- a/test/ProblemList.txt Mon Oct 27 13:45:39 2014 -0700 +++ b/test/ProblemList.txt Mon Oct 27 17:46:08 2014 -0700 @@ -200,6 +200,9 @@ # jdk_rmi +# 7140992 +java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java generic-all + # 7146541 java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java linux-all From joe.darcy at oracle.com Tue Oct 28 01:10:45 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Mon, 27 Oct 2014 18:10:45 -0700 Subject: RFR (xs) 8062233: add java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java In-Reply-To: <544EE8B2.6060201@oracle.com> References: <544EE8B2.6060201@oracle.com> Message-ID: <544EED15.7070100@oracle.com> Thumbs up; cheers, -Joe On 10/27/2014 5:52 PM, Stuart Marks wrote: > Hi all, > > Quick addition to the problem list. This test has been failing > intermittently for a while, but for some reason it seems to be failing > a bit more often recently. Please review the patch below. > > Thanks, > > s'marks > > > > # HG changeset patch > # User smarks > # Date 1414457168 25200 > # Mon Oct 27 17:46:08 2014 -0700 > # Node ID ac55626c516fbc4bdf218d22837fc9a74cd2f0b2 > # Parent 67a92afb97bc7110edaf49a03c1cc51e04463bd4 > 8062233: add > java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java to > problem list > Reviewed-by: XXX > > diff -r 67a92afb97bc -r ac55626c516f test/ProblemList.txt > --- a/test/ProblemList.txt Mon Oct 27 13:45:39 2014 -0700 > +++ b/test/ProblemList.txt Mon Oct 27 17:46:08 2014 -0700 > @@ -200,6 +200,9 @@ > > # jdk_rmi > > +# 7140992 > +java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java > generic-all > + > # 7146541 > java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java > linux-all > From mandy.chung at oracle.com Tue Oct 28 02:04:19 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Mon, 27 Oct 2014 19:04:19 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <544EC7FA.8070902@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> Message-ID: <544EF9A3.8090109@oracle.com> On 10/27/2014 3:32 PM, Ioi Lam wrote: > Hi David, I have update the latest webrev at: > > http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ > The update looks good. Thanks. > This version also contains the JDK test case that Mandy requested: > > http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html > > What I request to add is a test setting the system property (-Dsun.cds.enableSharedLookupCache=true) and continue to load class A and B. Removing line 44-58 should do it and also no need to set -Dfoo.foo.bar. It'd be good if you run this test and turn on the debug traces to make sure that the application class loader and ext class loader will start up with the lookup cache enabled and make up call to the VM. As it doesn't have the app cds archive, it will invalidate the cache right away and continue the class lookup with null cache array. Mandy From jiangli.zhou at oracle.com Tue Oct 28 02:52:53 2014 From: jiangli.zhou at oracle.com (Jiangli Zhou) Date: Mon, 27 Oct 2014 19:52:53 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <544EC7FA.8070902@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> Message-ID: <544F0505.4050206@oracle.com> Hi Ioi, I have a question for following code in AppClassLoader.loadClass(). If a class is 'known to not exist' for the AppClassLoader (not in the AppClassLoader and parent classloaders' shared lookup cache), it seems findLoadedClass() would only find classes that's dynamically loaded by the parent loaders. The AppClassLoader would never try to load the class. Is the AppClassLoader's lookup cache guaranteed to have all the classes in it's path? 315 if (ucp.knownToNotExist(name)) { 316 // The class of the given name is not found in the parent 317 // class loader as well as its local URLClassPath. 318 // Check if this class has already been defined dynamically; 319 // if so, return the loaded class; otherwise, skip the parent 320 // delegation and findClass. 321 synchronized (getClassLoadingLock(name)) { 322 Class c = findLoadedClass(name); 323 if (c != null) { 324 return c; 325 } 326 } 327 throw new ClassNotFoundException(name); 328 } Thanks, Jiangli On 10/27/2014 3:32 PM, Ioi Lam wrote: > Hi David, I have update the latest webrev at: > > http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ > > and fixed the "int cache[]" style you mentioned. > > This version also contains the JDK test case that Mandy requested: > > http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html > > > Thanks > - Ioi > From john.r.rose at oracle.com Tue Oct 28 03:46:08 2014 From: john.r.rose at oracle.com (John Rose) Date: Mon, 27 Oct 2014 20:46:08 -0700 Subject: [9] [8u40] RFR (M): 8059877: GWT branch frequencies pollution due to LF sharing In-Reply-To: <543E90E0.6080200@oracle.com> References: <54382E90.7040105@oracle.com> <03B32851-A9DB-4C43-ABB3-2CFE36D7CB0C@oracle.com> <543D717C.3090508@oracle.com> <0F6750AB-3949-4E5A-B67B-1FA1A10E5CA2@oracle.com> <543E90E0.6080200@oracle.com> Message-ID: <95EF0781-6DCB-4294-912A-25C61912F8B9@oracle.com> On Oct 15, 2014, at 8:21 AM, Vladimir Ivanov wrote: >>> Updated version: >>> http://cr.openjdk.java.net/~vlivanov/8059877/webrev.01/ The algorithm looks fine, as long as the count is small. (Otherwise we might want to spend effort recompiling the DontInline LF. Call it CountingWrapper, since that's what it does. (Count down vs. count up doesn't matter much.) Then you can call the states "counting" and "not counting". The pre-action is present only in the counting state. The aspect of inlining or blocking is then focused down to a detail of the LF flavor. You call DelegatingMethodHandle.makeReinvokerForm in three places, two of which are identical calls. I suggest refactoring so as to call it in two places. (Nit: As a matter of style, the default value of a boolean flag should be usual one, in typical cases. By that reasoning, LF.forceInline should be LF.dontInline; the objection to this is that it is anti-style to have a negative word in a boolean name.) You could create and cache *both* reinvoker forms when the MH wrapper is created, so that the non-counting, inline-enabled LF is created more eagerly during warmup. It might make for a smoother warmup. (Maybe. Maybe not.) Thanks! ? John From ioi.lam at oracle.com Tue Oct 28 04:38:34 2014 From: ioi.lam at oracle.com (Ioi Lam) Date: Mon, 27 Oct 2014 21:38:34 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <544EF9A3.8090109@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544EF9A3.8090109@oracle.com> Message-ID: <544F1DCA.9040304@oracle.com> On 10/27/14, 7:04 PM, Mandy Chung wrote: > > On 10/27/2014 3:32 PM, Ioi Lam wrote: >> Hi David, I have update the latest webrev at: >> >> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ >> > > The update looks good. Thanks. > >> This version also contains the JDK test case that Mandy requested: >> >> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html >> >> > > What I request to add is a test setting the system property > (-Dsun.cds.enableSharedLookupCache=true) and continue to load class A > and B. Removing line 44-58 should do it and also no need to set > -Dfoo.foo.bar. > Do you mean change the test to call System.setProperty("sun.cds.enableSharedLookupCache", "true")? But we know that the property is checked only once, before any app classes are loaded. So calling System.setProperty in an application class won't test anything. > It'd be good if you run this test and turn on the debug traces to make > sure that the application class loader and ext class loader will start > up with the lookup cache enabled and make up call to the VM. As it > doesn't have the app cds archive, it will invalidate the cache right > away and continue the class lookup with null cache array. In the latest code, if CDS is not available, lookupCacheEnabled will be set to false inside the static initializer of URLClassPath: private static volatile boolean lookupCacheEnabled = "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache")); later, when the boot/ext/app loaders call into here: synchronized void initLookupCache(ClassLoader loader) { if ((lookupCacheURLs = getLookupCacheURLs(loader)) != null) { lookupCacheLoader = loader; } else { // This JVM instance does not support lookup cache. disableAllLookupCaches(); } } their lookupCacheURLs[] fields will all be set to null. As a result, getLookupCacheForClassLoader and knownToNotExist0 will never be called. I can add a DEBUG_LOOKUP_CACHE trace inside disableAllLookupCaches to print "lookup cache disabled", and check for that in the test. Is this OK? Thanks - Ioi From mandy.chung at oracle.com Tue Oct 28 04:52:46 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Mon, 27 Oct 2014 21:52:46 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <544F1DCA.9040304@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544EF9A3.8090109@oracle.com> <544F1DCA.9040304@oracle.com> Message-ID: <544F211E.5040801@oracle.com> On 10/27/2014 9:38 PM, Ioi Lam wrote: > >> What I request to add is a test setting the system property >> (-Dsun.cds.enableSharedLookupCache=true) and continue to load class A >> and B. Removing line 44-58 should do it and also no need to set >> -Dfoo.foo.bar. >> > Do you mean change the test to call > System.setProperty("sun.cds.enableSharedLookupCache", "true")? > > But we know that the property is checked only once, before any app > classes are loaded. So calling System.setProperty in an application > class won't test anything. No, set it in the command-line (i.e. @run) is fine. Removing line 44-58 should do it. >> It'd be good if you run this test and turn on the debug traces to >> make sure that the application class loader and ext class loader will >> start up with the lookup cache enabled and make up call to the VM. >> As it doesn't have the app cds archive, it will invalidate the cache >> right away and continue the class lookup with null cache array. > In the latest code, if CDS is not available, lookupCacheEnabled will > be set to false inside the static initializer of URLClassPath: > > private static volatile boolean lookupCacheEnabled > = > "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache")); > > later, when the boot/ext/app loaders call into here: > > synchronized void initLookupCache(ClassLoader loader) { > if ((lookupCacheURLs = getLookupCacheURLs(loader)) != null) { > lookupCacheLoader = loader; > } else { > // This JVM instance does not support lookup cache. > disableAllLookupCaches(); > } > } > > their lookupCacheURLs[] fields will all be set to null. As a result, > getLookupCacheForClassLoader and knownToNotExist0 will never be called. > It will call getLookupCacheURLs. It's just a sanity test and it's fine to call one but not all three. > I can add a DEBUG_LOOKUP_CACHE trace inside disableAllLookupCaches to > print "lookup cache disabled", and check for that in the test. Is this > OK? As long as A.test and B.test are invoked and finishes, it should be adequate. Mandy From ioi.lam at oracle.com Tue Oct 28 04:57:55 2014 From: ioi.lam at oracle.com (Ioi Lam) Date: Mon, 27 Oct 2014 21:57:55 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <544F0505.4050206@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544F0505.4050206@oracle.com> Message-ID: <544F2253.5000401@oracle.com> On 10/27/14, 7:52 PM, Jiangli Zhou wrote: > Hi Ioi, > > I have a question for following code in AppClassLoader.loadClass(). If > a class is 'known to not exist' for the AppClassLoader (not in the > AppClassLoader and parent classloaders' shared lookup cache), it seems > findLoadedClass() would only find classes that's dynamically loaded by > the parent loaders. The AppClassLoader would never try to load the > class. Is the AppClassLoader's lookup cache guaranteed to have all the > classes in it's path? > > 315 if (ucp.knownToNotExist(name)) { > 316 // The class of the given name is not found in > the parent > 317 // class loader as well as its local URLClassPath. > 318 // Check if this class has already been defined > dynamically; > 319 // if so, return the loaded class; otherwise, > skip the parent > 320 // delegation and findClass. > 321 synchronized (getClassLoadingLock(name)) { > 322 Class c = findLoadedClass(name); > 323 if (c != null) { > 324 return c; > 325 } > 326 } > 327 throw new ClassNotFoundException(name); > 328 } The reason is to make the behavior consistent with java.lang.ClassLoader.loadClass(): protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class c = findLoadedClass(name); .... If is not in any of the JAR files but was dynamically defined (using ClassLoader.defineClass, etc), then AppClassLoader.loadClass() should return the class without throwing ClassNotFoundException. Thanks - Ioi > Thanks, > Jiangli > > On 10/27/2014 3:32 PM, Ioi Lam wrote: >> Hi David, I have update the latest webrev at: >> >> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ >> >> and fixed the "int cache[]" style you mentioned. >> >> This version also contains the JDK test case that Mandy requested: >> >> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html >> >> >> Thanks >> - Ioi >> From ioi.lam at oracle.com Tue Oct 28 05:03:11 2014 From: ioi.lam at oracle.com (Ioi Lam) Date: Mon, 27 Oct 2014 22:03:11 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <544F211E.5040801@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544EF9A3.8090109@oracle.com> <544F1DCA.9040304@oracle.com> <544F211E.5040801@oracle.com> Message-ID: <544F238F.2010703@oracle.com> On 10/27/14, 9:52 PM, Mandy Chung wrote: > > On 10/27/2014 9:38 PM, Ioi Lam wrote: >> >>> What I request to add is a test setting the system property >>> (-Dsun.cds.enableSharedLookupCache=true) and continue to load class >>> A and B. Removing line 44-58 should do it and also no need to set >>> -Dfoo.foo.bar. >>> >> Do you mean change the test to call >> System.setProperty("sun.cds.enableSharedLookupCache", "true")? >> >> But we know that the property is checked only once, before any app >> classes are loaded. So calling System.setProperty in an application >> class won't test anything. > > No, set it in the command-line (i.e. @run) is fine. > > Removing line 44-58 should do it. > I will remove the check from line 44 - 48. I want to keep the -Dfoo.foo.bar=xyz and the corresponding check to make sure that the JTREG framework is working as intended. Otherwise JTREG could have skipped the -Dsun.cds.enableSharedLookupCache=true and the test will still report "PASS" even though the intended action was not performed. >>> It'd be good if you run this test and turn on the debug traces to >>> make sure that the application class loader and ext class loader >>> will start up with the lookup cache enabled and make up call to the >>> VM. As it doesn't have the app cds archive, it will invalidate the >>> cache right away and continue the class lookup with null cache array. >> In the latest code, if CDS is not available, lookupCacheEnabled will >> be set to false inside the static initializer of URLClassPath: >> >> private static volatile boolean lookupCacheEnabled >> = >> "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache")); >> >> later, when the boot/ext/app loaders call into here: >> >> synchronized void initLookupCache(ClassLoader loader) { >> if ((lookupCacheURLs = getLookupCacheURLs(loader)) != null) { >> lookupCacheLoader = loader; >> } else { >> // This JVM instance does not support lookup cache. >> disableAllLookupCaches(); >> } >> } >> >> their lookupCacheURLs[] fields will all be set to null. As a result, >> getLookupCacheForClassLoader and knownToNotExist0 will never be called. >> > > It will call getLookupCacheURLs. It's just a sanity test and it's > fine to call one but not all three. > >> I can add a DEBUG_LOOKUP_CACHE trace inside disableAllLookupCaches to >> print "lookup cache disabled", and check for that in the test. Is >> this OK? > > As long as A.test and B.test are invoked and finishes, it should be > adequate. > > Mandy From mandy.chung at oracle.com Tue Oct 28 05:24:01 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Mon, 27 Oct 2014 22:24:01 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <544F238F.2010703@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544EF9A3.8090109@oracle.com> <544F1DCA.9040304@oracle.com> <544F211E.5040801@oracle.com> <544F238F.2010703@oracle.com> Message-ID: <544F2871.6090208@oracle.com> On 10/27/2014 10:03 PM, Ioi Lam wrote: > I will remove the check from line 44 - 48. > > I want to keep the -Dfoo.foo.bar=xyz and the corresponding check to > make sure that the JTREG framework is working as intended. Otherwise > JTREG could have skipped the -Dsun.cds.enableSharedLookupCache=true > and the test will still report "PASS" even though the intended action > was not performed. Now I see what the test is trying to verify: sun.cds.enableSharedLookupCache should be removed from the system properties as it's only an interface with the library. There is no harm in having the test as is while I would say -Dfoo.foo.bar=xyz is not really needed; otherwise other tests may fail if jtreg does something wrong. Approved what you have in v3. thanks Mandy From aleksej.efimov at oracle.com Tue Oct 28 11:57:05 2014 From: aleksej.efimov at oracle.com (Aleksej Efimov) Date: Tue, 28 Oct 2014 14:57:05 +0300 Subject: RFR: 8059206: (tz) Support tzdata2014i Message-ID: <544F8491.2090304@oracle.com> Hi, Can I ask for review of new tzdata - 2014i integration fix to JDK9. One change in this release is that new time zone was added - "Pacific/Bougainville". The localized names still needs to be translated - the appropriate comment was added to JDK-8057004. Testing results: JPRT tests: jdk_other jdk_util jdk_text jdk_time - no failures JTREG tests: test/sun/util/calendar test/java/util/Calendar test/sun/util/resources/TimeZone test/sun/util/calendar test/java/util/TimeZone test/java/time test/java/util/Formatter test/closed/java/util/Calendar test/closed/java/util/TimeZone test/closed/java/text/Format/DateFormat - no failures Thank you, Aleksej [1] Bug: https://bugs.openjdk.java.net/browse/JDK-8059206 [2] Webrev: http://cr.openjdk.java.net/~aefimov/8059206/9/webrev.00 From joel.franck at oracle.com Tue Oct 28 12:59:43 2014 From: joel.franck at oracle.com (=?iso-8859-1?Q?Joel_Borggr=E9n-Franck?=) Date: Tue, 28 Oct 2014 13:59:43 +0100 Subject: Request for review/advice from langtools team Re: Covariant overrides on the Buffer Hierarchy redux In-Reply-To: References: <3D27B84B-20F1-486C-954F-E908DD443DA9@oracle.com> <35FE2B2C-7BA2-4A11-AE9D-B5E12C7B5729@oracle.com> Message-ID: Hi Paul, Sorry for the delay. So if I understand this correctly, we get 4 warnings (and because of -Werror a build failure) in langtools when compiling vs Jdk 9, but need the casts because we bootstrap with Jdk 8. Looks good to me but I would prefer if you filed a bug on me for Jdk 10 for removing the SuppressWarnings and added comments pointing to the bug after the @SuppressWarnings annotations. That way I will remember to clean this up when we bootstrap with Jdk 9. cheers /Joel On 27 okt 2014, at 10:12, Paul Sandoz wrote: > Hi, > > Can someone from langtools kindly chime in with how to move this forward? > > https://bugs.openjdk.java.net/browse/JDK-4774077 > > http://cr.openjdk.java.net/~rwarburton/buffer-overrides-3/ > > http://cr.openjdk.java.net/~rwarburton/buffer-overrides-langtools-0/langtools.patch > > > On Oct 17, 2014, at 11:37 AM, Paul Sandoz wrote: > >> Hi, >> >> [Including compiler-dev, i am not on that list so please CC me if replying to just that list] >> >> > ... > > >> So Richard has a patch for that too: >> >> http://cr.openjdk.java.net/~rwarburton/buffer-overrides-langtools-0/langtools.patch >> >> This is required because in the bootstrap compilation phase a JDK without the co-variant overrides can be used. So the current solution is to suppress the warnings. Reviews from langtools gurus are very much appreciated. >> > > ? > > >> Ideally it would be nice to push all this under one issue, is that possible? If not i will have to create another issue and of course push to langtools before jdk. >> >> A internal CCC is also underway. >> > > This has be approved, with the comment that "@since 1.9" should be added to the doc of the new methods, which i have done in my copy of the patch. > > Thanks, > Paul. From masayoshi.okutsu at oracle.com Tue Oct 28 13:46:12 2014 From: masayoshi.okutsu at oracle.com (Masayoshi Okutsu) Date: Tue, 28 Oct 2014 22:46:12 +0900 Subject: RFR: 8059206: (tz) Support tzdata2014i In-Reply-To: <544F8491.2090304@oracle.com> References: <544F8491.2090304@oracle.com> Message-ID: <544F9E24.2080109@oracle.com> Hi Aleksej, src/java.base/share/classes/sun/util/resources/TimeZoneNames*.java: + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", + "Bougainville Summer Time", "BST", + "Bougainville Time", "BT"}}, I'd use "Daylight Time" instead of "Summer Time" because of the recent move from Summer to Daylight. No daylight saving time is observed in Bougainville, though. Otherwise, all the changes look good to me. Thanks, Masayoshi On 10/28/2014 8:57 PM, Aleksej Efimov wrote: > Hi, > > Can I ask for review of new tzdata - 2014i integration fix to JDK9. > One change in this release is that new time zone was added - > "Pacific/Bougainville". The localized names still needs to be > translated - the appropriate comment was added to JDK-8057004. > > Testing results: > JPRT tests: jdk_other jdk_util jdk_text jdk_time - no failures > JTREG tests: test/sun/util/calendar test/java/util/Calendar > test/sun/util/resources/TimeZone test/sun/util/calendar > test/java/util/TimeZone test/java/time test/java/util/Formatter > test/closed/java/util/Calendar test/closed/java/util/TimeZone > test/closed/java/text/Format/DateFormat - no failures > > Thank you, > Aleksej > > [1] Bug: https://bugs.openjdk.java.net/browse/JDK-8059206 > [2] Webrev: http://cr.openjdk.java.net/~aefimov/8059206/9/webrev.00 From aleksej.efimov at oracle.com Tue Oct 28 14:08:09 2014 From: aleksej.efimov at oracle.com (Aleksej Efimov) Date: Tue, 28 Oct 2014 17:08:09 +0300 Subject: RFR: 8059206: (tz) Support tzdata2014i In-Reply-To: <544F9E24.2080109@oracle.com> References: <544F8491.2090304@oracle.com> <544F9E24.2080109@oracle.com> Message-ID: <544FA349.4060003@oracle.com> Hi Masayoshi, Thank you for the review. Ok, I will change the "Summer Time" to "Daylight Time" before the push. Best Regards, Aleksej On 10/28/2014 04:46 PM, Masayoshi Okutsu wrote: > Hi Aleksej, > > src/java.base/share/classes/sun/util/resources/TimeZoneNames*.java: > + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", > + "Bougainville Summer Time", "BST", > + "Bougainville Time", "BT"}}, > > I'd use "Daylight Time" instead of "Summer Time" because of the recent > move from Summer to Daylight. No daylight saving time is observed in > Bougainville, though. > > Otherwise, all the changes look good to me. > > Thanks, > Masayoshi > > On 10/28/2014 8:57 PM, Aleksej Efimov wrote: >> Hi, >> >> Can I ask for review of new tzdata - 2014i integration fix to JDK9. >> One change in this release is that new time zone was added - >> "Pacific/Bougainville". The localized names still needs to be >> translated - the appropriate comment was added to JDK-8057004. >> >> Testing results: >> JPRT tests: jdk_other jdk_util jdk_text jdk_time - no failures >> JTREG tests: test/sun/util/calendar test/java/util/Calendar >> test/sun/util/resources/TimeZone test/sun/util/calendar >> test/java/util/TimeZone test/java/time test/java/util/Formatter >> test/closed/java/util/Calendar test/closed/java/util/TimeZone >> test/closed/java/text/Format/DateFormat - no failures >> >> Thank you, >> Aleksej >> >> [1] Bug: https://bugs.openjdk.java.net/browse/JDK-8059206 >> [2] Webrev: http://cr.openjdk.java.net/~aefimov/8059206/9/webrev.00 > From Alan.Bateman at oracle.com Tue Oct 28 14:52:21 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 28 Oct 2014 14:52:21 +0000 Subject: Lower overhead String encoding/decoding In-Reply-To: References: <54200F07.4070604@oracle.com> <542441BB.600@oracle.com> <5444BB17.8080708@oracle.com> Message-ID: <544FADA5.7000403@oracle.com> On 26/10/2014 21:10, Richard Warburton wrote: > : > > Thanks for taking the time to look at this - most appreciated. I've > pushed the latest iteration to > http://cr.openjdk.java.net/~rwarburton/string-patch-webrev-8/ > . > I think this is looking good. For the constructor then the words "decoding the specified byte buffer", it might be a bit clearer as "decoding the remaining bytes in the ...". For getBytes(ByteBuffer, Charset) then the position is advanced by the bytes written, no need to mention the number of chars read here. In the constructor then you make it clear that malformed/unmappable sequences use the default replacement. This is important to state in the getBytes methods too because the encoding can fail. -Alan. From forax at univ-mlv.fr Tue Oct 28 15:06:31 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 28 Oct 2014 16:06:31 +0100 Subject: Lower overhead String encoding/decoding In-Reply-To: <544FADA5.7000403@oracle.com> References: <54200F07.4070604@oracle.com> <542441BB.600@oracle.com> <5444BB17.8080708@oracle.com> <544FADA5.7000403@oracle.com> Message-ID: <544FB0F7.8080909@univ-mlv.fr> On 10/28/2014 03:52 PM, Alan Bateman wrote: > On 26/10/2014 21:10, Richard Warburton wrote: >> : >> >> Thanks for taking the time to look at this - most appreciated. I've >> pushed the latest iteration to >> http://cr.openjdk.java.net/~rwarburton/string-patch-webrev-8/ >> . >> > I think this is looking good. > > For the constructor then the words "decoding the specified byte > buffer", it might be a bit clearer as "decoding the remaining bytes in > the ...". > > For getBytes(ByteBuffer, Charset) then the position is advanced by the > bytes written, no need to mention the number of chars read here. > > In the constructor then you make it clear that malformed/unmappable > sequences use the default replacement. This is important to state in > the getBytes methods too because the encoding can fail. > > -Alan. > > Hi Richard, hi all, Two comments, You replace the nullcheck in getBytes() by a requireNonNull and at the same time, you don"t use requireNonNull in String(ByteBuffer,Charset), no very logical isn't it ? I think you need a supplementary constructor that takes a ByteBuffer and a charset name as a String, i may be wrong, but it seems that every constructor of String that takes a Charset has a dual constructor that takes a Charset as a String. As far as I remember, a constructor that takes a Charset as a String may be faster because you can share the character decoder instead of creating a new one. cheers, R?mi From lance.andersen at oracle.com Tue Oct 28 17:12:31 2014 From: lance.andersen at oracle.com (Lance Andersen) Date: Tue, 28 Oct 2014 13:12:31 -0400 Subject: RFR 8062288: Minor re-org of java/sql testing tests Message-ID: <0D30CFF8-A03A-4777-A2AE-8CA80D0721C1@oracle.com> Hi all, I need a reviewer for this change which moves the java/sql testng tests into its own directory making it consistent with the javax/sql testing tests I also kicked off a jtreg which just completed successfully Webrev is at http://cr.openjdk.java.net/~lancea/8062288/webrev.00/ Best Lance Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From huizhe.wang at oracle.com Tue Oct 28 17:23:18 2014 From: huizhe.wang at oracle.com (huizhe wang) Date: Tue, 28 Oct 2014 10:23:18 -0700 Subject: RFR 8062288: Minor re-org of java/sql testing tests In-Reply-To: <0D30CFF8-A03A-4777-A2AE-8CA80D0721C1@oracle.com> References: <0D30CFF8-A03A-4777-A2AE-8CA80D0721C1@oracle.com> Message-ID: <544FD106.6020708@oracle.com> Hi Lance, Looks good to me. Best, Joe On 10/28/2014 10:12 AM, Lance Andersen wrote: > Hi all, > > I need a reviewer for this change which moves the java/sql testng tests into its own directory making it consistent with the javax/sql testing tests > > I also kicked off a jtreg which just completed successfully > > Webrev is at http://cr.openjdk.java.net/~lancea/8062288/webrev.00/ > > Best > Lance > > > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 > Oracle Java Engineering > 1 Network Drive > Burlington, MA 01803 > Lance.Andersen at oracle.com > > > From roger.riggs at oracle.com Tue Oct 28 17:26:03 2014 From: roger.riggs at oracle.com (roger riggs) Date: Tue, 28 Oct 2014 13:26:03 -0400 Subject: RFR 8062288: Minor re-org of java/sql testing tests In-Reply-To: <0D30CFF8-A03A-4777-A2AE-8CA80D0721C1@oracle.com> References: <0D30CFF8-A03A-4777-A2AE-8CA80D0721C1@oracle.com> Message-ID: <544FD1AB.1010008@oracle.com> Hi Lance, Looks fine. Roger On 10/28/2014 1:12 PM, Lance Andersen wrote: > Hi all, > > I need a reviewer for this change which moves the java/sql testng tests into its own directory making it consistent with the javax/sql testing tests > > I also kicked off a jtreg which just completed successfully > > Webrev is at http://cr.openjdk.java.net/~lancea/8062288/webrev.00/ > > Best > Lance > > > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 > Oracle Java Engineering > 1 Network Drive > Burlington, MA 01803 > Lance.Andersen at oracle.com > > > From roger.riggs at oracle.com Tue Oct 28 17:44:08 2014 From: roger.riggs at oracle.com (roger riggs) Date: Tue, 28 Oct 2014 13:44:08 -0400 Subject: RFR 9: 8048124: Read hijra-config-umalqura.properties as a resource Message-ID: <544FD5E8.1040404@oracle.com> Hi, One change missing from the previous webrev is to copy the Hijrah calendar data to its location as a resource. It is in the top level repository, so it was not covered by the earlier webrev. Webrev: http://cr.openjdk.java.net/~rriggs/webrev-hijrah-config-8049376-top/ Issue: 8048124: Read hijra-config-umalqura.properties as a resource Thanks, Roger [1] jdk webrev: http://bussund0416.us.oracle.com/~rriggs/webrev/webrev-hijrah-config-8049376/ From martinrb at google.com Tue Oct 28 18:09:15 2014 From: martinrb at google.com (Martin Buchholz) Date: Tue, 28 Oct 2014 11:09:15 -0700 Subject: RFR: 8062194: java.util.jar.Attributes should use insertion-ordered iteration In-Reply-To: References: <544E96AC.90904@oracle.com> Message-ID: Xueming, I understand that getting CCC approval is a fair amount of work. At your option, we could leave the spec unchanged and do without CCC, given that Attributes' iteration order has changed in every past release. Or we could split the spec change off as a separate improvement. On Mon, Oct 27, 2014 at 12:15 PM, Martin Buchholz wrote: > [+core-libs-dev oops I forgot to cc: the first time...] > > On Mon, Oct 27, 2014 at 12:02 PM, Xueming Shen > wrote: >> >> On 10/27/2014 11:33 AM, Martin Buchholz wrote: >>> >>> Hello Xueming, Alan, >>> >>> I'd like you to do a code review. >>> >>> >>> http://cr.openjdk.java.net/~martin/webrevs/openjdk9/Attributes-iteration-order/ >>> >>> https://bugs.openjdk.java.net/browse/JDK-8062194 >> >> >> The change looks fine. But guess we might have to go through the CCC for >> this one, >> given the nature of its "incompatibility"? >> > > Yes - technically, this is a small incompatibility. (But Attribute > iteration order has changed many times) > >> >> Btw, is there any "noticeable" performance concern of switching from >> hashmap to linkedhashmap? >> Guess, we might have use scenario that lots of attributes is being access >> when lots of jar get >> opened the same time... > > > LinkedHashMap uses a "little more" cpu and memory. The cost is small enough > that some people have suggested simply replacing HashMap's implementation > with that of LinkedHashMap, and that is not totally crazy, but we're not > going that far. Attributes are unlikely to contain many elements or to be > long-lived. > From xueming.shen at oracle.com Tue Oct 28 18:24:21 2014 From: xueming.shen at oracle.com (Xueming Shen) Date: Tue, 28 Oct 2014 11:24:21 -0700 Subject: RFR: 8062194: java.util.jar.Attributes should use insertion-ordered iteration In-Reply-To: References: <544E96AC.90904@oracle.com> Message-ID: <544FDF55.6000906@oracle.com> Martin, I can help the CCC, it is fair quick these days given this is a really simple update, just couple days. -Sherman On 10/28/2014 11:09 AM, Martin Buchholz wrote: > Xueming, I understand that getting CCC approval is a fair amount of > work. At your option, we could leave the spec unchanged and do > without CCC, given that Attributes' iteration order has changed in > every past release. Or we could split the spec change off as a > separate improvement. > > On Mon, Oct 27, 2014 at 12:15 PM, Martin Buchholz wrote: >> [+core-libs-dev oops I forgot to cc: the first time...] >> >> On Mon, Oct 27, 2014 at 12:02 PM, Xueming Shen >> wrote: >>> On 10/27/2014 11:33 AM, Martin Buchholz wrote: >>>> Hello Xueming, Alan, >>>> >>>> I'd like you to do a code review. >>>> >>>> >>>> http://cr.openjdk.java.net/~martin/webrevs/openjdk9/Attributes-iteration-order/ >>>> >>>> https://bugs.openjdk.java.net/browse/JDK-8062194 >>> >>> The change looks fine. But guess we might have to go through the CCC for >>> this one, >>> given the nature of its "incompatibility"? >>> >> Yes - technically, this is a small incompatibility. (But Attribute >> iteration order has changed many times) >> >>> Btw, is there any "noticeable" performance concern of switching from >>> hashmap to linkedhashmap? >>> Guess, we might have use scenario that lots of attributes is being access >>> when lots of jar get >>> opened the same time... >> >> LinkedHashMap uses a "little more" cpu and memory. The cost is small enough >> that some people have suggested simply replacing HashMap's implementation >> with that of LinkedHashMap, and that is not totally crazy, but we're not >> going that far. Attributes are unlikely to contain many elements or to be >> long-lived. >> From Alan.Bateman at oracle.com Tue Oct 28 19:52:13 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 28 Oct 2014 19:52:13 +0000 Subject: RFR: 8062194: java.util.jar.Attributes should use insertion-ordered iteration In-Reply-To: References: <544E96AC.90904@oracle.com> Message-ID: <544FF3ED.2020901@oracle.com> On 28/10/2014 18:09, Martin Buchholz wrote: > Xueming, I understand that getting CCC approval is a fair amount of > work. At your option, we could leave the spec unchanged and do > without CCC, given that Attributes' iteration order has changed in > every past release. Or we could split the spec change off as a > separate improvement. > If we eventually want to specify that the iteration order is predictable then it's probably best to do it all together. The additional class description looks okay. One comment on the constructor that takes the Attributes parameter is that the newly created Attributes might have a different order to the Attributes that it was created with. This would only arise if Attributes is sub-classes by something that uses a different iteration order to its super. -Alan From vladimir.x.ivanov at oracle.com Tue Oct 28 19:04:47 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Tue, 28 Oct 2014 23:04:47 +0400 Subject: [9] [8u40] RFR (M): 8059877: GWT branch frequencies pollution due to LF sharing In-Reply-To: <95EF0781-6DCB-4294-912A-25C61912F8B9@oracle.com> References: <54382E90.7040105@oracle.com> <03B32851-A9DB-4C43-ABB3-2CFE36D7CB0C@oracle.com> <543D717C.3090508@oracle.com> <0F6750AB-3949-4E5A-B67B-1FA1A10E5CA2@oracle.com> <543E90E0.6080200@oracle.com> <95EF0781-6DCB-4294-912A-25C61912F8B9@oracle.com> Message-ID: <544FE8CF.6050003@oracle.com> John, thanks for the feedback! See my answers inline. Updated version: http://cr.openjdk.java.net/~vlivanov/8059877/webrev.02/ > The algorithm looks fine, as long as the count is small. (Otherwise we > might want to spend effort recompiling the DontInline LF. Yes, the intention is to have it small - about the same as COMPILE_THRESHOLD. I experimented with recompiling all affected nmethods, but it seriously slows down warmup once recompilation limit is hit. > Call it CountingWrapper, since that's what it does. (Count down vs. > count up doesn't matter much.) > Then you can call the states "counting" and "not counting". The > pre-action is present only in the counting state. > The aspect of inlining or blocking is then focused down to a detail of > the LF flavor. > You call DelegatingMethodHandle.makeReinvokerForm in three places, two > of which are identical calls. I suggest refactoring so as to call it in > two places. I decided to go the following route: I factored CountingWrapper logic, but instead of caching lambda forms for counting & non-counting cases, I cache lambda form producers (MethodHandle -> LambdaForm). It allows to delay LF instantiation for non-counting case and create new lambda forms for DelegatingMethodHandle::asTypeUncached in CoutingWrapper. My observations show that about half of the wrappers stay in counting state, so I decided it makes sense to delay LF instantiation. > (Nit: As a matter of style, the default value of a boolean flag should > be usual one, in typical cases. By that reasoning, LF.forceInline > should be LF.dontInline; the objection to this is that it is anti-style > to have a negative word in a boolean name.) If you don't mind, I decided to leave forceInline flag name as is. > You could create and cache *both* reinvoker forms when the MH wrapper is > created, so that the non-counting, inline-enabled LF is created more > eagerly during warmup. It might make for a smoother warmup. (Maybe. > Maybe not.) Good point! I decided to precompile non-counting LF before setting it. Best regards, Vladimir Ivanov From Alan.Bateman at oracle.com Tue Oct 28 20:13:24 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 28 Oct 2014 20:13:24 +0000 Subject: RFR 9: 8048124: Read hijra-config-umalqura.properties as a resource In-Reply-To: <544FD5E8.1040404@oracle.com> References: <544FD5E8.1040404@oracle.com> Message-ID: <544FF8E4.9040406@oracle.com> On 28/10/2014 17:44, roger riggs wrote: > Hi, > > One change missing from the previous webrev is to copy the Hijrah > calendar data > to its location as a resource. It is in the top level repository, so > it was not covered by > the earlier webrev. > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-hijrah-config-8049376-top/ This looks okay. -Alan From john.r.rose at oracle.com Tue Oct 28 20:21:08 2014 From: john.r.rose at oracle.com (John Rose) Date: Tue, 28 Oct 2014 13:21:08 -0700 Subject: [9] [8u40] RFR (M): 8059877: GWT branch frequencies pollution due to LF sharing In-Reply-To: <544FE8CF.6050003@oracle.com> References: <54382E90.7040105@oracle.com> <03B32851-A9DB-4C43-ABB3-2CFE36D7CB0C@oracle.com> <543D717C.3090508@oracle.com> <0F6750AB-3949-4E5A-B67B-1FA1A10E5CA2@oracle.com> <543E90E0.6080200@oracle.com> <95EF0781-6DCB-4294-912A-25C61912F8B9@oracle.com> <544FE8CF.6050003@oracle.com> Message-ID: <5D2610C2-4DC6-4703-BE08-2CFF7CA12369@oracle.com> Good, I'm happy. Reviewed. ? John On Oct 28, 2014, at 12:04 PM, Vladimir Ivanov wrote: > John, thanks for the feedback! > See my answers inline. From lance.andersen at oracle.com Tue Oct 28 20:45:51 2014 From: lance.andersen at oracle.com (Lance Andersen) Date: Tue, 28 Oct 2014 16:45:51 -0400 Subject: remote: Permission denied (publickey). -- anyone else getting this Message-ID: <38611A18-6443-407A-A2E9-B296DD77D4CE@oracle.com> Anyone have an idea as to the following error after pulling a clean workspace. Also getting this on a previous workspace... hg outgoing -v comparing with ssh://lancea at hg.openjdk.java.net/jdk9/dev/jdk running ssh lancea at hg.openjdk.java.net 'hg -R jdk9/dev/jdk serve --stdio' remote: Permission denied (publickey). abort: no suitable response from remote hg! hg paths default = http://hg.openjdk.java.net/jdk9/dev/jdk default-push = ssh://lancea at hg.openjdk.java.net/jdk9/dev/jdk Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From jiangli.zhou at oracle.com Tue Oct 28 21:45:12 2014 From: jiangli.zhou at oracle.com (Jiangli Zhou) Date: Tue, 28 Oct 2014 14:45:12 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <544F2253.5000401@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544F0505.4050206@oracle.com> <544F2253.5000401@oracle.com> Message-ID: <54500E68.1040202@oracle.com> Hi Ioi, This sounds ok. Thanks, Jiangli On 10/27/2014 09:57 PM, Ioi Lam wrote: > > On 10/27/14, 7:52 PM, Jiangli Zhou wrote: >> Hi Ioi, >> >> I have a question for following code in AppClassLoader.loadClass(). >> If a class is 'known to not exist' for the AppClassLoader (not in the >> AppClassLoader and parent classloaders' shared lookup cache), it >> seems findLoadedClass() would only find classes that's dynamically >> loaded by the parent loaders. The AppClassLoader would never try to >> load the class. Is the AppClassLoader's lookup cache guaranteed to >> have all the classes in it's path? >> >> 315 if (ucp.knownToNotExist(name)) { >> 316 // The class of the given name is not found in >> the parent >> 317 // class loader as well as its local URLClassPath. >> 318 // Check if this class has already been defined >> dynamically; >> 319 // if so, return the loaded class; otherwise, >> skip the parent >> 320 // delegation and findClass. >> 321 synchronized (getClassLoadingLock(name)) { >> 322 Class c = findLoadedClass(name); >> 323 if (c != null) { >> 324 return c; >> 325 } >> 326 } >> 327 throw new ClassNotFoundException(name); >> 328 } > The reason is to make the behavior consistent with > java.lang.ClassLoader.loadClass(): > > protected Class loadClass(String name, boolean resolve) > throws ClassNotFoundException > { > synchronized (getClassLoadingLock(name)) { > // First, check if the class has already been loaded > Class c = findLoadedClass(name); > .... > > If is not in any of the JAR files but was dynamically defined > (using ClassLoader.defineClass, etc), then AppClassLoader.loadClass() > should return the class without throwing ClassNotFoundException. > > Thanks > - Ioi > >> Thanks, >> Jiangli >> >> On 10/27/2014 3:32 PM, Ioi Lam wrote: >>> Hi David, I have update the latest webrev at: >>> >>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ >>> >>> and fixed the "int cache[]" style you mentioned. >>> >>> This version also contains the JDK test case that Mandy requested: >>> >>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html >>> >>> >>> Thanks >>> - Ioi >>> > From martinrb at google.com Tue Oct 28 22:49:57 2014 From: martinrb at google.com (Martin Buchholz) Date: Tue, 28 Oct 2014 15:49:57 -0700 Subject: RFR 7156085: ArrayIndexOutOfBoundsException throws in UTF8Reader of SAXParser Message-ID: Hi Joe, I'd like you to do a code review. http://cr.openjdk.java.net/~martin/webrevs/openjdk9/xerces-UTF8Reader-supplementary-characters/ https://bugs.openjdk.java.net/browse/JDK-7156085#comment-13569882 https://issues.apache.org/jira/browse/XERCESJ-1257 As usual, I don't know what I'm doing in jaxp land. This bug should be fixed in both upstream xerces and in openjdk's copy. Probably the xerces private UTF8 decoder should be thrown out, but I'm only trying to bandaid the code here. From karen.kinnear at oracle.com Tue Oct 28 22:49:57 2014 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Tue, 28 Oct 2014 18:49:57 -0400 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <544F1DCA.9040304@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544EF9A3.8090109@oracle.com> <544F1DCA.9040304@oracle.com> Message-ID: <253BAE47-9732-4085-A221-16285AA62782@oracle.com> Ioi, Looks good! Thanks to all who have contributed! A couple of minor comments/questions: 1. jvm.h (hotspot and jdk) All three APIs talk about loader_type, but the code uses loader. 2. Launcher.java To the best of my understanding - the call to findLoadedClass does not require synchronizing on the class loader lock, that is needed to ensure find/define atomicity - so that we do not call defineClass twice on the same class - i.e. in loadClass - it is needed around the findLoadedClass / findClass(defineClass) calls. This call is just a SystemDictionary lookup and does not require the lock to be held. David H and Mandy - does that make sense to you both? thanks, Karen On Oct 28, 2014, at 12:38 AM, Ioi Lam wrote: > > On 10/27/14, 7:04 PM, Mandy Chung wrote: >> >> On 10/27/2014 3:32 PM, Ioi Lam wrote: >>> Hi David, I have update the latest webrev at: >>> >>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ >>> >> >> The update looks good. Thanks. >> >>> This version also contains the JDK test case that Mandy requested: >>> >>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html >>> >> >> What I request to add is a test setting the system property (-Dsun.cds.enableSharedLookupCache=true) and continue to load class A and B. Removing line 44-58 should do it and also no need to set -Dfoo.foo.bar. >> > Do you mean change the test to call System.setProperty("sun.cds.enableSharedLookupCache", "true")? > > But we know that the property is checked only once, before any app classes are loaded. So calling System.setProperty in an application class won't test anything. >> It'd be good if you run this test and turn on the debug traces to make sure that the application class loader and ext class loader will start up with the lookup cache enabled and make up call to the VM. As it doesn't have the app cds archive, it will invalidate the cache right away and continue the class lookup with null cache array. > In the latest code, if CDS is not available, lookupCacheEnabled will be set to false inside the static initializer of URLClassPath: > > private static volatile boolean lookupCacheEnabled > = "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache")); > > later, when the boot/ext/app loaders call into here: > > synchronized void initLookupCache(ClassLoader loader) { > if ((lookupCacheURLs = getLookupCacheURLs(loader)) != null) { > lookupCacheLoader = loader; > } else { > // This JVM instance does not support lookup cache. > disableAllLookupCaches(); > } > } > > their lookupCacheURLs[] fields will all be set to null. As a result, getLookupCacheForClassLoader and knownToNotExist0 will never be called. > > I can add a DEBUG_LOOKUP_CACHE trace inside disableAllLookupCaches to print "lookup cache disabled", and check for that in the test. Is this OK? > > Thanks > - Ioi > > > From david.holmes at oracle.com Wed Oct 29 02:34:07 2014 From: david.holmes at oracle.com (David Holmes) Date: Wed, 29 Oct 2014 12:34:07 +1000 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <253BAE47-9732-4085-A221-16285AA62782@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544EF9A3.8090109@oracle.com> <544F1DCA.9040304@oracle.com> <253BAE47-9732-4085-A221-16285AA62782@oracle.com> Message-ID: <5450521F.2050609@oracle.com> Hi Karen, I haven't been tracking the details of this and am unclear on the overall caching strategy however ... On 29/10/2014 8:49 AM, Karen Kinnear wrote: > Ioi, > > Looks good! Thanks to all who have contributed! > > A couple of minor comments/questions: > > 1. jvm.h (hotspot and jdk) > All three APIs talk about loader_type, but the code uses loader. > > 2. Launcher.java > To the best of my understanding - the call to findLoadedClass does not require synchronizing on the class loader lock, > that is needed to ensure find/define atomicity - so that we do not call defineClass twice on the same class - i.e. in > loadClass - it is needed around the findLoadedClass / findClass(defineClass) calls. This call is just a SystemDictionary lookup > and does not require the lock to be held. If the class can be defined dynamically - which it appears it can (though I'm not sure what that means) - then you can have a race between the thread doing the defining and the thread doing the findLoadedClass. By doing findLoadedClass with the lock held you enforce some serialization of the actions, but there is still a race. So the only way the lock could matter is if user code could trigger the second thread's lookup of the class after the lock has been taken by the thread doing the dynamic definition - whether that is possible depends on what this dynamic definition actually is. David > David H and Mandy - does that make sense to you both? > > thanks, > Karen > > On Oct 28, 2014, at 12:38 AM, Ioi Lam wrote: > >> >> On 10/27/14, 7:04 PM, Mandy Chung wrote: >>> >>> On 10/27/2014 3:32 PM, Ioi Lam wrote: >>>> Hi David, I have update the latest webrev at: >>>> >>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ >>>> >>> >>> The update looks good. Thanks. >>> >>>> This version also contains the JDK test case that Mandy requested: >>>> >>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html >>>> >>> >>> What I request to add is a test setting the system property (-Dsun.cds.enableSharedLookupCache=true) and continue to load class A and B. Removing line 44-58 should do it and also no need to set -Dfoo.foo.bar. >>> >> Do you mean change the test to call System.setProperty("sun.cds.enableSharedLookupCache", "true")? >> >> But we know that the property is checked only once, before any app classes are loaded. So calling System.setProperty in an application class won't test anything. >>> It'd be good if you run this test and turn on the debug traces to make sure that the application class loader and ext class loader will start up with the lookup cache enabled and make up call to the VM. As it doesn't have the app cds archive, it will invalidate the cache right away and continue the class lookup with null cache array. >> In the latest code, if CDS is not available, lookupCacheEnabled will be set to false inside the static initializer of URLClassPath: >> >> private static volatile boolean lookupCacheEnabled >> = "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache")); >> >> later, when the boot/ext/app loaders call into here: >> >> synchronized void initLookupCache(ClassLoader loader) { >> if ((lookupCacheURLs = getLookupCacheURLs(loader)) != null) { >> lookupCacheLoader = loader; >> } else { >> // This JVM instance does not support lookup cache. >> disableAllLookupCaches(); >> } >> } >> >> their lookupCacheURLs[] fields will all be set to null. As a result, getLookupCacheForClassLoader and knownToNotExist0 will never be called. >> >> I can add a DEBUG_LOOKUP_CACHE trace inside disableAllLookupCaches to print "lookup cache disabled", and check for that in the test. Is this OK? >> >> Thanks >> - Ioi >> >> >> > From ioi.lam at oracle.com Wed Oct 29 06:04:47 2014 From: ioi.lam at oracle.com (Ioi Lam) Date: Tue, 28 Oct 2014 23:04:47 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <5450521F.2050609@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544EF9A3.8090109@oracle.com> <544F1DCA.9040304@oracle.com> <253BAE47-9732-4085-A221-16285AA62782@oracle.com> <5450521F.2050609@oracle.com> Message-ID: <5450837F.6090802@oracle.com> On 10/28/14, 7:34 PM, David Holmes wrote: > Hi Karen, > > I haven't been tracking the details of this and am unclear on the > overall caching strategy however ... > > On 29/10/2014 8:49 AM, Karen Kinnear wrote: >> Ioi, >> >> Looks good! Thanks to all who have contributed! >> >> A couple of minor comments/questions: >> >> 1. jvm.h (hotspot and jdk) >> All three APIs talk about loader_type, but the code uses loader. >> >> 2. Launcher.java >> To the best of my understanding - the call to findLoadedClass does >> not require synchronizing on the class loader lock, >> that is needed to ensure find/define atomicity - so that we do not >> call defineClass twice on the same class - i.e. in >> loadClass - it is needed around the findLoadedClass / >> findClass(defineClass) calls. This call is just a SystemDictionary >> lookup >> and does not require the lock to be held. > > If the class can be defined dynamically - which it appears it can > (though I'm not sure what that means) - then you can have a race > between the thread doing the defining and the thread doing the > findLoadedClass. By doing findLoadedClass with the lock held you > enforce some serialization of the actions, but there is still a race. > So the only way the lock could matter is if user code could trigger > the second thread's lookup of the class after the lock has been taken > by the thread doing the dynamic definition - whether that is possible > depends on what this dynamic definition actually is. > I copied the code from ClassLoader.loadClass, which does it it a synchronized block: class ClassLoader { protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } } So I guess it should look like this in Launcher$AppClassLoader, just to ensure the same things are done (regardless of whether it's necessary or not)? Does resolveClass need to be done inside the synchronized block? class Launcher$AppClassLoader { public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { int i = name.lastIndexOf('.'); if (i != -1) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPackageAccess(name.substring(0, i)); } } if (ucp.knownToNotExist(name)) { // The class of the given name is not found in the parent // class loader as well as its local URLClassPath. // Check if this class has already been defined dynamically; // if so, return the loaded class; otherwise, skip the parent // delegation and findClass. >>from here * synchronized (getClassLoadingLock(name)) {** ** Class c = findLoadedClass(name);** ** if (c != null) {** ** if (resolve) {** ** resolveClass(c);** ** }** ** return c;** ** }** ** }* < David > >> David H and Mandy - does that make sense to you both? >> >> thanks, >> Karen >> >> On Oct 28, 2014, at 12:38 AM, Ioi Lam wrote: >> >>> >>> On 10/27/14, 7:04 PM, Mandy Chung wrote: >>>> >>>> On 10/27/2014 3:32 PM, Ioi Lam wrote: >>>>> Hi David, I have update the latest webrev at: >>>>> >>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ >>>>> >>>> >>>> The update looks good. Thanks. >>>> >>>>> This version also contains the JDK test case that Mandy requested: >>>>> >>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html >>>>> >>>>> >>>> >>>> What I request to add is a test setting the system property >>>> (-Dsun.cds.enableSharedLookupCache=true) and continue to load class >>>> A and B. Removing line 44-58 should do it and also no need to set >>>> -Dfoo.foo.bar. >>>> >>> Do you mean change the test to call >>> System.setProperty("sun.cds.enableSharedLookupCache", "true")? >>> >>> But we know that the property is checked only once, before any app >>> classes are loaded. So calling System.setProperty in an application >>> class won't test anything. >>>> It'd be good if you run this test and turn on the debug traces to >>>> make sure that the application class loader and ext class loader >>>> will start up with the lookup cache enabled and make up call to the >>>> VM. As it doesn't have the app cds archive, it will invalidate the >>>> cache right away and continue the class lookup with null cache array. >>> In the latest code, if CDS is not available, lookupCacheEnabled will >>> be set to false inside the static initializer of URLClassPath: >>> >>> private static volatile boolean lookupCacheEnabled >>> = >>> "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache")); >>> >>> later, when the boot/ext/app loaders call into here: >>> >>> synchronized void initLookupCache(ClassLoader loader) { >>> if ((lookupCacheURLs = getLookupCacheURLs(loader)) != null) { >>> lookupCacheLoader = loader; >>> } else { >>> // This JVM instance does not support lookup cache. >>> disableAllLookupCaches(); >>> } >>> } >>> >>> their lookupCacheURLs[] fields will all be set to null. As a result, >>> getLookupCacheForClassLoader and knownToNotExist0 will never be called. >>> >>> I can add a DEBUG_LOOKUP_CACHE trace inside disableAllLookupCaches >>> to print "lookup cache disabled", and check for that in the test. Is >>> this OK? >>> >>> Thanks >>> - Ioi >>> >>> >>> >> From david.holmes at oracle.com Wed Oct 29 06:37:28 2014 From: david.holmes at oracle.com (David Holmes) Date: Wed, 29 Oct 2014 16:37:28 +1000 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <5450837F.6090802@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544EF9A3.8090109@oracle.com> <544F1DCA.9040304@oracle.com> <253BAE47-9732-4085-A221-16285AA62782@oracle.com> <5450521F.2050609@oracle.com> <5450837F.6090802@oracle.com> Message-ID: <54508B28.2000105@oracle.com> On 29/10/2014 4:04 PM, Ioi Lam wrote: > > On 10/28/14, 7:34 PM, David Holmes wrote: >> Hi Karen, >> >> I haven't been tracking the details of this and am unclear on the >> overall caching strategy however ... >> >> On 29/10/2014 8:49 AM, Karen Kinnear wrote: >>> Ioi, >>> >>> Looks good! Thanks to all who have contributed! >>> >>> A couple of minor comments/questions: >>> >>> 1. jvm.h (hotspot and jdk) >>> All three APIs talk about loader_type, but the code uses loader. >>> >>> 2. Launcher.java >>> To the best of my understanding - the call to findLoadedClass does >>> not require synchronizing on the class loader lock, >>> that is needed to ensure find/define atomicity - so that we do not >>> call defineClass twice on the same class - i.e. in >>> loadClass - it is needed around the findLoadedClass / >>> findClass(defineClass) calls. This call is just a SystemDictionary >>> lookup >>> and does not require the lock to be held. >> >> If the class can be defined dynamically - which it appears it can >> (though I'm not sure what that means) - then you can have a race >> between the thread doing the defining and the thread doing the >> findLoadedClass. By doing findLoadedClass with the lock held you >> enforce some serialization of the actions, but there is still a race. >> So the only way the lock could matter is if user code could trigger >> the second thread's lookup of the class after the lock has been taken >> by the thread doing the dynamic definition - whether that is possible >> depends on what this dynamic definition actually is. >> > I copied the code from ClassLoader.loadClass, which does it it a > synchronized block: > > class ClassLoader { > protected Class loadClass(String name, boolean resolve) > throws ClassNotFoundException > { > synchronized (getClassLoadingLock(name)) { > // First, check if the class has already been loaded > Class c = findLoadedClass(name); > if (c == null) { > long t0 = System.nanoTime(); > try { > if (parent != null) { > c = parent.loadClass(name, false); > } else { > c = findBootstrapClassOrNull(name); > } > } catch (ClassNotFoundException e) { > // ClassNotFoundException thrown if class not found > // from the non-null parent class loader > } > > if (c == null) { > // If still not found, then invoke findClass in order > // to find the class. > long t1 = System.nanoTime(); > c = findClass(name); > > // this is the defining class loader; record the stats > sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); > sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); > sun.misc.PerfCounter.getFindClasses().increment(); > } > } > if (resolve) { > resolveClass(c); > } > return c; > } > } > > So I guess it should look like this in Launcher$AppClassLoader, just to > ensure the same things are done (regardless of whether it's necessary or > not)? In ClassLoader.loadClass it is providing atomicity across a number of actions in the worst-case: - checking for already loaded; if not then - try to load through parent; if not then - findClass (which will do defineClass) You don't have those atomicity constraints because you are only doing one thing - checking to see if the class is loaded. Your locking is probably harmless but those are famous last words when it comes to classloading. :) > > Does resolveClass need to be done inside the synchronized block? Depends on whether it depends on the classloader locking to prevent concurrent resolve attempts. David ----- > class Launcher$AppClassLoader { > public Class loadClass(String name, boolean resolve) > throws ClassNotFoundException > { > int i = name.lastIndexOf('.'); > if (i != -1) { > SecurityManager sm = System.getSecurityManager(); > if (sm != null) { > sm.checkPackageAccess(name.substring(0, i)); > } > } > > if (ucp.knownToNotExist(name)) { > // The class of the given name is not found in the parent > // class loader as well as its local URLClassPath. > // Check if this class has already been defined > dynamically; > // if so, return the loaded class; otherwise, skip the > parent > // delegation and findClass. > >>from here > * synchronized (getClassLoadingLock(name)) {** > ** Class c = findLoadedClass(name);** > ** if (c != null) {** > ** if (resolve) {** > ** resolveClass(c);** > ** }** > ** return c;** > ** }** > ** }* > < throw new ClassNotFoundException(name); > } > > return (super.loadClass(name, resolve)); > } > > Thanks > - Ioi > > >> David >> >>> David H and Mandy - does that make sense to you both? >>> >>> thanks, >>> Karen >>> >>> On Oct 28, 2014, at 12:38 AM, Ioi Lam wrote: >>> >>>> >>>> On 10/27/14, 7:04 PM, Mandy Chung wrote: >>>>> >>>>> On 10/27/2014 3:32 PM, Ioi Lam wrote: >>>>>> Hi David, I have update the latest webrev at: >>>>>> >>>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ >>>>>> >>>>> >>>>> The update looks good. Thanks. >>>>> >>>>>> This version also contains the JDK test case that Mandy requested: >>>>>> >>>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html >>>>>> >>>>>> >>>>> >>>>> What I request to add is a test setting the system property >>>>> (-Dsun.cds.enableSharedLookupCache=true) and continue to load class >>>>> A and B. Removing line 44-58 should do it and also no need to set >>>>> -Dfoo.foo.bar. >>>>> >>>> Do you mean change the test to call >>>> System.setProperty("sun.cds.enableSharedLookupCache", "true")? >>>> >>>> But we know that the property is checked only once, before any app >>>> classes are loaded. So calling System.setProperty in an application >>>> class won't test anything. >>>>> It'd be good if you run this test and turn on the debug traces to >>>>> make sure that the application class loader and ext class loader >>>>> will start up with the lookup cache enabled and make up call to the >>>>> VM. As it doesn't have the app cds archive, it will invalidate the >>>>> cache right away and continue the class lookup with null cache array. >>>> In the latest code, if CDS is not available, lookupCacheEnabled will >>>> be set to false inside the static initializer of URLClassPath: >>>> >>>> private static volatile boolean lookupCacheEnabled >>>> = >>>> "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache")); >>>> >>>> later, when the boot/ext/app loaders call into here: >>>> >>>> synchronized void initLookupCache(ClassLoader loader) { >>>> if ((lookupCacheURLs = getLookupCacheURLs(loader)) != null) { >>>> lookupCacheLoader = loader; >>>> } else { >>>> // This JVM instance does not support lookup cache. >>>> disableAllLookupCaches(); >>>> } >>>> } >>>> >>>> their lookupCacheURLs[] fields will all be set to null. As a result, >>>> getLookupCacheForClassLoader and knownToNotExist0 will never be called. >>>> >>>> I can add a DEBUG_LOOKUP_CACHE trace inside disableAllLookupCaches >>>> to print "lookup cache disabled", and check for that in the test. Is >>>> this OK? >>>> >>>> Thanks >>>> - Ioi >>>> >>>> >>>> >>> > From paul.sandoz at oracle.com Wed Oct 29 08:51:37 2014 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 29 Oct 2014 09:51:37 +0100 Subject: Request for review/advice from langtools team Re: Covariant overrides on the Buffer Hierarchy redux In-Reply-To: References: <3D27B84B-20F1-486C-954F-E908DD443DA9@oracle.com> <35FE2B2C-7BA2-4A11-AE9D-B5E12C7B5729@oracle.com> Message-ID: On Oct 28, 2014, at 1:59 PM, Joel Borggr?n-Franck wrote: > Hi Paul, > > Sorry for the delay. > > So if I understand this correctly, we get 4 warnings (and because of -Werror a build failure) in langtools when compiling vs Jdk 9, but need the casts because we bootstrap with Jdk 8. > Yes. > Looks good to me but I would prefer if you filed a bug on me for Jdk 10 for removing the SuppressWarnings and added comments pointing to the bug after the @SuppressWarnings annotations. That way I will remember to clean this up when we bootstrap with Jdk 9. > Ok, after i push i will log a new P4 bug and assign it to you. Thanks, Paul. From peter.levart at gmail.com Wed Oct 29 11:26:33 2014 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 29 Oct 2014 12:26:33 +0100 Subject: Loading classes with many methods is very expensive In-Reply-To: References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> Message-ID: <5450CEE9.7060707@gmail.com> Hi Joel, I found an inconsistency between getMethod() and getMethods() results that is present in current JDK8/9 code and in my latest webrev.02. The following program: import java.util.stream.Collectors; import java.util.stream.Stream; public class GetMethodTest { static void test(Class clazz) throws Exception { System.out.println(clazz.getName() + ".class.getMethods(): " + Stream .of(clazz.getMethods()) .filter(m -> m.getDeclaringClass() != Object.class) .collect(Collectors.toList())); System.out.println(clazz.getName() + ".class.getMethod(\"m\"): " + clazz.getMethod("m")); System.out.println(); } public static void main(String[] args) throws Exception { test(I.class); test(J.class); test(A.class); test(B.class); } } interface I { void m(); } interface J extends I { default void m() {} } abstract class A implements I {} abstract class B extends A implements J {} prints: I.class.getMethods(): [public abstract void I.m()] I.class.getMethod("m"): public abstract void I.m() J.class.getMethods(): [public default void J.m()] J.class.getMethod("m"): public default void J.m() A.class.getMethods(): [public abstract void I.m()] A.class.getMethod("m"): public abstract void I.m() B.class.getMethods(): [public default void J.m()] B.class.getMethod("m"): public abstract void I.m() B.class.getMethods() reports default method J.m() (which I think is correct), but B.class.getMethod("m") reports the abstract I.m() inherited from A, because here the getMethod0() algorithm stops searching for and consolidating any methods in (super)interfaces. Do you agree that this is a bug? Regards, Peter On 10/27/2014 02:45 PM, Joel Borggr?n-Franck wrote: > Hi Peter, > > As always, thanks for doing this! It has been on my todolist for a while but never quite bubbling up to the top. > > I don?t have time to look att his right now, but I expect to have some free time next week, but i have two short comments > > First, I have been thinking about moving MethodArray to its?s own top-level class, isn?t it about time? > > Second I would expect testing for the missing cases you uncovered (good catch!). > > I?ll try to get back to you asap. > > cheers > /Joel > > > On 26 okt 2014, at 23:53, Peter Levart wrote: > >> On 10/26/2014 09:25 PM, Peter Levart wrote: >>> 19657 classes loaded in 1.987373401 seconds. >>> 494141 methods obtained in 1.02493941 seconds. >>> >>> vs. >>> >>> 19657 classes loaded in 2.084409717 seconds. >>> 494124 methods obtained in 0.915928578 seconds. >> Hi, >> >> As you might have noticed, the number of methods obtained from patched code differed from original code. I have investigated this and found that original code treats abstract class methods the same as abstract interface methods as far as multiple inheritance is concerned (it keeps them together in the returned array). So I fixed this and here's new webrev which behaves the same as original code: >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.02/ >> >> Comparing original vs. patched code still shows speed-up: >> >> Original: >> >> 19657 classes loaded in 1.980493029 seconds. >> 494141 methods obtained in 0.976318927 seconds. >> 494141 methods obtained in 0.886504437 seconds. >> 494141 methods obtained in 0.911153722 seconds. >> 494141 methods obtained in 0.880550509 seconds. >> 494141 methods obtained in 0.875526704 seconds. >> 494141 methods obtained in 0.877258894 seconds. >> 494141 methods obtained in 0.871794344 seconds. >> 494141 methods obtained in 0.884159644 seconds. >> 494141 methods obtained in 0.892648522 seconds. >> 494141 methods obtained in 0.884581841 seconds. >> >> Patched: >> >> 19657 classes loaded in 2.055697675 seconds. >> 494141 methods obtained in 0.853922188 seconds. >> 494141 methods obtained in 0.776203794 seconds. >> 494141 methods obtained in 0.858774803 seconds. >> 494141 methods obtained in 0.778178867 seconds. >> 494141 methods obtained in 0.760043997 seconds. >> 494141 methods obtained in 0.756352444 seconds. >> 494141 methods obtained in 0.740826372 seconds. >> 494141 methods obtained in 0.744264782 seconds. >> 494141 methods obtained in 0.73805894 seconds. >> 494141 methods obtained in 0.746852752 seconds. >> >> >> 55 java/lang/reflect jtreg tests still pass. As they did before, which means that we don't have a coverage for such cases. I'll see where I can add such a case (EnumSet for example, which inherits from Set interface and AbstractColection class via two different paths, so Set.size()/iterator() and AbstractCollection.size()/iterator() are both returned from getMethods())... >> >> >> Regards, Peter >> From david.holmes at oracle.com Wed Oct 29 12:25:50 2014 From: david.holmes at oracle.com (David Holmes) Date: Wed, 29 Oct 2014 22:25:50 +1000 Subject: java.util.Optional: a better implementation? In-Reply-To: <5450D83A.1080809@gmail.com> References: <5450D83A.1080809@gmail.com> Message-ID: <5450DCCE.4080501@oracle.com> Nicolas, core-libs-dev is the right mailing list for this so I've cc'd it. Please drop the discuss list from any follow up. David On 29/10/2014 10:06 PM, nicarran at gmail.com wrote: > Hi, > > I'm evaluating java.util.Optional to use it all around my code. I > noticed that its current implementation checks for null on almost every > method and that these checks can be avoided by changing its > implementation to an abstract Optional class with two subclasses, one > for the EMPTY and another for the not-empty (present) values without > breaking compatibility. Something like this: > > ********************** > > public abstract class Optional { > > private static final Optional EMPTY=new Empty<>(); > > private static class Empty > extends Optional { > > @Override > public boolean isPresent() { > return false; > } > @Override > public T get() { > throw new NoSuchElementException("No value present"); > } > @Override > public void ifPresent(Consumer consumer) { > } > // and so on > } > > private static class Present > extends Optional { > > private final T value; > > Present(T value) { > this.value=Objects.requireNonNull(value); > } > > @Override > public boolean isPresent() { > return true; > } > @Override > public T get() { > return value; > } > @Override > public void ifPresent(Consumer consumer) { > consumer.accept(value); > } > // and so on > } > > private Optional() {} > > public static Optional of(T value) { > return new Present<>(value); > } > > public static Optional ofNullable(T value) { > return value==null? empty(): new Present<>(value); > } > > @SuppressWarnings("unchecked") > public static Optional empty(){ > return (Optional)EMPTY; > } > > public abstract boolean isPresent(); > > public abstract T get(); > > public abstract void ifPresent(Consumer consumer); > > // and so on > } > ******************** > > The JVM probably optimizes and throws away the null checks yielding in > equal performance compared to the proposed implementation (above) ---I > haven't done any performance tests----, but why wait for the JVM when > this implementation is also nicer to read? What do you think? > > Please let me know if this is not the appropriate mailing list to post > this message, > Thanks, > Nicolas > From aleksey.shipilev at oracle.com Wed Oct 29 12:43:01 2014 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Wed, 29 Oct 2014 15:43:01 +0300 Subject: java.util.Optional: a better implementation? In-Reply-To: <5450DCCE.4080501@oracle.com> References: <5450D83A.1080809@gmail.com> <5450DCCE.4080501@oracle.com> Message-ID: <5450E0D5.4070102@oracle.com> On 29.10.2014 15:25, David Holmes wrote: > On 29/10/2014 10:06 PM, nicarran at gmail.com wrote: >> The JVM probably optimizes and throws away the null checks yielding in >> equal performance compared to the proposed implementation (above) ---I >> haven't done any performance tests----, but why wait for the JVM when >> this implementation is also nicer to read? What do you think? I think most of the null checks will be folded into implicit null checks, which will have null (pun intended) effect on performance. What you suggest, however, will probably explode otherwise monomorphic calls to Optional to bimorphic calls to Optional.Empty/Optional.present -- and that will affect performance. You can make a few benchmarks to quantify those effects -- out of curiosity. I don't think the minute improvements, if any, will justify exploding the class hierarchy though. -Aleksey. From joel.franck at oracle.com Wed Oct 29 13:08:52 2014 From: joel.franck at oracle.com (=?windows-1252?Q?Joel_Borggr=E9n-Franck?=) Date: Wed, 29 Oct 2014 14:08:52 +0100 Subject: Loading classes with many methods is very expensive In-Reply-To: <5450CEE9.7060707@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <5450CEE9.7060707@gmail.com> Message-ID: Hi Peter, I?m not entirely convinced this is a bug. The lookup order for getMethod has for a long time been walk up superclasses and return what you find there first without even looking at interfaces. It might be desirable to change that but I?m not sure. cheers /Joel On 29 okt 2014, at 12:26, Peter Levart wrote: > Hi Joel, > > I found an inconsistency between getMethod() and getMethods() results that is present in current JDK8/9 code and in my latest webrev.02. The following program: > > import java.util.stream.Collectors; > import java.util.stream.Stream; > > public class GetMethodTest { > > static void test(Class clazz) throws Exception { > > System.out.println(clazz.getName() + ".class.getMethods(): " + > Stream > .of(clazz.getMethods()) > .filter(m -> m.getDeclaringClass() != Object.class) > .collect(Collectors.toList())); > > System.out.println(clazz.getName() + ".class.getMethod(\"m\"): " + > clazz.getMethod("m")); > > System.out.println(); > } > > public static void main(String[] args) throws Exception { > test(I.class); > test(J.class); > test(A.class); > test(B.class); > } > } > > interface I { > void m(); > } > > interface J extends I { > default void m() {} > } > > abstract class A implements I {} > > abstract class B extends A implements J {} > > > prints: > > I.class.getMethods(): [public abstract void I.m()] > I.class.getMethod("m"): public abstract void I.m() > > J.class.getMethods(): [public default void J.m()] > J.class.getMethod("m"): public default void J.m() > > A.class.getMethods(): [public abstract void I.m()] > A.class.getMethod("m"): public abstract void I.m() > > B.class.getMethods(): [public default void J.m()] > B.class.getMethod("m"): public abstract void I.m() > > B.class.getMethods() reports default method J.m() (which I think is correct), but B.class.getMethod("m") reports the abstract I.m() inherited from A, because here the getMethod0() algorithm stops searching for and consolidating any methods in (super)interfaces. Do you agree that this is a bug? > > > Regards, Peter > > On 10/27/2014 02:45 PM, Joel Borggr?n-Franck wrote: >> Hi Peter, >> >> As always, thanks for doing this! It has been on my todolist for a while but never quite bubbling up to the top. >> >> I don?t have time to look att his right now, but I expect to have some free time next week, but i have two short comments >> >> First, I have been thinking about moving MethodArray to its?s own top-level class, isn?t it about time? >> >> Second I would expect testing for the missing cases you uncovered (good catch!). >> >> I?ll try to get back to you asap. >> >> cheers >> /Joel >> >> >> On 26 okt 2014, at 23:53, Peter Levart wrote: >> >>> On 10/26/2014 09:25 PM, Peter Levart wrote: >>>> 19657 classes loaded in 1.987373401 seconds. >>>> 494141 methods obtained in 1.02493941 seconds. >>>> >>>> vs. >>>> >>>> 19657 classes loaded in 2.084409717 seconds. >>>> 494124 methods obtained in 0.915928578 seconds. >>> Hi, >>> >>> As you might have noticed, the number of methods obtained from patched code differed from original code. I have investigated this and found that original code treats abstract class methods the same as abstract interface methods as far as multiple inheritance is concerned (it keeps them together in the returned array). So I fixed this and here's new webrev which behaves the same as original code: >>> >>> http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.02/ >>> >>> Comparing original vs. patched code still shows speed-up: >>> >>> Original: >>> >>> 19657 classes loaded in 1.980493029 seconds. >>> 494141 methods obtained in 0.976318927 seconds. >>> 494141 methods obtained in 0.886504437 seconds. >>> 494141 methods obtained in 0.911153722 seconds. >>> 494141 methods obtained in 0.880550509 seconds. >>> 494141 methods obtained in 0.875526704 seconds. >>> 494141 methods obtained in 0.877258894 seconds. >>> 494141 methods obtained in 0.871794344 seconds. >>> 494141 methods obtained in 0.884159644 seconds. >>> 494141 methods obtained in 0.892648522 seconds. >>> 494141 methods obtained in 0.884581841 seconds. >>> >>> Patched: >>> >>> 19657 classes loaded in 2.055697675 seconds. >>> 494141 methods obtained in 0.853922188 seconds. >>> 494141 methods obtained in 0.776203794 seconds. >>> 494141 methods obtained in 0.858774803 seconds. >>> 494141 methods obtained in 0.778178867 seconds. >>> 494141 methods obtained in 0.760043997 seconds. >>> 494141 methods obtained in 0.756352444 seconds. >>> 494141 methods obtained in 0.740826372 seconds. >>> 494141 methods obtained in 0.744264782 seconds. >>> 494141 methods obtained in 0.73805894 seconds. >>> 494141 methods obtained in 0.746852752 seconds. >>> >>> >>> 55 java/lang/reflect jtreg tests still pass. As they did before, which means that we don't have a coverage for such cases. I'll see where I can add such a case (EnumSet for example, which inherits from Set interface and AbstractColection class via two different paths, so Set.size()/iterator() and AbstractCollection.size()/iterator() are both returned from getMethods())... >>> >>> >>> Regards, Peter >>> > From forax at univ-mlv.fr Wed Oct 29 13:10:43 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 29 Oct 2014 14:10:43 +0100 Subject: java.util.Optional: a better implementation? In-Reply-To: <5450E0D5.4070102@oracle.com> References: <5450D83A.1080809@gmail.com> <5450DCCE.4080501@oracle.com> <5450E0D5.4070102@oracle.com> Message-ID: <5450E753.9010407@univ-mlv.fr> On 10/29/2014 01:43 PM, Aleksey Shipilev wrote: > On 29.10.2014 15:25, David Holmes wrote: >> On 29/10/2014 10:06 PM, nicarran at gmail.com wrote: >>> The JVM probably optimizes and throws away the null checks yielding in >>> equal performance compared to the proposed implementation (above) ---I >>> haven't done any performance tests----, but why wait for the JVM when >>> this implementation is also nicer to read? What do you think? > I think most of the null checks will be folded into implicit null > checks, which will have null (pun intended) effect on performance. What > you suggest, however, will probably explode otherwise monomorphic calls > to Optional to bimorphic calls to Optional.Empty/Optional.present -- and > that will affect performance. > > You can make a few benchmarks to quantify those effects -- out of > curiosity. I don't think the minute improvements, if any, will justify > exploding the class hierarchy though. > > -Aleksey. > > Nicolas, The first implementation of Optional was roughly the one you suggest, it was later change to the current implementation which is, as everybody, said faster and will let the VM to remove the boxing (the object corresponding to Optional) in a future version of Java and please don't use Optional all around your code but only in public API :) cheers, R?mi From karen.kinnear at oracle.com Wed Oct 29 14:14:43 2014 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Wed, 29 Oct 2014 10:14:43 -0400 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <5450837F.6090802@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544EF9A3.8090109@oracle.com> <544F1DCA.9040304@oracle.com> <253BAE47-9732-4085-A221-16285AA62782@oracle.com> <5450521F.2050609@oracle.com> <5450837F.6090802@oracle.com> Message-ID: <355F8CF0-B67C-42D8-96D0-80857436612C@oracle.com> David, On Oct 29, 2014, at 2:04 AM, Ioi Lam wrote: > > On 10/28/14, 7:34 PM, David Holmes wrote: >> Hi Karen, >> >> I haven't been tracking the details of this and am unclear on the overall caching strategy however ... >> >> On 29/10/2014 8:49 AM, Karen Kinnear wrote: >>> Ioi, >>> >>> Looks good! Thanks to all who have contributed! >>> >>> A couple of minor comments/questions: >>> >>> 1. jvm.h (hotspot and jdk) >>> All three APIs talk about loader_type, but the code uses loader. >>> >>> 2. Launcher.java >>> To the best of my understanding - the call to findLoadedClass does not require synchronizing on the class loader lock, >>> that is needed to ensure find/define atomicity - so that we do not call defineClass twice on the same class - i.e. in >>> loadClass - it is needed around the findLoadedClass / findClass(defineClass) calls. This call is just a SystemDictionary lookup >>> and does not require the lock to be held. >> >> If the class can be defined dynamically - which it appears it can (though I'm not sure what that means) - then you can have a race between the thread doing the defining and the thread doing the findLoadedClass. By doing findLoadedClass with the lock held you enforce some serialization of the actions, but there is still a race. So the only way the lock could matter is if user code could trigger the second thread's lookup of the class after the lock has been taken by the thread doing the dynamic definition - whether that is possible depends on what this dynamic definition actually is. findLoadedClass is always a "snapshot", i.e. I agree with you that with or without a lock it is possible that another thread will define the class you are looking for after the findLoadedClass returns failure. Defined dynamically here is in contrast to being found in the archive - and uses the normal defineClass code paths. Going back to double-check in our parallel class loading changes to class loader synchronization: http://openjdk.java.net/groups/core-libs/ClassLoaderProposal.html This does match my memory - which is that the synchronization is to prevent duplicate defineClass calls, and we deliberately made the following changes to java.lang.ClassLoader: protected loadClass(String, boolean) changes: Remove synchronized keyword If "this" is not a parallel capable class loader, synchronize on "this" for backward compatibility else synchronize on a class-name-based-lock The synchronization in protected loadClass(String, boolean) ensures that defineClass(...) will not be called multiple times in parallel for the same class name/class loader pair. and recommendations for other class loaders: 4.b. Class loaders that invoke registerAsParallelCapable(), that override protected loadClass(String, boolean) or public loadClass(String) We recommend that you override findClass(String) instead, if at all possible To ensure that the protected defineClass(...) method is only called once for the same class name, you need to implement a finer-grained locking scheme. One option would be to adopt the class name based locking mechanism from java.lang.ClassLoader's protected loadClass(String, boolean) method. Note also that resolveClass does nothing (it throws an exception if called with a null value). So - my conclusion is we do not need the lock. David - I believe you might be improving the parallel class loading logic going forward, exploring the possibility of allowing parallel defineClass (with spec modifications). I don't think any synchronization is going to help us with that cleanup or with performance. And I think it will confuse people into worrying that the synchronization is needed here. If you want to leave it in anyway, please add some sort of comment that the synchronized is paranoia rather than having a known reason to use it - or that Karen doesn't believe it is needed :-) - or something - to not prevent future improvements here. thanks, Karen >> > I copied the code from ClassLoader.loadClass, which does it it a synchronized block: > > class ClassLoader { > protected Class loadClass(String name, boolean resolve) > throws ClassNotFoundException > { > synchronized (getClassLoadingLock(name)) { > // First, check if the class has already been loaded > Class c = findLoadedClass(name); > if (c == null) { > long t0 = System.nanoTime(); > try { > if (parent != null) { > c = parent.loadClass(name, false); > } else { > c = findBootstrapClassOrNull(name); > } > } catch (ClassNotFoundException e) { > // ClassNotFoundException thrown if class not found > // from the non-null parent class loader > } > > if (c == null) { > // If still not found, then invoke findClass in order > // to find the class. > long t1 = System.nanoTime(); > c = findClass(name); > > // this is the defining class loader; record the stats > sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); > sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); > sun.misc.PerfCounter.getFindClasses().increment(); > } > } > if (resolve) { > resolveClass(c); > } > return c; > } > } > > So I guess it should look like this in Launcher$AppClassLoader, just to ensure the same things are done (regardless of whether it's necessary or not)? > > Does resolveClass need to be done inside the synchronized block? > > class Launcher$AppClassLoader { > public Class loadClass(String name, boolean resolve) > throws ClassNotFoundException > { > int i = name.lastIndexOf('.'); > if (i != -1) { > SecurityManager sm = System.getSecurityManager(); > if (sm != null) { > sm.checkPackageAccess(name.substring(0, i)); > } > } > > if (ucp.knownToNotExist(name)) { > // The class of the given name is not found in the parent > // class loader as well as its local URLClassPath. > // Check if this class has already been defined dynamically; > // if so, return the loaded class; otherwise, skip the parent > // delegation and findClass. > >>from here > synchronized (getClassLoadingLock(name)) { > Class c = findLoadedClass(name); > if (c != null) { > if (resolve) { > resolveClass(c); > } > return c; > } > } > < throw new ClassNotFoundException(name); > } > > return (super.loadClass(name, resolve)); > } > > Thanks > - Ioi > > >> David >> >>> David H and Mandy - does that make sense to you both? >>> >>> thanks, >>> Karen >>> >>> On Oct 28, 2014, at 12:38 AM, Ioi Lam wrote: >>> >>>> >>>> On 10/27/14, 7:04 PM, Mandy Chung wrote: >>>>> >>>>> On 10/27/2014 3:32 PM, Ioi Lam wrote: >>>>>> Hi David, I have update the latest webrev at: >>>>>> >>>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ >>>>>> >>>>> >>>>> The update looks good. Thanks. >>>>> >>>>>> This version also contains the JDK test case that Mandy requested: >>>>>> >>>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html >>>>>> >>>>> >>>>> What I request to add is a test setting the system property (-Dsun.cds.enableSharedLookupCache=true) and continue to load class A and B. Removing line 44-58 should do it and also no need to set -Dfoo.foo.bar. >>>>> >>>> Do you mean change the test to call System.setProperty("sun.cds.enableSharedLookupCache", "true")? >>>> >>>> But we know that the property is checked only once, before any app classes are loaded. So calling System.setProperty in an application class won't test anything. >>>>> It'd be good if you run this test and turn on the debug traces to make sure that the application class loader and ext class loader will start up with the lookup cache enabled and make up call to the VM. As it doesn't have the app cds archive, it will invalidate the cache right away and continue the class lookup with null cache array. >>>> In the latest code, if CDS is not available, lookupCacheEnabled will be set to false inside the static initializer of URLClassPath: >>>> >>>> private static volatile boolean lookupCacheEnabled >>>> = "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache")); >>>> >>>> later, when the boot/ext/app loaders call into here: >>>> >>>> synchronized void initLookupCache(ClassLoader loader) { >>>> if ((lookupCacheURLs = getLookupCacheURLs(loader)) != null) { >>>> lookupCacheLoader = loader; >>>> } else { >>>> // This JVM instance does not support lookup cache. >>>> disableAllLookupCaches(); >>>> } >>>> } >>>> >>>> their lookupCacheURLs[] fields will all be set to null. As a result, getLookupCacheForClassLoader and knownToNotExist0 will never be called. >>>> >>>> I can add a DEBUG_LOOKUP_CACHE trace inside disableAllLookupCaches to print "lookup cache disabled", and check for that in the test. Is this OK? >>>> >>>> Thanks >>>> - Ioi >>>> >>>> >>>> >>> > From karen.kinnear at oracle.com Wed Oct 29 14:16:08 2014 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Wed, 29 Oct 2014 10:16:08 -0400 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <54508B28.2000105@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544EF9A3.8090109@oracle.com> <544F1DCA.9040304@oracle.com> <253BAE47-9732-4085-A221-16285AA62782@oracle.com> <5450521F.2050609@oracle.com> <5450837F.6090802@oracle.com> <54508B28.2000105@oracle.com> Message-ID: <63D2F1B3-1F79-4624-BDF2-DF3EEAFAD479@oracle.com> Sorry, I was confused about who wrote what. Sounds like David and I are in agreement that you can remove the synchronization - I believe that would be much cleaner. And resolveClass does nothing and is final so no worries there. thanks, Karen On Oct 29, 2014, at 2:37 AM, David Holmes wrote: > On 29/10/2014 4:04 PM, Ioi Lam wrote: >> >> On 10/28/14, 7:34 PM, David Holmes wrote: >>> Hi Karen, >>> >>> I haven't been tracking the details of this and am unclear on the >>> overall caching strategy however ... >>> >>> On 29/10/2014 8:49 AM, Karen Kinnear wrote: >>>> Ioi, >>>> >>>> Looks good! Thanks to all who have contributed! >>>> >>>> A couple of minor comments/questions: >>>> >>>> 1. jvm.h (hotspot and jdk) >>>> All three APIs talk about loader_type, but the code uses loader. >>>> >>>> 2. Launcher.java >>>> To the best of my understanding - the call to findLoadedClass does >>>> not require synchronizing on the class loader lock, >>>> that is needed to ensure find/define atomicity - so that we do not >>>> call defineClass twice on the same class - i.e. in >>>> loadClass - it is needed around the findLoadedClass / >>>> findClass(defineClass) calls. This call is just a SystemDictionary >>>> lookup >>>> and does not require the lock to be held. >>> >>> If the class can be defined dynamically - which it appears it can >>> (though I'm not sure what that means) - then you can have a race >>> between the thread doing the defining and the thread doing the >>> findLoadedClass. By doing findLoadedClass with the lock held you >>> enforce some serialization of the actions, but there is still a race. >>> So the only way the lock could matter is if user code could trigger >>> the second thread's lookup of the class after the lock has been taken >>> by the thread doing the dynamic definition - whether that is possible >>> depends on what this dynamic definition actually is. >>> >> I copied the code from ClassLoader.loadClass, which does it it a >> synchronized block: > > >> class ClassLoader { >> protected Class loadClass(String name, boolean resolve) >> throws ClassNotFoundException >> { >> synchronized (getClassLoadingLock(name)) { >> // First, check if the class has already been loaded >> Class c = findLoadedClass(name); >> if (c == null) { >> long t0 = System.nanoTime(); >> try { >> if (parent != null) { >> c = parent.loadClass(name, false); >> } else { >> c = findBootstrapClassOrNull(name); >> } >> } catch (ClassNotFoundException e) { >> // ClassNotFoundException thrown if class not found >> // from the non-null parent class loader >> } >> >> if (c == null) { >> // If still not found, then invoke findClass in order >> // to find the class. >> long t1 = System.nanoTime(); >> c = findClass(name); >> >> // this is the defining class loader; record the stats >> sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); >> sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); >> sun.misc.PerfCounter.getFindClasses().increment(); >> } >> } >> if (resolve) { >> resolveClass(c); >> } >> return c; >> } >> } >> >> So I guess it should look like this in Launcher$AppClassLoader, just to >> ensure the same things are done (regardless of whether it's necessary or >> not)? > > In ClassLoader.loadClass it is providing atomicity across a number of actions in the worst-case: > - checking for already loaded; if not then > - try to load through parent; if not then > - findClass (which will do defineClass) > > You don't have those atomicity constraints because you are only doing one thing - checking to see if the class is loaded. > > Your locking is probably harmless but those are famous last words when it comes to classloading. :) > >> >> Does resolveClass need to be done inside the synchronized block? > > Depends on whether it depends on the classloader locking to prevent concurrent resolve attempts. > > David > ----- > >> class Launcher$AppClassLoader { >> public Class loadClass(String name, boolean resolve) >> throws ClassNotFoundException >> { >> int i = name.lastIndexOf('.'); >> if (i != -1) { >> SecurityManager sm = System.getSecurityManager(); >> if (sm != null) { >> sm.checkPackageAccess(name.substring(0, i)); >> } >> } >> >> if (ucp.knownToNotExist(name)) { >> // The class of the given name is not found in the parent >> // class loader as well as its local URLClassPath. >> // Check if this class has already been defined >> dynamically; >> // if so, return the loaded class; otherwise, skip the >> parent >> // delegation and findClass. >> >>from here >> * synchronized (getClassLoadingLock(name)) {** >> ** Class c = findLoadedClass(name);** >> ** if (c != null) {** >> ** if (resolve) {** >> ** resolveClass(c);** >> ** }** >> ** return c;** >> ** }** >> ** }* >> <> throw new ClassNotFoundException(name); >> } >> >> return (super.loadClass(name, resolve)); >> } >> >> Thanks >> - Ioi >> >> >>> David >>> >>>> David H and Mandy - does that make sense to you both? >>>> >>>> thanks, >>>> Karen >>>> >>>> On Oct 28, 2014, at 12:38 AM, Ioi Lam wrote: >>>> >>>>> >>>>> On 10/27/14, 7:04 PM, Mandy Chung wrote: >>>>>> >>>>>> On 10/27/2014 3:32 PM, Ioi Lam wrote: >>>>>>> Hi David, I have update the latest webrev at: >>>>>>> >>>>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ >>>>>>> >>>>>> >>>>>> The update looks good. Thanks. >>>>>> >>>>>>> This version also contains the JDK test case that Mandy requested: >>>>>>> >>>>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html >>>>>>> >>>>>>> >>>>>> >>>>>> What I request to add is a test setting the system property >>>>>> (-Dsun.cds.enableSharedLookupCache=true) and continue to load class >>>>>> A and B. Removing line 44-58 should do it and also no need to set >>>>>> -Dfoo.foo.bar. >>>>>> >>>>> Do you mean change the test to call >>>>> System.setProperty("sun.cds.enableSharedLookupCache", "true")? >>>>> >>>>> But we know that the property is checked only once, before any app >>>>> classes are loaded. So calling System.setProperty in an application >>>>> class won't test anything. >>>>>> It'd be good if you run this test and turn on the debug traces to >>>>>> make sure that the application class loader and ext class loader >>>>>> will start up with the lookup cache enabled and make up call to the >>>>>> VM. As it doesn't have the app cds archive, it will invalidate the >>>>>> cache right away and continue the class lookup with null cache array. >>>>> In the latest code, if CDS is not available, lookupCacheEnabled will >>>>> be set to false inside the static initializer of URLClassPath: >>>>> >>>>> private static volatile boolean lookupCacheEnabled >>>>> = >>>>> "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache")); >>>>> >>>>> later, when the boot/ext/app loaders call into here: >>>>> >>>>> synchronized void initLookupCache(ClassLoader loader) { >>>>> if ((lookupCacheURLs = getLookupCacheURLs(loader)) != null) { >>>>> lookupCacheLoader = loader; >>>>> } else { >>>>> // This JVM instance does not support lookup cache. >>>>> disableAllLookupCaches(); >>>>> } >>>>> } >>>>> >>>>> their lookupCacheURLs[] fields will all be set to null. As a result, >>>>> getLookupCacheForClassLoader and knownToNotExist0 will never be called. >>>>> >>>>> I can add a DEBUG_LOOKUP_CACHE trace inside disableAllLookupCaches >>>>> to print "lookup cache disabled", and check for that in the test. Is >>>>> this OK? >>>>> >>>>> Thanks >>>>> - Ioi >>>>> >>>>> >>>>> >>>> >> From konstantin.shefov at oracle.com Wed Oct 29 14:25:40 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Wed, 29 Oct 2014 17:25:40 +0300 Subject: [9] Review request : JDK-8059070: [TESTBUG] java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java failed - timeout In-Reply-To: <544E1B65.1090400@oracle.com> References: <543D1DEE.8030206@oracle.com> <543F8520.9090408@oracle.com> <8F9DD322-1793-4739-8155-61CE7D2C5AAB@oracle.com> <543F9800.7040406@oracle.com> <543FC71F.8020504@oracle.com> <5440E39C.8070001@oracle.com> <5448E5A2.9030804@oracle.com> <544E1B65.1090400@oracle.com> Message-ID: <5450F8E4.2060808@oracle.com> Please, review a test bug fix. http://cr.openjdk.java.net/~kshefov/8059070/webrev.01/ -Konstantin On 27.10.2014 13:16, Konstantin Shefov wrote: > Kindly reminder > > On 23.10.2014 19:04, Paul Sandoz wrote: >> On Oct 23, 2014, at 1:25 PM, Konstantin Shefov >> wrote: >>> Gently reminder >>> >>> On 17.10.2014 13:38, Konstantin Shefov wrote: >>>> Hi, >>>> >>>> I have updated the webrev: >>>> http://cr.openjdk.java.net/~kshefov/8059070/webrev.01/ >>>> >> +1 >> >> Sorry for the delay, >> Paul. > From vladimir.x.ivanov at oracle.com Wed Oct 29 14:06:34 2014 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Wed, 29 Oct 2014 18:06:34 +0400 Subject: [9] [8u40] RFR (M): 8059877: GWT branch frequencies pollution due to LF sharing In-Reply-To: <5D2610C2-4DC6-4703-BE08-2CFF7CA12369@oracle.com> References: <54382E90.7040105@oracle.com> <03B32851-A9DB-4C43-ABB3-2CFE36D7CB0C@oracle.com> <543D717C.3090508@oracle.com> <0F6750AB-3949-4E5A-B67B-1FA1A10E5CA2@oracle.com> <543E90E0.6080200@oracle.com> <95EF0781-6DCB-4294-912A-25C61912F8B9@oracle.com> <544FE8CF.6050003@oracle.com> <5D2610C2-4DC6-4703-BE08-2CFF7CA12369@oracle.com> Message-ID: <5450F46A.3000708@oracle.com> Thanks, John. Best regards, Vladimir Ivanov On 10/29/14, 12:21 AM, John Rose wrote: > Good, I'm happy. Reviewed. ? John > > On Oct 28, 2014, at 12:04 PM, Vladimir Ivanov > > wrote: > >> John, thanks for the feedback! >> See my answers inline. > From peter.levart at gmail.com Wed Oct 29 17:16:02 2014 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 29 Oct 2014 18:16:02 +0100 Subject: Loading classes with many methods is very expensive In-Reply-To: References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <5450CEE9.7060707@gmail.com> Message-ID: <545120D2.5010301@gmail.com> On 10/29/2014 02:08 PM, Joel Borggr?n-Franck wrote: > Hi Peter, > > I?m not entirely convinced this is a bug. > > The lookup order for getMethod has for a long time been walk up superclasses and return what you find there first without even looking at interfaces. It might be desirable to change that but I?m not sure. Hi Joel, It has been for a long time like that as you say, but for a long time Java did not have default methods. It's unexpected for getMethod() to return a method that is not contained in getMethods() result. Anyway, I have created a bug to track this: https://bugs.openjdk.java.net/browse/JDK-8062389 For next iteration of the getMethods() O(n^2) fix, I used a slightly different approach, which you might like more or not. Instead of using linked-lists of Method objects as values of a LinkedHashMap I created a special Key object, holding a reference to Method object and an additional 'seq' int field, which discriminates among methods with same signature. Values of LinkedHashMap are Method objects themselves: http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.03/ I have encapsulated this functionality into a package-private java.lang.MethodTable. The implementation of this API can be easily changed to using linked-lists as values of LinkedHashMap if desired. The performance characteristics are similar, with hardly measurable advantage of this latest approach as can be seen from http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/GetAllRtMethods.java benchmark: Original code: 19658 classes loaded in 2.071013902 seconds. 494392 methods obtained in 1.089983418 seconds. 494392 methods obtained in 0.952488497 seconds. 494392 methods obtained in 0.912878317 seconds. 494392 methods obtained in 0.940293784 seconds. 494392 methods obtained in 0.987640733 seconds. 494392 methods obtained in 0.925393355 seconds. 494392 methods obtained in 0.89397002 seconds. 494392 methods obtained in 0.915042463 seconds. 494392 methods obtained in 0.897669082 seconds. 494392 methods obtained in 0.878140502 seconds. Patched code: 19658 classes loaded in 2.153024197 seconds. 494392 methods obtained in 0.875651469 seconds. 494392 methods obtained in 0.791937742 seconds. 494392 methods obtained in 0.780995693 seconds. 494392 methods obtained in 0.759593461 seconds. 494392 methods obtained in 0.766528355 seconds. 494392 methods obtained in 0.756567663 seconds. 494392 methods obtained in 0.739177848 seconds. 494392 methods obtained in 0.729245613 seconds. 494392 methods obtained in 0.74081083 seconds. 494392 methods obtained in 0.731749505 seconds. Martin's ManyMethodsBenchmark shows this algorithm has O(n) time complexity too: Original: Base class load time: 131.95 ms getDeclaredMethods: 65521 methods, 32.00 ms total time, 0.0005 ms per method getMethods : 65530 methods, 44.24 ms total time, 0.0007 ms per method Derived class load time: 32525.23 ms getDeclaredMethods: 65521 methods, 30.37 ms total time, 0.0005 ms per method getMethods : 65530 methods, 7897.03 ms total time, 0.1205 ms per method Patched: Base class load time: 129.72 ms getDeclaredMethods: 65521 methods, 32.76 ms total time, 0.0005 ms per method getMethods : 65530 methods, 42.68 ms total time, 0.0007 ms per method Derived class load time: 31620.47 ms getDeclaredMethods: 65521 methods, 30.49 ms total time, 0.0005 ms per method getMethods : 65530 methods, 88.23 ms total time, 0.0013 ms per method I have also run Martin's LoadAllClassesAndMethods test (Thanks Martin, I changed it slightly so that exceptions are collected and reported at the end instead of bailing-out on first exception). Original LoadAllClassesAndMethods write classlist.txt: class load: 23052 classes, 1563.75 ms total time, 0.0678 ms per class 4 exceptions encountered: java.lang.IncompatibleClassChangeError: jdk.nashorn.internal.codegen.CompilationPhase$10 and jdk.nashorn.internal.codegen.CompilationPhase$10$1 disagree on InnerClasses attribute java.lang.IncompatibleClassChangeError: jdk.nashorn.internal.codegen.CompilationPhase$5 and jdk.nashorn.internal.codegen.CompilationPhase$5$1 disagree on InnerClasses attribute java.lang.IncompatibleClassChangeError: java.security.ProtectionDomain$3 and java.security.ProtectionDomain$3$1 disagree on InnerClasses attribute java.lang.IncompatibleClassChangeError: java.lang.Compiler and java.lang.Compiler$1 disagree on InnerClasses attribute getMethods: 23052 classes, 831.87 ms total time, 0.0361 ms per class Patched LoadAllClassesAndMethods diff classlist.txt: class load: 23051 classes, 1596.58 ms total time, 0.0693 ms per class 5 exceptions encountered: java.lang.IncompatibleClassChangeError: jdk.nashorn.internal.codegen.CompilationPhase$10 and jdk.nashorn.internal.codegen.CompilationPhase$10$1 disagree on InnerClasses attribute java.lang.IncompatibleClassChangeError: jdk.nashorn.internal.codegen.CompilationPhase$5 and jdk.nashorn.internal.codegen.CompilationPhase$5$1 disagree on InnerClasses attribute java.lang.IncompatibleClassChangeError: java.lang.Class and java.lang.Class$MethodArray disagree on InnerClasses attribute java.lang.IncompatibleClassChangeError: java.security.ProtectionDomain$3 and java.security.ProtectionDomain$3$1 disagree on InnerClasses attribute java.lang.IncompatibleClassChangeError: java.lang.Compiler and java.lang.Compiler$1 disagree on InnerClasses attribute getMethods: 23051 classes, 799.99 ms total time, 0.0347 ms per class The following classes were expected, but not found: [java.lang.Class$MethodArray] The reason for Class$MethodArray to not be loaded by patched code is the way I tested patched j.l.Class. I prepended the boot classpath with a directory holding patched Class/MethodTable. Martin's LoadAllClassesAndMethods tries to load Class$MethodArray anyway, since it's in rt.jar, but this class is gone in patched j.l.Class, so "IncompatibleClassChangeError: java.lang.Class and java.lang.Class$MethodArray disagree on InnerClasses attribute" is expected in this case. Otherwise this test shows that original and patched code agree on results returned from getMethods() for all system and extension JDK classes. All 86 jtreg tests in java/lang/Class/ and java/lang/reflect/ pass. I still have to create a test case for inconsistency I discovered in previous iteration. Regards, Peter > > cheers > /Joel > > On 29 okt 2014, at 12:26, Peter Levart wrote: > >> Hi Joel, >> >> I found an inconsistency between getMethod() and getMethods() results that is present in current JDK8/9 code and in my latest webrev.02. The following program: >> >> import java.util.stream.Collectors; >> import java.util.stream.Stream; >> >> public class GetMethodTest { >> >> static void test(Class clazz) throws Exception { >> >> System.out.println(clazz.getName() + ".class.getMethods(): " + >> Stream >> .of(clazz.getMethods()) >> .filter(m -> m.getDeclaringClass() != Object.class) >> .collect(Collectors.toList())); >> >> System.out.println(clazz.getName() + ".class.getMethod(\"m\"): " + >> clazz.getMethod("m")); >> >> System.out.println(); >> } >> >> public static void main(String[] args) throws Exception { >> test(I.class); >> test(J.class); >> test(A.class); >> test(B.class); >> } >> } >> >> interface I { >> void m(); >> } >> >> interface J extends I { >> default void m() {} >> } >> >> abstract class A implements I {} >> >> abstract class B extends A implements J {} >> >> >> prints: >> >> I.class.getMethods(): [public abstract void I.m()] >> I.class.getMethod("m"): public abstract void I.m() >> >> J.class.getMethods(): [public default void J.m()] >> J.class.getMethod("m"): public default void J.m() >> >> A.class.getMethods(): [public abstract void I.m()] >> A.class.getMethod("m"): public abstract void I.m() >> >> B.class.getMethods(): [public default void J.m()] >> B.class.getMethod("m"): public abstract void I.m() >> >> B.class.getMethods() reports default method J.m() (which I think is correct), but B.class.getMethod("m") reports the abstract I.m() inherited from A, because here the getMethod0() algorithm stops searching for and consolidating any methods in (super)interfaces. Do you agree that this is a bug? >> >> >> Regards, Peter >> >> On 10/27/2014 02:45 PM, Joel Borggr?n-Franck wrote: >>> Hi Peter, >>> >>> As always, thanks for doing this! It has been on my todolist for a while but never quite bubbling up to the top. >>> >>> I don?t have time to look att his right now, but I expect to have some free time next week, but i have two short comments >>> >>> First, I have been thinking about moving MethodArray to its?s own top-level class, isn?t it about time? >>> >>> Second I would expect testing for the missing cases you uncovered (good catch!). >>> >>> I?ll try to get back to you asap. >>> >>> cheers >>> /Joel >>> >>> >>> On 26 okt 2014, at 23:53, Peter Levart wrote: >>> >>>> On 10/26/2014 09:25 PM, Peter Levart wrote: >>>>> 19657 classes loaded in 1.987373401 seconds. >>>>> 494141 methods obtained in 1.02493941 seconds. >>>>> >>>>> vs. >>>>> >>>>> 19657 classes loaded in 2.084409717 seconds. >>>>> 494124 methods obtained in 0.915928578 seconds. >>>> Hi, >>>> >>>> As you might have noticed, the number of methods obtained from patched code differed from original code. I have investigated this and found that original code treats abstract class methods the same as abstract interface methods as far as multiple inheritance is concerned (it keeps them together in the returned array). So I fixed this and here's new webrev which behaves the same as original code: >>>> >>>> http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.02/ >>>> >>>> Comparing original vs. patched code still shows speed-up: >>>> >>>> Original: >>>> >>>> 19657 classes loaded in 1.980493029 seconds. >>>> 494141 methods obtained in 0.976318927 seconds. >>>> 494141 methods obtained in 0.886504437 seconds. >>>> 494141 methods obtained in 0.911153722 seconds. >>>> 494141 methods obtained in 0.880550509 seconds. >>>> 494141 methods obtained in 0.875526704 seconds. >>>> 494141 methods obtained in 0.877258894 seconds. >>>> 494141 methods obtained in 0.871794344 seconds. >>>> 494141 methods obtained in 0.884159644 seconds. >>>> 494141 methods obtained in 0.892648522 seconds. >>>> 494141 methods obtained in 0.884581841 seconds. >>>> >>>> Patched: >>>> >>>> 19657 classes loaded in 2.055697675 seconds. >>>> 494141 methods obtained in 0.853922188 seconds. >>>> 494141 methods obtained in 0.776203794 seconds. >>>> 494141 methods obtained in 0.858774803 seconds. >>>> 494141 methods obtained in 0.778178867 seconds. >>>> 494141 methods obtained in 0.760043997 seconds. >>>> 494141 methods obtained in 0.756352444 seconds. >>>> 494141 methods obtained in 0.740826372 seconds. >>>> 494141 methods obtained in 0.744264782 seconds. >>>> 494141 methods obtained in 0.73805894 seconds. >>>> 494141 methods obtained in 0.746852752 seconds. >>>> >>>> >>>> 55 java/lang/reflect jtreg tests still pass. As they did before, which means that we don't have a coverage for such cases. I'll see where I can add such a case (EnumSet for example, which inherits from Set interface and AbstractColection class via two different paths, so Set.size()/iterator() and AbstractCollection.size()/iterator() are both returned from getMethods())... >>>> >>>> >>>> Regards, Peter >>>> From mandy.chung at oracle.com Wed Oct 29 19:10:18 2014 From: mandy.chung at oracle.com (Mandy Chung) Date: Wed, 29 Oct 2014 12:10:18 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <63D2F1B3-1F79-4624-BDF2-DF3EEAFAD479@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544EF9A3.8090109@oracle.com> <544F1DCA.9040304@oracle.com> <253BAE47-9732-4085-A221-16285AA62782@oracle.com> <5450521F.2050609@oracle.com> <5450837F.6090802@oracle.com> <54508B28.2000105@oracle.com> <63D2F1B3-1F79-4624-BDF2-DF3EEAFAD479@oracle.com> Message-ID: <54513B9A.9010606@oracle.com> On 10/29/2014 7:16 AM, Karen Kinnear wrote: > Sorry, I was confused about who wrote what. > > Sounds like David and I are in agreement that you can remove the synchronization - I believe that would be much cleaner. I agree that the class loader lock is not really needed in the knownToNotExist case as it's checking if the class is loaded or not. Good catch, Karen. Mandy > And resolveClass does nothing and is final so no worries there. > > thanks, > Karen > > On Oct 29, 2014, at 2:37 AM, David Holmes wrote: > >> On 29/10/2014 4:04 PM, Ioi Lam wrote: >>> On 10/28/14, 7:34 PM, David Holmes wrote: >>>> Hi Karen, >>>> >>>> I haven't been tracking the details of this and am unclear on the >>>> overall caching strategy however ... >>>> >>>> On 29/10/2014 8:49 AM, Karen Kinnear wrote: >>>>> Ioi, >>>>> >>>>> Looks good! Thanks to all who have contributed! >>>>> >>>>> A couple of minor comments/questions: >>>>> >>>>> 1. jvm.h (hotspot and jdk) >>>>> All three APIs talk about loader_type, but the code uses loader. >>>>> >>>>> 2. Launcher.java >>>>> To the best of my understanding - the call to findLoadedClass does >>>>> not require synchronizing on the class loader lock, >>>>> that is needed to ensure find/define atomicity - so that we do not >>>>> call defineClass twice on the same class - i.e. in >>>>> loadClass - it is needed around the findLoadedClass / >>>>> findClass(defineClass) calls. This call is just a SystemDictionary >>>>> lookup >>>>> and does not require the lock to be held. >>>> If the class can be defined dynamically - which it appears it can >>>> (though I'm not sure what that means) - then you can have a race >>>> between the thread doing the defining and the thread doing the >>>> findLoadedClass. By doing findLoadedClass with the lock held you >>>> enforce some serialization of the actions, but there is still a race. >>>> So the only way the lock could matter is if user code could trigger >>>> the second thread's lookup of the class after the lock has been taken >>>> by the thread doing the dynamic definition - whether that is possible >>>> depends on what this dynamic definition actually is. >>>> >>> I copied the code from ClassLoader.loadClass, which does it it a >>> synchronized block: >>> >>> class ClassLoader { >>> protected Class loadClass(String name, boolean resolve) >>> throws ClassNotFoundException >>> { >>> synchronized (getClassLoadingLock(name)) { >>> // First, check if the class has already been loaded >>> Class c = findLoadedClass(name); >>> if (c == null) { >>> long t0 = System.nanoTime(); >>> try { >>> if (parent != null) { >>> c = parent.loadClass(name, false); >>> } else { >>> c = findBootstrapClassOrNull(name); >>> } >>> } catch (ClassNotFoundException e) { >>> // ClassNotFoundException thrown if class not found >>> // from the non-null parent class loader >>> } >>> >>> if (c == null) { >>> // If still not found, then invoke findClass in order >>> // to find the class. >>> long t1 = System.nanoTime(); >>> c = findClass(name); >>> >>> // this is the defining class loader; record the stats >>> sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); >>> sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); >>> sun.misc.PerfCounter.getFindClasses().increment(); >>> } >>> } >>> if (resolve) { >>> resolveClass(c); >>> } >>> return c; >>> } >>> } >>> >>> So I guess it should look like this in Launcher$AppClassLoader, just to >>> ensure the same things are done (regardless of whether it's necessary or >>> not)? >> In ClassLoader.loadClass it is providing atomicity across a number of actions in the worst-case: >> - checking for already loaded; if not then >> - try to load through parent; if not then >> - findClass (which will do defineClass) >> >> You don't have those atomicity constraints because you are only doing one thing - checking to see if the class is loaded. >> >> Your locking is probably harmless but those are famous last words when it comes to classloading. :) >> >>> Does resolveClass need to be done inside the synchronized block? >> Depends on whether it depends on the classloader locking to prevent concurrent resolve attempts. >> >> David >> ----- >> >>> class Launcher$AppClassLoader { >>> public Class loadClass(String name, boolean resolve) >>> throws ClassNotFoundException >>> { >>> int i = name.lastIndexOf('.'); >>> if (i != -1) { >>> SecurityManager sm = System.getSecurityManager(); >>> if (sm != null) { >>> sm.checkPackageAccess(name.substring(0, i)); >>> } >>> } >>> >>> if (ucp.knownToNotExist(name)) { >>> // The class of the given name is not found in the parent >>> // class loader as well as its local URLClassPath. >>> // Check if this class has already been defined >>> dynamically; >>> // if so, return the loaded class; otherwise, skip the >>> parent >>> // delegation and findClass. >>>> >from here >>> * synchronized (getClassLoadingLock(name)) {** >>> ** Class c = findLoadedClass(name);** >>> ** if (c != null) {** >>> ** if (resolve) {** >>> ** resolveClass(c);** >>> ** }** >>> ** return c;** >>> ** }** >>> ** }* >>> <>> throw new ClassNotFoundException(name); >>> } >>> >>> return (super.loadClass(name, resolve)); >>> } >>> >>> Thanks >>> - Ioi >>> >>> >>>> David >>>> >>>>> David H and Mandy - does that make sense to you both? >>>>> >>>>> thanks, >>>>> Karen >>>>> >>>>> On Oct 28, 2014, at 12:38 AM, Ioi Lam wrote: >>>>> >>>>>> On 10/27/14, 7:04 PM, Mandy Chung wrote: >>>>>>> On 10/27/2014 3:32 PM, Ioi Lam wrote: >>>>>>>> Hi David, I have update the latest webrev at: >>>>>>>> >>>>>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ >>>>>>>> >>>>>>> The update looks good. Thanks. >>>>>>> >>>>>>>> This version also contains the JDK test case that Mandy requested: >>>>>>>> >>>>>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html >>>>>>>> >>>>>>>> >>>>>>> What I request to add is a test setting the system property >>>>>>> (-Dsun.cds.enableSharedLookupCache=true) and continue to load class >>>>>>> A and B. Removing line 44-58 should do it and also no need to set >>>>>>> -Dfoo.foo.bar. >>>>>>> >>>>>> Do you mean change the test to call >>>>>> System.setProperty("sun.cds.enableSharedLookupCache", "true")? >>>>>> >>>>>> But we know that the property is checked only once, before any app >>>>>> classes are loaded. So calling System.setProperty in an application >>>>>> class won't test anything. >>>>>>> It'd be good if you run this test and turn on the debug traces to >>>>>>> make sure that the application class loader and ext class loader >>>>>>> will start up with the lookup cache enabled and make up call to the >>>>>>> VM. As it doesn't have the app cds archive, it will invalidate the >>>>>>> cache right away and continue the class lookup with null cache array. >>>>>> In the latest code, if CDS is not available, lookupCacheEnabled will >>>>>> be set to false inside the static initializer of URLClassPath: >>>>>> >>>>>> private static volatile boolean lookupCacheEnabled >>>>>> = >>>>>> "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache")); >>>>>> >>>>>> later, when the boot/ext/app loaders call into here: >>>>>> >>>>>> synchronized void initLookupCache(ClassLoader loader) { >>>>>> if ((lookupCacheURLs = getLookupCacheURLs(loader)) != null) { >>>>>> lookupCacheLoader = loader; >>>>>> } else { >>>>>> // This JVM instance does not support lookup cache. >>>>>> disableAllLookupCaches(); >>>>>> } >>>>>> } >>>>>> >>>>>> their lookupCacheURLs[] fields will all be set to null. As a result, >>>>>> getLookupCacheForClassLoader and knownToNotExist0 will never be called. >>>>>> >>>>>> I can add a DEBUG_LOOKUP_CACHE trace inside disableAllLookupCaches >>>>>> to print "lookup cache disabled", and check for that in the test. Is >>>>>> this OK? >>>>>> >>>>>> Thanks >>>>>> - Ioi >>>>>> >>>>>> >>>>>> From joel.franck at oracle.com Wed Oct 29 19:25:04 2014 From: joel.franck at oracle.com (=?windows-1252?Q?Joel_Borggr=E9n-Franck?=) Date: Wed, 29 Oct 2014 20:25:04 +0100 Subject: inconsistency between Class.getMethod and Class.getMethods Was: Loading classes with many methods is very expensive In-Reply-To: <545120D2.5010301@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <5450CEE9.7060707@gmail.com> <545120D2.5010301@gmail.com> Message-ID: <8B22D8B3-4122-451C-A8D7-D95B51B45A94@oracle.com> Hi Peter, On 29 Oct 2014, at 18:16, Peter Levart wrote: > On 10/29/2014 02:08 PM, Joel Borggr?n-Franck wrote: >> Hi Peter, >> >> I?m not entirely convinced this is a bug. >> >> The lookup order for getMethod has for a long time been walk up superclasses and return what you find there first without even looking at interfaces. It might be desirable to change that but I?m not sure. > > Hi Joel, > > It has been for a long time like that as you say, but for a long time Java did not have default methods. It's unexpected for getMethod() to return a method that is not contained in getMethods() result. > > Anyway, I have created a bug to track this: > > https://bugs.openjdk.java.net/browse/JDK-8062389 Thanks. For the record I don?t necessarily disagree, I just haven?t had time to research this yet. I think this is a subset of https://bugs.openjdk.java.net/browse/JDK-8029459 but might also be worth changing separately in 9. If it is a bug, it might not be worth fixing in 8u. cheers /Joel From martinrb at google.com Wed Oct 29 20:12:06 2014 From: martinrb at google.com (Martin Buchholz) Date: Wed, 29 Oct 2014 13:12:06 -0700 Subject: Losing features of JVM_Open, e.g. CLOEXEC Message-ID: Hi guys, In your change 8057777: Cleanup of old and unused VM interfaces you have made changes like this: - zfd = JVM_Open(path, flag, 0); + zfd = open(path, flag, 0); throwing away use of old shared infrastructure and replacing with "naked" calls to the OS. Although understandable, this abandons benefits of using shared infrastructure. Here I'm thinking of the close-on-exec flag. I just added use of O_CLOEXEC to linux hotspot, but e.g. zip file opening no longer uses JVM_Open, which is a code hygiene regression. What we want is to have almost all file descriptors have the close-on-exec flag automatically set at fd creation time, using O_CLOEXEC where available, and FD_CLOEXEC where not. How do we get there? I'm distressed that the JDK core libraries should be moving towards having *more* shared native code infrastructure, but here we seem to be moving in the opposite direction. Having abandoned JVM_Open, the responsibility of doing these things right belongs entirely to the core libraries team. So where's the core-library replacement for JVM_Open? I'll quote from os::open: // All file descriptors that are opened in the Java process and not // specifically destined for a subprocess should have the close-on-exec // flag set. If we don't set it, then careless 3rd party native code // might fork and exec without closing all appropriate file descriptors // (e.g. as we do in closeDescriptors in UNIXProcess.c), and this in // turn might: // // - cause end-of-file to fail to be detected on some file // descriptors, resulting in mysterious hangs, or // // - might cause an fopen in the subprocess to fail on a system // suffering from bug 1085341. // // (Yes, the default setting of the close-on-exec flag is a Unix // design flaw) // // See: // 1085341: 32-bit stdio routines should support file descriptors >255 // 4843136: (process) pipe file descriptor from Runtime.exec not being closed // 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9 // // Modern Linux kernels (after 2.6.23 2007) support O_CLOEXEC with open(). // O_CLOEXEC is preferable to using FD_CLOEXEC on an open file descriptor // because it saves a system call and removes a small window where the flag // is unset. On ancient Linux kernels the O_CLOEXEC flag will be ignored // and we fall back to using FD_CLOEXEC (see below). #ifdef O_CLOEXEC oflag |= O_CLOEXEC; #endif From christos at zoulas.com Wed Oct 29 20:46:40 2014 From: christos at zoulas.com (Christos Zoulas) Date: Wed, 29 Oct 2014 16:46:40 -0400 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: from Martin Buchholz (Oct 29, 1:12pm) Message-ID: <20141029204640.9995417FDA3@rebar.astron.com> On Oct 29, 1:12pm, martinrb at google.com (Martin Buchholz) wrote: -- Subject: Losing features of JVM_Open, e.g. CLOEXEC | throwing away use of old shared infrastructure and replacing with "naked" | calls to the OS. Although understandable, this abandons benefits of using | shared infrastructure. Here I'm thinking of the close-on-exec flag. I | just added use of O_CLOEXEC to linux hotspot, but e.g. zip file opening no | longer uses JVM_Open, which is a code hygiene regression. | | What we want is to have almost all file descriptors have the close-on-exec | flag automatically set at fd creation time, using O_CLOEXEC where | available, and FD_CLOEXEC where not. How do we get there? | | I'm distressed that the JDK core libraries should be moving towards having | *more* shared native code infrastructure, but here we seem to be moving in | the opposite direction. Having abandoned JVM_Open, the responsibility of | doing these things right belongs entirely to the core libraries team. So | where's the core-library replacement for JVM_Open? I totally agree with Martin here. Changes like this are harmful. christos From neugens.limasoftware at gmail.com Wed Oct 29 21:15:52 2014 From: neugens.limasoftware at gmail.com (Mario Torre) Date: Wed, 29 Oct 2014 22:15:52 +0100 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: <20141029204640.9995417FDA3@rebar.astron.com> References: <20141029204640.9995417FDA3@rebar.astron.com> Message-ID: +1 We should have spotted it in the review though. Cheers, Mario Il 29/ott/2014 21:47 "Christos Zoulas" ha scritto: > On Oct 29, 1:12pm, martinrb at google.com (Martin Buchholz) wrote: > -- Subject: Losing features of JVM_Open, e.g. CLOEXEC > > | throwing away use of old shared infrastructure and replacing with "naked" > | calls to the OS. Although understandable, this abandons benefits of > using > | shared infrastructure. Here I'm thinking of the close-on-exec flag. I > | just added use of O_CLOEXEC to linux hotspot, but e.g. zip file opening > no > | longer uses JVM_Open, which is a code hygiene regression. > | > | What we want is to have almost all file descriptors have the > close-on-exec > | flag automatically set at fd creation time, using O_CLOEXEC where > | available, and FD_CLOEXEC where not. How do we get there? > | > | I'm distressed that the JDK core libraries should be moving towards > having > | *more* shared native code infrastructure, but here we seem to be moving > in > | the opposite direction. Having abandoned JVM_Open, the responsibility of > | doing these things right belongs entirely to the core libraries team. So > | where's the core-library replacement for JVM_Open? > > I totally agree with Martin here. Changes like this are harmful. > > christos > From huizhe.wang at oracle.com Wed Oct 29 21:37:43 2014 From: huizhe.wang at oracle.com (huizhe wang) Date: Wed, 29 Oct 2014 14:37:43 -0700 Subject: RFR 7156085: ArrayIndexOutOfBoundsException throws in UTF8Reader of SAXParser In-Reply-To: References: Message-ID: <54515E27.9060403@oracle.com> Hi Martin, You're welcome in the jaxp land :-) Bandaid is what we need for now. There are many things we would like to do to this aging code base, unfortunately, we have to focus on a few. The change looks okay. I did a full-test run and saw no failures. One thing to note is that the SQE team has been working on migrating jaxp unit and functional tests into the jaxp repo. Before that's done, we should continue putting unit tests in jdk/test. I've moved your test to jdk/test and also removed a few unused imports. http://cr.openjdk.java.net/~joehw/jdk9/7156085/webrev/ I saw that you included a license header in the test that had a structure like: Google copyright + GNU GPL. I saw that you've already done it before (e.g. JDK-8058520). I don't have a problem with the lic header itself. But I'd like to know that the License Structure was approved by legal. Has it been approved? Thanks, Joe On 10/28/2014 3:49 PM, Martin Buchholz wrote: > Hi Joe, > > I'd like you to do a code review. > > http://cr.openjdk.java.net/~martin/webrevs/openjdk9/xerces-UTF8Reader-supplementary-characters/ > https://bugs.openjdk.java.net/browse/JDK-7156085#comment-13569882 > https://issues.apache.org/jira/browse/XERCESJ-1257 > > As usual, I don't know what I'm doing in jaxp land. > This bug should be fixed in both upstream xerces and in openjdk's copy. > Probably the xerces private UTF8 decoder should be thrown out, but I'm > only trying to bandaid the code here. From martinrb at google.com Wed Oct 29 22:59:00 2014 From: martinrb at google.com (Martin Buchholz) Date: Wed, 29 Oct 2014 15:59:00 -0700 Subject: RFR 7156085: ArrayIndexOutOfBoundsException throws in UTF8Reader of SAXParser In-Reply-To: <54515E27.9060403@oracle.com> References: <54515E27.9060403@oracle.com> Message-ID: On Wed, Oct 29, 2014 at 2:37 PM, huizhe wang wrote: > Hi Martin, > > You're welcome in the jaxp land :-) Bandaid is what we need for now. > There are many things we would like to do to this aging code base, > unfortunately, we have to focus on a few. > > The change looks okay. I did a full-test run and saw no failures. > > One thing to note is that the SQE team has been working on migrating jaxp > unit and functional tests into the jaxp repo. Before that's done, we should > continue putting unit tests in jdk/test. I've moved your test to jdk/test > and also removed a few unused imports. > > http://cr.openjdk.java.net/~joehw/jdk9/7156085/webrev/ > > Your re-shuffling of files in your webrev looks fine. Feel free to commit this change, (or I can do it) > I saw that you included a license header in the test that had a structure > like: Google copyright + GNU GPL. I saw that you've already done it before > (e.g. JDK-8058520). I don't have a problem with the lic header itself. But > I'd like to know that the License Structure was approved by legal. Has it > been approved? > yes, this is what new files contributed by Google have looked like for many years. From stanimir at riflexo.com Wed Oct 29 23:00:20 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Thu, 30 Oct 2014 01:00:20 +0200 Subject: Loading classes with many methods is very expensive In-Reply-To: <545120D2.5010301@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <5450CEE9.7060707@gmail.com> <545120D2.5010301@gmail.com> Message-ID: Hi Peter, The removal of value wrapper is a clever approach to reduce the new instances created although it feels very unnatural (at least to me). Small optimization; eagerly calculate the hash in the c'tor, hash = 149 method.getReturnType().hashCode() ^ 150 System.identityHashCode(method.getName()) ^ 151 Arrays.hashCode(method.getParameterTypes() and so the real int hashCode(){return seq+hash;} Also I am not sure if method.getName().hashCode() would be better or not, if previously identityHashCode is not invoked on that string and depending on the configured hashCode (-XX:hashCode) generator System.identityHashCode might be slow or worse call C random() which doesn't scale. Setting the hashCode requires a CAS too. CAS is of course one-time off but still About the order of the returned methods: if you remove and then put from/to the LHM the order of iteration is going to be greatly altered. Is that ok? Stanimir On Wed, Oct 29, 2014 at 7:16 PM, Peter Levart wrote: > On 10/29/2014 02:08 PM, Joel Borggr?n-Franck wrote: > >> Hi Peter, >> >> I'm not entirely convinced this is a bug. >> >> The lookup order for getMethod has for a long time been walk up >> superclasses and return what you find there first without even looking at >> interfaces. It might be desirable to change that but I'm not sure. >> > > Hi Joel, > > It has been for a long time like that as you say, but for a long time Java > did not have default methods. It's unexpected for getMethod() to return a > method that is not contained in getMethods() result. > > Anyway, I have created a bug to track this: > > https://bugs.openjdk.java.net/browse/JDK-8062389 > > For next iteration of the getMethods() O(n^2) fix, I used a slightly > different approach, which you might like more or not. Instead of using > linked-lists of Method objects as values of a LinkedHashMap I created a > special Key object, holding a reference to Method object and an additional > 'seq' int field, which discriminates among methods with same signature. > Values of LinkedHashMap are Method objects themselves: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.03/ > > I have encapsulated this functionality into a package-private > java.lang.MethodTable. The implementation of this API can be easily changed > to using linked-lists as values of LinkedHashMap if desired. The > performance characteristics are similar, with hardly measurable advantage > of this latest approach as can be seen from http://cr.openjdk.java.net/~ > plevart/jdk9-dev/Class.getMethods/GetAllRtMethods.java benchmark: > > Original code: > > 19658 classes loaded in 2.071013902 seconds. > 494392 methods obtained in 1.089983418 seconds. > 494392 methods obtained in 0.952488497 seconds. > 494392 methods obtained in 0.912878317 seconds. > 494392 methods obtained in 0.940293784 seconds. > 494392 methods obtained in 0.987640733 seconds. > 494392 methods obtained in 0.925393355 seconds. > 494392 methods obtained in 0.89397002 seconds. > 494392 methods obtained in 0.915042463 seconds. > 494392 methods obtained in 0.897669082 seconds. > 494392 methods obtained in 0.878140502 seconds. > > Patched code: > > 19658 classes loaded in 2.153024197 seconds. > 494392 methods obtained in 0.875651469 seconds. > 494392 methods obtained in 0.791937742 seconds. > 494392 methods obtained in 0.780995693 seconds. > 494392 methods obtained in 0.759593461 seconds. > 494392 methods obtained in 0.766528355 seconds. > 494392 methods obtained in 0.756567663 seconds. > 494392 methods obtained in 0.739177848 seconds. > 494392 methods obtained in 0.729245613 seconds. > 494392 methods obtained in 0.74081083 seconds. > 494392 methods obtained in 0.731749505 seconds. > > > Martin's ManyMethodsBenchmark shows this algorithm has O(n) time > complexity too: > > Original: > > Base class load time: 131.95 ms > getDeclaredMethods: 65521 methods, 32.00 ms total time, 0.0005 ms per > method > getMethods : 65530 methods, 44.24 ms total time, 0.0007 ms per > method > Derived class load time: 32525.23 ms > getDeclaredMethods: 65521 methods, 30.37 ms total time, 0.0005 ms per > method > getMethods : 65530 methods, 7897.03 ms total time, 0.1205 ms per > method > > Patched: > > Base class load time: 129.72 ms > getDeclaredMethods: 65521 methods, 32.76 ms total time, 0.0005 ms per > method > getMethods : 65530 methods, 42.68 ms total time, 0.0007 ms per > method > Derived class load time: 31620.47 ms > getDeclaredMethods: 65521 methods, 30.49 ms total time, 0.0005 ms per > method > getMethods : 65530 methods, 88.23 ms total time, 0.0013 ms per > method > > > I have also run Martin's LoadAllClassesAndMethods test (Thanks Martin, I > changed it slightly so that exceptions are collected and reported at the > end instead of bailing-out on first exception). > > Original LoadAllClassesAndMethods write classlist.txt: > > class load: 23052 classes, 1563.75 ms total time, 0.0678 ms per class > 4 exceptions encountered: > java.lang.IncompatibleClassChangeError: jdk.nashorn.internal.codegen.CompilationPhase$10 > and jdk.nashorn.internal.codegen.CompilationPhase$10$1 disagree on > InnerClasses attribute > java.lang.IncompatibleClassChangeError: jdk.nashorn.internal.codegen.CompilationPhase$5 > and jdk.nashorn.internal.codegen.CompilationPhase$5$1 disagree on > InnerClasses attribute > java.lang.IncompatibleClassChangeError: java.security.ProtectionDomain$3 > and java.security.ProtectionDomain$3$1 disagree on InnerClasses attribute > java.lang.IncompatibleClassChangeError: java.lang.Compiler and > java.lang.Compiler$1 disagree on InnerClasses attribute > getMethods: 23052 classes, 831.87 ms total time, 0.0361 ms per class > > Patched LoadAllClassesAndMethods diff classlist.txt: > > class load: 23051 classes, 1596.58 ms total time, 0.0693 ms per class > 5 exceptions encountered: > java.lang.IncompatibleClassChangeError: jdk.nashorn.internal.codegen.CompilationPhase$10 > and jdk.nashorn.internal.codegen.CompilationPhase$10$1 disagree on > InnerClasses attribute > java.lang.IncompatibleClassChangeError: jdk.nashorn.internal.codegen.CompilationPhase$5 > and jdk.nashorn.internal.codegen.CompilationPhase$5$1 disagree on > InnerClasses attribute > java.lang.IncompatibleClassChangeError: java.lang.Class and > java.lang.Class$MethodArray disagree on InnerClasses attribute > java.lang.IncompatibleClassChangeError: java.security.ProtectionDomain$3 > and java.security.ProtectionDomain$3$1 disagree on InnerClasses attribute > java.lang.IncompatibleClassChangeError: java.lang.Compiler and > java.lang.Compiler$1 disagree on InnerClasses attribute > getMethods: 23051 classes, 799.99 ms total time, 0.0347 ms per class > The following classes were expected, but not found: > [java.lang.Class$MethodArray] > > > The reason for Class$MethodArray to not be loaded by patched code is the > way I tested patched j.l.Class. I prepended the boot classpath with a > directory holding patched Class/MethodTable. Martin's > LoadAllClassesAndMethods tries to load Class$MethodArray anyway, since it's > in rt.jar, but this class is gone in patched j.l.Class, so > "IncompatibleClassChangeError: java.lang.Class and > java.lang.Class$MethodArray disagree on InnerClasses attribute" is expected > in this case. Otherwise this test shows that original and patched code > agree on results returned from getMethods() for all system and extension > JDK classes. > > All 86 jtreg tests in java/lang/Class/ and java/lang/reflect/ pass. > > I still have to create a test case for inconsistency I discovered in > previous iteration. > > Regards, Peter > > > > >> cheers >> /Joel >> >> On 29 okt 2014, at 12:26, Peter Levart wrote: >> >> Hi Joel, >>> >>> I found an inconsistency between getMethod() and getMethods() results >>> that is present in current JDK8/9 code and in my latest webrev.02. The >>> following program: >>> >>> import java.util.stream.Collectors; >>> import java.util.stream.Stream; >>> >>> public class GetMethodTest { >>> >>> static void test(Class clazz) throws Exception { >>> >>> System.out.println(clazz.getName() + ".class.getMethods(): " + >>> Stream >>> .of(clazz.getMethods()) >>> .filter(m -> m.getDeclaringClass() != >>> Object.class) >>> .collect(Collectors.toList())); >>> >>> System.out.println(clazz.getName() + ".class.getMethod(\"m\"): >>> " + >>> clazz.getMethod("m")); >>> >>> System.out.println(); >>> } >>> >>> public static void main(String[] args) throws Exception { >>> test(I.class); >>> test(J.class); >>> test(A.class); >>> test(B.class); >>> } >>> } >>> >>> interface I { >>> void m(); >>> } >>> >>> interface J extends I { >>> default void m() {} >>> } >>> >>> abstract class A implements I {} >>> >>> abstract class B extends A implements J {} >>> >>> >>> prints: >>> >>> I.class.getMethods(): [public abstract void I.m()] >>> I.class.getMethod("m"): public abstract void I.m() >>> >>> J.class.getMethods(): [public default void J.m()] >>> J.class.getMethod("m"): public default void J.m() >>> >>> A.class.getMethods(): [public abstract void I.m()] >>> A.class.getMethod("m"): public abstract void I.m() >>> >>> B.class.getMethods(): [public default void J.m()] >>> B.class.getMethod("m"): public abstract void I.m() >>> >>> B.class.getMethods() reports default method J.m() (which I think is >>> correct), but B.class.getMethod("m") reports the abstract I.m() inherited >>> from A, because here the getMethod0() algorithm stops searching for and >>> consolidating any methods in (super)interfaces. Do you agree that this is a >>> bug? >>> >>> >>> Regards, Peter >>> >>> On 10/27/2014 02:45 PM, Joel Borggr?n-Franck wrote: >>> >>>> Hi Peter, >>>> >>>> As always, thanks for doing this! It has been on my todolist for a >>>> while but never quite bubbling up to the top. >>>> >>>> I don't have time to look att his right now, but I expect to have some >>>> free time next week, but i have two short comments >>>> >>>> First, I have been thinking about moving MethodArray to its's own >>>> top-level class, isn't it about time? >>>> >>>> Second I would expect testing for the missing cases you uncovered (good >>>> catch!). >>>> >>>> I'll try to get back to you asap. >>>> >>>> cheers >>>> /Joel >>>> >>>> >>>> On 26 okt 2014, at 23:53, Peter Levart wrote: >>>> >>>> On 10/26/2014 09:25 PM, Peter Levart wrote: >>>>> >>>>>> 19657 classes loaded in 1.987373401 seconds. >>>>>> 494141 methods obtained in 1.02493941 seconds. >>>>>> >>>>>> vs. >>>>>> >>>>>> 19657 classes loaded in 2.084409717 seconds. >>>>>> 494124 methods obtained in 0.915928578 seconds. >>>>>> >>>>> Hi, >>>>> >>>>> As you might have noticed, the number of methods obtained from patched >>>>> code differed from original code. I have investigated this and found that >>>>> original code treats abstract class methods the same as abstract interface >>>>> methods as far as multiple inheritance is concerned (it keeps them together >>>>> in the returned array). So I fixed this and here's new webrev which behaves >>>>> the same as original code: >>>>> >>>>> http://cr.openjdk.java.net/~plevart/jdk9-dev/Class. >>>>> getMethods/webrev.02/ >>>>> >>>>> Comparing original vs. patched code still shows speed-up: >>>>> >>>>> Original: >>>>> >>>>> 19657 classes loaded in 1.980493029 seconds. >>>>> 494141 methods obtained in 0.976318927 seconds. >>>>> 494141 methods obtained in 0.886504437 seconds. >>>>> 494141 methods obtained in 0.911153722 seconds. >>>>> 494141 methods obtained in 0.880550509 seconds. >>>>> 494141 methods obtained in 0.875526704 seconds. >>>>> 494141 methods obtained in 0.877258894 seconds. >>>>> 494141 methods obtained in 0.871794344 seconds. >>>>> 494141 methods obtained in 0.884159644 seconds. >>>>> 494141 methods obtained in 0.892648522 seconds. >>>>> 494141 methods obtained in 0.884581841 seconds. >>>>> >>>>> Patched: >>>>> >>>>> 19657 classes loaded in 2.055697675 seconds. >>>>> 494141 methods obtained in 0.853922188 seconds. >>>>> 494141 methods obtained in 0.776203794 seconds. >>>>> 494141 methods obtained in 0.858774803 seconds. >>>>> 494141 methods obtained in 0.778178867 seconds. >>>>> 494141 methods obtained in 0.760043997 seconds. >>>>> 494141 methods obtained in 0.756352444 seconds. >>>>> 494141 methods obtained in 0.740826372 seconds. >>>>> 494141 methods obtained in 0.744264782 seconds. >>>>> 494141 methods obtained in 0.73805894 seconds. >>>>> 494141 methods obtained in 0.746852752 seconds. >>>>> >>>>> >>>>> 55 java/lang/reflect jtreg tests still pass. As they did before, which >>>>> means that we don't have a coverage for such cases. I'll see where I can >>>>> add such a case (EnumSet for example, which inherits from Set interface and >>>>> AbstractColection class via two different paths, so Set.size()/iterator() >>>>> and AbstractCollection.size()/iterator() are both returned from >>>>> getMethods())... >>>>> >>>>> >>>>> Regards, Peter >>>>> >>>>> > From huizhe.wang at oracle.com Wed Oct 29 23:09:00 2014 From: huizhe.wang at oracle.com (huizhe wang) Date: Wed, 29 Oct 2014 16:09:00 -0700 Subject: RFR 7156085: ArrayIndexOutOfBoundsException throws in UTF8Reader of SAXParser In-Reply-To: References: <54515E27.9060403@oracle.com> Message-ID: <5451738C.3030907@oracle.com> On 10/29/2014 3:59 PM, Martin Buchholz wrote: > > > On Wed, Oct 29, 2014 at 2:37 PM, huizhe wang > wrote: > > Hi Martin, > > You're welcome in the jaxp land :-) Bandaid is what we need for > now. There are many things we would like to do to this aging code > base, unfortunately, we have to focus on a few. > > The change looks okay. I did a full-test run and saw no failures. > > One thing to note is that the SQE team has been working on > migrating jaxp unit and functional tests into the jaxp repo. > Before that's done, we should continue putting unit tests in > jdk/test. I've moved your test to jdk/test and also removed a few > unused imports. > > http://cr.openjdk.java.net/~joehw/jdk9/7156085/webrev/ > > > > Your re-shuffling of files in your webrev looks fine. Feel free to > commit this change, (or I can do it) Please do. > I saw that you included a license header in the test that had a > structure like: Google copyright + GNU GPL. I saw that you've > already done it before (e.g. JDK-8058520). I don't have a problem > with the lic header itself. But I'd like to know that the License > Structure was approved by legal. Has it been approved? > > > yes, this is what new files contributed by Google have looked like for > many years. Awesome! Thanks, Joe From david.holmes at oracle.com Thu Oct 30 00:39:40 2014 From: david.holmes at oracle.com (David Holmes) Date: Thu, 30 Oct 2014 10:39:40 +1000 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: References: <20141029204640.9995417FDA3@rebar.astron.com> Message-ID: <545188CC.9030402@oracle.com> On 30/10/2014 7:15 AM, Mario Torre wrote: > +1 > > We should have spotted it in the review though. My thoughts exactly! Further only 2 calls were changed both in the zip code, while raw open is used in quite a number of other places in the JDK code. So while I can understand there may be a desire to add an abstraction layer where things like CLOEXEC can be added, I don't think the removal of JVM_Open can be considered a "lost feature". David > Cheers, > Mario > Il 29/ott/2014 21:47 "Christos Zoulas" ha scritto: > >> On Oct 29, 1:12pm, martinrb at google.com (Martin Buchholz) wrote: >> -- Subject: Losing features of JVM_Open, e.g. CLOEXEC >> >> | throwing away use of old shared infrastructure and replacing with "naked" >> | calls to the OS. Although understandable, this abandons benefits of >> using >> | shared infrastructure. Here I'm thinking of the close-on-exec flag. I >> | just added use of O_CLOEXEC to linux hotspot, but e.g. zip file opening >> no >> | longer uses JVM_Open, which is a code hygiene regression. >> | >> | What we want is to have almost all file descriptors have the >> close-on-exec >> | flag automatically set at fd creation time, using O_CLOEXEC where >> | available, and FD_CLOEXEC where not. How do we get there? >> | >> | I'm distressed that the JDK core libraries should be moving towards >> having >> | *more* shared native code infrastructure, but here we seem to be moving >> in >> | the opposite direction. Having abandoned JVM_Open, the responsibility of >> | doing these things right belongs entirely to the core libraries team. So >> | where's the core-library replacement for JVM_Open? >> >> I totally agree with Martin here. Changes like this are harmful. >> >> christos >> From stuart.marks at oracle.com Thu Oct 30 01:04:45 2014 From: stuart.marks at oracle.com (Stuart Marks) Date: Wed, 29 Oct 2014 18:04:45 -0700 Subject: RFR (s): 4354680: Runtime.runFinalization() silently clears interrupted flag in the calling thread Message-ID: <54518EAD.3060504@oracle.com> Hi all, Please review this small change that fixes this bug in System.runFinalization() and Runtime.runFinalization(). Bug: https://bugs.openjdk.java.net/browse/JDK-4354680 Webrev: http://cr.openjdk.java.net/~smarks/reviews/4354680/webrev.0/ This is probably the simplest approach, which is to reassert the interrupt bit if an InterruptedException is caught. I'm slightly concerned by this, though, since if the join() was interrupted (either because an interrupt was received while waiting to join the thread, or the caller's interrupt bit was set at the time join() was called), the method will return immediately, without waiting for pending objects to be finalized. This seems to violate the spirit (if not the letter) of this method's specification. This is the way runFinalization() has always behaved, though. The only difference with this change is that the interrupt bit is restored instead of being cleared. One could imagine an alternative approach which would loop until the secondary finalizer thread actually completes. However, it's hard for me to imagine any code relying on runFinalization() synchronously clearing the finalization queue. Since objects become finalizable asynchronously, how would the caller know that the "right" set of objects had been finalized? It seems to me that this isn't very useful, it's a change in behavior, and it's harder to test. If we don't wait for the secondary finalizer thread to complete, perhaps it would be appropriate to add a note to the doc about the early return in case of an interrupt. Perhaps something like, If the calling thread is interrupted before or during this call, this call may return before all outstanding finalizations have been completed, and the calling thread's interrupt status will be set. Would something like this be appropriate? Probably this would be added to both System.runFinalization() and Runtime.runFinalization(). s'marks From david.holmes at oracle.com Thu Oct 30 02:22:19 2014 From: david.holmes at oracle.com (David Holmes) Date: Thu, 30 Oct 2014 12:22:19 +1000 Subject: RFR (s): 4354680: Runtime.runFinalization() silently clears interrupted flag in the calling thread In-Reply-To: <54518EAD.3060504@oracle.com> References: <54518EAD.3060504@oracle.com> Message-ID: <5451A0DB.3030303@oracle.com> Hi Stuart, You're a brave man! :) On 30/10/2014 11:04 AM, Stuart Marks wrote: > Hi all, > > Please review this small change that fixes this bug in > System.runFinalization() and Runtime.runFinalization(). > > Bug: https://bugs.openjdk.java.net/browse/JDK-4354680 > > Webrev: http://cr.openjdk.java.net/~smarks/reviews/4354680/webrev.0/ > > This is probably the simplest approach, which is to reassert the > interrupt bit if an InterruptedException is caught. > > I'm slightly concerned by this, though, since if the join() was > interrupted (either because an interrupt was received while waiting to > join the thread, or the caller's interrupt bit was set at the time > join() was called), the method will return immediately, without waiting > for pending objects to be finalized. This seems to violate the spirit > (if not the letter) of this method's specification. > > This is the way runFinalization() has always behaved, though. The only > difference with this change is that the interrupt bit is restored > instead of being cleared. Right - there is no change in behaviour with your change other than fixing the problem with the cleared interrupt bit. That's the best you can do in my opinion. > One could imagine an alternative approach which would loop until the > secondary finalizer thread actually completes. However, it's hard for me > to imagine any code relying on runFinalization() synchronously clearing > the finalization queue. Since objects become finalizable asynchronously, > how would the caller know that the "right" set of objects had been > finalized? It seems to me that this isn't very useful, it's a change in > behavior, and it's harder to test. The spec of this method is weak enough: "When control returns from the method call, the virtual machine has made a best effort to complete all outstanding finalizations." that nobody should have any expectations about what a single invocation of it should achieve. At best they might argue that the VMs "best effort" was pretty poor, but I can live with that - plus it would be a distinct RFE not part of this bug fix. > If we don't wait for the secondary finalizer thread to complete, perhaps > it would be appropriate to add a note to the doc about the early return > in case of an interrupt. Perhaps something like, > > If the calling thread is interrupted before or during this call, > this call may return before all outstanding finalizations have been > completed, and the calling thread's interrupt status will be set. > > Would something like this be appropriate? Probably this would be added > to both System.runFinalization() and Runtime.runFinalization(). The fact a method is called that interacts with the interruption mechanism is purely an internal implementation detail. It should not bubble up to the specification of these methods. I don't see a need to document this aspect given the weakness of the spec as referenced above. That said it may be worth doing a search for all tests that use runFinalization to see how it is used. If used in a loop (which I suspect is common) and the test is timing out and so the thread is interrupted by the test harness, it will become a spin loop. Aside, I noticed in this code: 146 forkSecondaryFinalizer(new Runnable() { 147 private volatile boolean running; 148 public void run() { 149 if (running) 150 return; 151 final JavaLangAccess jla = SharedSecrets.getJavaLangAccess(); 152 running = true; that as we create a new Runnable on every call, the "running" field serves absolutely no purpose. Cheers, David > s'marks From roger.riggs at oracle.com Thu Oct 30 02:28:38 2014 From: roger.riggs at oracle.com (roger riggs) Date: Wed, 29 Oct 2014 22:28:38 -0400 Subject: RFR 9 8062513: doclint warnings in HijrahChronology Message-ID: <5451A256.1020608@oracle.com> Please review a correction to address a doclint warning in HijrahChronology. Webrev: http://cr.openjdk.java.net/~rriggs/webrev-doclint-8062513/ Issue: 8062513: doclint warnings in HijrahChronology Thanks, Roger From joe.darcy at oracle.com Wed Oct 29 20:40:51 2014 From: joe.darcy at oracle.com (joe darcy) Date: Wed, 29 Oct 2014 13:40:51 -0700 Subject: RFR 9 8062513: doclint warnings in HijrahChronology In-Reply-To: <5451A256.1020608@oracle.com> References: <5451A256.1020608@oracle.com> Message-ID: <545150D3.3080104@oracle.com> Looks good; thanks Roger, -Joe On 10/29/2014 7:28 PM, roger riggs wrote: > Please review a correction to address a doclint warning in > HijrahChronology. > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-doclint-8062513/ > > Issue: > 8062513: doclint warnings in HijrahChronology > > Thanks, Roger > From ioi.lam at oracle.com Thu Oct 30 05:26:01 2014 From: ioi.lam at oracle.com (Ioi Lam) Date: Wed, 29 Oct 2014 22:26:01 -0700 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <54513B9A.9010606@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544EF9A3.8090109@oracle.com> <544F1DCA.9040304@oracle.com> <253BAE47-9732-4085-A221-16285AA62782@oracle.com> <5450521F.2050609@oracle.com> <5450837F.6090802@oracle.com> <54508B28.2000105@oracle.com> <63D2F1B3-1F79-4624-BDF2-DF3EEAFAD479@oracle.com> <54513B9A.9010606@oracle.com> Message-ID: <5451CBE9.4020800@oracle.com> OK, here's the latest version. I removed the synchronization but kept the resolveClass just for completeness, even if it currently does nothing. class Launcher$AppClassLoader { .... public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { int i = name.lastIndexOf('.'); if (i != -1) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPackageAccess(name.substring(0, i)); } } if (ucp.knownToNotExist(name)) { // The class of the given name is not found in the parent // class loader as well as its local URLClassPath. // Check if this class has already been defined dynamically; // if so, return the loaded class; otherwise, skip the parent // delegation and findClass. Class c = findLoadedClass(name); if (c != null) { if (resolve) { resolveClass(c); } return c; } throw new ClassNotFoundException(name); } return (super.loadClass(name, resolve)); } Thanks - Ioi On 10/29/14, 12:10 PM, Mandy Chung wrote: > > On 10/29/2014 7:16 AM, Karen Kinnear wrote: >> Sorry, I was confused about who wrote what. >> >> Sounds like David and I are in agreement that you can remove the >> synchronization - I believe that would be much cleaner. > > I agree that the class loader lock is not really needed in > the knownToNotExist case as it's checking if the class is > loaded or not. Good catch, Karen. > > Mandy > >> And resolveClass does nothing and is final so no worries there. >> >> thanks, >> Karen >> >> On Oct 29, 2014, at 2:37 AM, David Holmes wrote: >> >>> On 29/10/2014 4:04 PM, Ioi Lam wrote: >>>> On 10/28/14, 7:34 PM, David Holmes wrote: >>>>> Hi Karen, >>>>> >>>>> I haven't been tracking the details of this and am unclear on the >>>>> overall caching strategy however ... >>>>> >>>>> On 29/10/2014 8:49 AM, Karen Kinnear wrote: >>>>>> Ioi, >>>>>> >>>>>> Looks good! Thanks to all who have contributed! >>>>>> >>>>>> A couple of minor comments/questions: >>>>>> >>>>>> 1. jvm.h (hotspot and jdk) >>>>>> All three APIs talk about loader_type, but the code uses loader. >>>>>> >>>>>> 2. Launcher.java >>>>>> To the best of my understanding - the call to findLoadedClass does >>>>>> not require synchronizing on the class loader lock, >>>>>> that is needed to ensure find/define atomicity - so that we do not >>>>>> call defineClass twice on the same class - i.e. in >>>>>> loadClass - it is needed around the findLoadedClass / >>>>>> findClass(defineClass) calls. This call is just a SystemDictionary >>>>>> lookup >>>>>> and does not require the lock to be held. >>>>> If the class can be defined dynamically - which it appears it can >>>>> (though I'm not sure what that means) - then you can have a race >>>>> between the thread doing the defining and the thread doing the >>>>> findLoadedClass. By doing findLoadedClass with the lock held you >>>>> enforce some serialization of the actions, but there is still a race. >>>>> So the only way the lock could matter is if user code could trigger >>>>> the second thread's lookup of the class after the lock has been taken >>>>> by the thread doing the dynamic definition - whether that is possible >>>>> depends on what this dynamic definition actually is. >>>>> >>>> I copied the code from ClassLoader.loadClass, which does it it a >>>> synchronized block: >>>> >>>> class ClassLoader { >>>> protected Class loadClass(String name, boolean resolve) >>>> throws ClassNotFoundException >>>> { >>>> synchronized (getClassLoadingLock(name)) { >>>> // First, check if the class has already been loaded >>>> Class c = findLoadedClass(name); >>>> if (c == null) { >>>> long t0 = System.nanoTime(); >>>> try { >>>> if (parent != null) { >>>> c = parent.loadClass(name, false); >>>> } else { >>>> c = findBootstrapClassOrNull(name); >>>> } >>>> } catch (ClassNotFoundException e) { >>>> // ClassNotFoundException thrown if class not >>>> found >>>> // from the non-null parent class loader >>>> } >>>> >>>> if (c == null) { >>>> // If still not found, then invoke findClass >>>> in order >>>> // to find the class. >>>> long t1 = System.nanoTime(); >>>> c = findClass(name); >>>> >>>> // this is the defining class loader; record >>>> the stats >>>> sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); >>>> sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); >>>> sun.misc.PerfCounter.getFindClasses().increment(); >>>> } >>>> } >>>> if (resolve) { >>>> resolveClass(c); >>>> } >>>> return c; >>>> } >>>> } >>>> >>>> So I guess it should look like this in Launcher$AppClassLoader, >>>> just to >>>> ensure the same things are done (regardless of whether it's >>>> necessary or >>>> not)? >>> In ClassLoader.loadClass it is providing atomicity across a number >>> of actions in the worst-case: >>> - checking for already loaded; if not then >>> - try to load through parent; if not then >>> - findClass (which will do defineClass) >>> >>> You don't have those atomicity constraints because you are only >>> doing one thing - checking to see if the class is loaded. >>> >>> Your locking is probably harmless but those are famous last words >>> when it comes to classloading. :) >>> >>>> Does resolveClass need to be done inside the synchronized block? >>> Depends on whether it depends on the classloader locking to prevent >>> concurrent resolve attempts. >>> >>> David >>> ----- >>> >>>> class Launcher$AppClassLoader { >>>> public Class loadClass(String name, boolean resolve) >>>> throws ClassNotFoundException >>>> { >>>> int i = name.lastIndexOf('.'); >>>> if (i != -1) { >>>> SecurityManager sm = System.getSecurityManager(); >>>> if (sm != null) { >>>> sm.checkPackageAccess(name.substring(0, i)); >>>> } >>>> } >>>> >>>> if (ucp.knownToNotExist(name)) { >>>> // The class of the given name is not found in the >>>> parent >>>> // class loader as well as its local URLClassPath. >>>> // Check if this class has already been defined >>>> dynamically; >>>> // if so, return the loaded class; otherwise, skip >>>> the >>>> parent >>>> // delegation and findClass. >>>>> >from here >>>> * synchronized (getClassLoadingLock(name)) {** >>>> ** Class c = findLoadedClass(name);** >>>> ** if (c != null) {** >>>> ** if (resolve) {** >>>> ** resolveClass(c);** >>>> ** }** >>>> ** return c;** >>>> ** }** >>>> ** }* >>>> <>>> throw new ClassNotFoundException(name); >>>> } >>>> >>>> return (super.loadClass(name, resolve)); >>>> } >>>> >>>> Thanks >>>> - Ioi >>>> >>>> >>>>> David >>>>> >>>>>> David H and Mandy - does that make sense to you both? >>>>>> >>>>>> thanks, >>>>>> Karen >>>>>> >>>>>> On Oct 28, 2014, at 12:38 AM, Ioi Lam wrote: >>>>>> >>>>>>> On 10/27/14, 7:04 PM, Mandy Chung wrote: >>>>>>>> On 10/27/2014 3:32 PM, Ioi Lam wrote: >>>>>>>>> Hi David, I have update the latest webrev at: >>>>>>>>> >>>>>>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ >>>>>>>>> >>>>>>>> The update looks good. Thanks. >>>>>>>> >>>>>>>>> This version also contains the JDK test case that Mandy >>>>>>>>> requested: >>>>>>>>> >>>>>>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>> What I request to add is a test setting the system property >>>>>>>> (-Dsun.cds.enableSharedLookupCache=true) and continue to load >>>>>>>> class >>>>>>>> A and B. Removing line 44-58 should do it and also no need to set >>>>>>>> -Dfoo.foo.bar. >>>>>>>> >>>>>>> Do you mean change the test to call >>>>>>> System.setProperty("sun.cds.enableSharedLookupCache", "true")? >>>>>>> >>>>>>> But we know that the property is checked only once, before any app >>>>>>> classes are loaded. So calling System.setProperty in an application >>>>>>> class won't test anything. >>>>>>>> It'd be good if you run this test and turn on the debug traces to >>>>>>>> make sure that the application class loader and ext class loader >>>>>>>> will start up with the lookup cache enabled and make up call to >>>>>>>> the >>>>>>>> VM. As it doesn't have the app cds archive, it will invalidate >>>>>>>> the >>>>>>>> cache right away and continue the class lookup with null cache >>>>>>>> array. >>>>>>> In the latest code, if CDS is not available, lookupCacheEnabled >>>>>>> will >>>>>>> be set to false inside the static initializer of URLClassPath: >>>>>>> >>>>>>> private static volatile boolean lookupCacheEnabled >>>>>>> = >>>>>>> "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache")); >>>>>>> >>>>>>> >>>>>>> later, when the boot/ext/app loaders call into here: >>>>>>> >>>>>>> synchronized void initLookupCache(ClassLoader loader) { >>>>>>> if ((lookupCacheURLs = getLookupCacheURLs(loader)) != >>>>>>> null) { >>>>>>> lookupCacheLoader = loader; >>>>>>> } else { >>>>>>> // This JVM instance does not support lookup cache. >>>>>>> disableAllLookupCaches(); >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> their lookupCacheURLs[] fields will all be set to null. As a >>>>>>> result, >>>>>>> getLookupCacheForClassLoader and knownToNotExist0 will never be >>>>>>> called. >>>>>>> >>>>>>> I can add a DEBUG_LOOKUP_CACHE trace inside disableAllLookupCaches >>>>>>> to print "lookup cache disabled", and check for that in the >>>>>>> test. Is >>>>>>> this OK? >>>>>>> >>>>>>> Thanks >>>>>>> - Ioi >>>>>>> >>>>>>> >>>>>>> > From stuart.marks at oracle.com Thu Oct 30 05:40:15 2014 From: stuart.marks at oracle.com (Stuart Marks) Date: Wed, 29 Oct 2014 22:40:15 -0700 Subject: RFR (s): 4354680: Runtime.runFinalization() silently clears interrupted flag in the calling thread In-Reply-To: <5451A0DB.3030303@oracle.com> References: <54518EAD.3060504@oracle.com> <5451A0DB.3030303@oracle.com> Message-ID: <5451CF3F.6090303@oracle.com> On 10/29/14 7:22 PM, David Holmes wrote: > Hi Stuart, > > You're a brave man! :) :-) > Right - there is no change in behaviour with your change other than fixing the > problem with the cleared interrupt bit. That's the best you can do in my opinion. OK, after thinking about it, I was starting to lean that direction too. > The spec of this method is weak enough: > > "When control returns from the method call, the virtual machine has made a best > effort to complete all outstanding finalizations." > > that nobody should have any expectations about what a single invocation of it > should achieve. At best they might argue that the VMs "best effort" was pretty > poor, but I can live with that - plus it would be a distinct RFE not part of > this bug fix. OK. > The fact a method is called that interacts with the interruption mechanism is > purely an internal implementation detail. It should not bubble up to the > specification of these methods. I don't see a need to document this aspect given > the weakness of the spec as referenced above. Fair enough. Less work. :-) > That said it may be worth doing a search for all tests that use runFinalization > to see how it is used. If used in a loop (which I suspect is common) and the > test is timing out and so the thread is interrupted by the test harness, it will > become a spin loop. Yes, I've started to look at some of the uses of runFinalization(). Mostly in tests so far, but I haven't looked everywhere yet. Most uses seem to call some combination of System.gc() and System.runFinalization(), and then sleep for a while, so there is implicitly some notion of waiting for finalization to occur asynchronously. Or, they have the finalizer set some piece of state that's waited for. If such a test were to time out (and interrupt the thread) during a call to runFinalization(), the change would preserve the interrupt bit instead of clearing it. But most such tests have code like, try { Thread.sleep(DELAY); } catch (InterruptedException ignore) { } so the interrupt would get ignored anyway.... (Yet Another Cleanup Task: fix all the tests that ignore InterruptedException.) > Aside, I noticed in this code: > > 146 forkSecondaryFinalizer(new Runnable() { > 147 private volatile boolean running; > 148 public void run() { > 149 if (running) > 150 return; > 151 final JavaLangAccess jla = SharedSecrets.getJavaLangAccess(); > 152 running = true; > > that as we create a new Runnable on every call, the "running" field serves > absolutely no purpose. Ha. Good catch. This was probably refactored from a static field of a containing class. The intent was probably to prevent multiple secondary finalizer threads from running, but it wouldn't do this very well even if it were static. I'll clean this up since it clearly serves no purpose as it stands. Thanks, s'marks From stanimir at riflexo.com Thu Oct 30 06:00:39 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Thu, 30 Oct 2014 08:00:39 +0200 Subject: RFR (s): 4354680: Runtime.runFinalization() silently clears interrupted flag in the calling thread In-Reply-To: <5451A0DB.3030303@oracle.com> References: <54518EAD.3060504@oracle.com> <5451A0DB.3030303@oracle.com> Message-ID: > Aside, I noticed in this code: > > 146 forkSecondaryFinalizer(new Runnable() { > 147 private volatile boolean running; > 148 public void run() { > 149 if (running) > 150 return; > 151 final JavaLangAccess jla = SharedSecrets. > getJavaLangAccess(); > 152 running = true; > > that as we create a new Runnable on every call, the "running" field serves > absolutely no purpose. > > Cheers, > David > It could be defense vs Thread.currentThread().run() in finalizer that would cause calling run() of Thread.target. I am not sure if that would cause invocation, though. But I have done similar "non-senses"... Stanimir From david.holmes at oracle.com Thu Oct 30 07:31:51 2014 From: david.holmes at oracle.com (David Holmes) Date: Thu, 30 Oct 2014 17:31:51 +1000 Subject: RFR (s): 4354680: Runtime.runFinalization() silently clears interrupted flag in the calling thread In-Reply-To: References: <54518EAD.3060504@oracle.com> <5451A0DB.3030303@oracle.com> Message-ID: <5451E967.3060900@oracle.com> On 30/10/2014 4:00 PM, Stanimir Simeonoff wrote: > > Aside, I noticed in this code: > > 146 forkSecondaryFinalizer(new Runnable() { > 147 private volatile boolean running; > 148 public void run() { > 149 if (running) > 150 return; > 151 final JavaLangAccess jla = > SharedSecrets.__getJavaLangAccess(); > 152 running = true; > > that as we create a new Runnable on every call, the "running" field > serves absolutely no purpose. > > Cheers, > David > > It could be defense vs Thread.currentThread().run() in finalizer that > would cause calling run() of Thread.target. I am not sure if that would > cause invocation, though. That is an excellent point! But it deserves a comment in the code. Thanks, David > But I have done similar "non-senses"... > > Stanimir From Alan.Bateman at oracle.com Thu Oct 30 08:46:55 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 30 Oct 2014 08:46:55 +0000 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: References: <20141029204640.9995417FDA3@rebar.astron.com> Message-ID: <5451FAFF.3060007@oracle.com> On 29/10/2014 21:15, Mario Torre wrote: > > +1 > > We should have spotted it in the review though. > We should but the ultimate rat catcher should be the tests, it's possible that we have a hole there. From chris.hegarty at oracle.com Thu Oct 30 09:21:46 2014 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Thu, 30 Oct 2014 09:21:46 +0000 Subject: RFR (s): 4354680: Runtime.runFinalization() silently clears interrupted flag in the calling thread In-Reply-To: <5451E967.3060900@oracle.com> References: <54518EAD.3060504@oracle.com> <5451A0DB.3030303@oracle.com> <5451E967.3060900@oracle.com> Message-ID: On 30 Oct 2014, at 07:31, David Holmes wrote: > On 30/10/2014 4:00 PM, Stanimir Simeonoff wrote: >> >> Aside, I noticed in this code: >> >> 146 forkSecondaryFinalizer(new Runnable() { >> 147 private volatile boolean running; >> 148 public void run() { >> 149 if (running) >> 150 return; >> 151 final JavaLangAccess jla = >> SharedSecrets.__getJavaLangAccess(); >> 152 running = true; >> >> that as we create a new Runnable on every call, the "running" field >> serves absolutely no purpose. >> >> Cheers, >> David >> >> It could be defense vs Thread.currentThread().run() in finalizer that >> would cause calling run() of Thread.target. I am not sure if that would >> cause invocation, though. > > That is an excellent point! But it deserves a comment in the code. Adding a comment is fine, but please to not remove this field. ?hg log? may reveal more about it?s origins. -Chris. > Thanks, > David > >> But I have done similar "non-senses"... >> >> Stanimir From peter.levart at gmail.com Thu Oct 30 09:29:05 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 30 Oct 2014 10:29:05 +0100 Subject: Loading classes with many methods is very expensive In-Reply-To: References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <5450CEE9.7060707@gmail.com> <545120D2.5010301@gmail.com> Message-ID: <545204E1.6000702@gmail.com> Hi Stanimir, On 10/30/2014 12:00 AM, Stanimir Simeonoff wrote: > Hi Peter, > > The removal of value wrapper is a clever approach to reduce the new > instances created although it feels very unnatural (at least to me). Number of objects created is practically the same. Previous approach used same MethodList instances for keys and values. New approach uses just Key instances, values are Methods themselves. It's allways 1 additional object per Method, but new approach might use a couple of more Map.Entry objects (when multiple methods with same signature are present). New approach is different in that it was designed to keep the insertion order of Method(s) (LinkedHashMap), but you found out this is not true (below)... > Small > optimization; eagerly calculate the hash in the c'tor, > hash = > > 149 method.getReturnType().hashCode() ^ > 150 System.identityHashCode(method.getName()) ^ > 151 Arrays.hashCode(method.getParameterTypes() > > and so the real int hashCode(){return seq+hash;} Right, that would be an time/space trade-off. It might not be on 64bit arch - just on 32bit. I should check. Perhaps hashCode should not depend on seq (see below). > > Also I am not sure if method.getName().hashCode() would be better or not, > if previously identityHashCode is not invoked on that string and depending > on the configured hashCode (-XX:hashCode) generator System.identityHashCode > might be slow or worse call C random() which doesn't scale. Setting the > hashCode requires a CAS too. CAS is of course one-time off but still Thanks for pointing that out. I'll use String.hashCode() then. > > About the order of the returned methods: if you remove and then put from/to > the LHM the order of iteration is going to be greatly altered. Is that ok? Excelent point! I might get away with excluding seq from hashCode computation and only use it in equals(). This way Key(s) could be modified in-place (hashCode would not change, entry would stay in same bucket), it would just become equal to some other Key. Modification operations would keep the invariant that there are no duplicate Key(s) at any time in the Map. All entries sharing same method signature would end-up in the same bucket (and maybe share it with entries that just happen to have the same hashCode mod capacity) and we would get a similar linked list of entries as with previous approach - only without another level of indirection... Regards, Peter > > Stanimir > > On Wed, Oct 29, 2014 at 7:16 PM, Peter Levart > wrote: > >> On 10/29/2014 02:08 PM, Joel Borggr?n-Franck wrote: >> >>> Hi Peter, >>> >>> I'm not entirely convinced this is a bug. >>> >>> The lookup order for getMethod has for a long time been walk up >>> superclasses and return what you find there first without even looking at >>> interfaces. It might be desirable to change that but I'm not sure. >>> >> Hi Joel, >> >> It has been for a long time like that as you say, but for a long time Java >> did not have default methods. It's unexpected for getMethod() to return a >> method that is not contained in getMethods() result. >> >> Anyway, I have created a bug to track this: >> >> https://bugs.openjdk.java.net/browse/JDK-8062389 >> >> For next iteration of the getMethods() O(n^2) fix, I used a slightly >> different approach, which you might like more or not. Instead of using >> linked-lists of Method objects as values of a LinkedHashMap I created a >> special Key object, holding a reference to Method object and an additional >> 'seq' int field, which discriminates among methods with same signature. >> Values of LinkedHashMap are Method objects themselves: >> >> http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.03/ >> >> I have encapsulated this functionality into a package-private >> java.lang.MethodTable. The implementation of this API can be easily changed >> to using linked-lists as values of LinkedHashMap if desired. The >> performance characteristics are similar, with hardly measurable advantage >> of this latest approach as can be seen from http://cr.openjdk.java.net/~ >> plevart/jdk9-dev/Class.getMethods/GetAllRtMethods.java benchmark: >> >> Original code: >> >> 19658 classes loaded in 2.071013902 seconds. >> 494392 methods obtained in 1.089983418 seconds. >> 494392 methods obtained in 0.952488497 seconds. >> 494392 methods obtained in 0.912878317 seconds. >> 494392 methods obtained in 0.940293784 seconds. >> 494392 methods obtained in 0.987640733 seconds. >> 494392 methods obtained in 0.925393355 seconds. >> 494392 methods obtained in 0.89397002 seconds. >> 494392 methods obtained in 0.915042463 seconds. >> 494392 methods obtained in 0.897669082 seconds. >> 494392 methods obtained in 0.878140502 seconds. >> >> Patched code: >> >> 19658 classes loaded in 2.153024197 seconds. >> 494392 methods obtained in 0.875651469 seconds. >> 494392 methods obtained in 0.791937742 seconds. >> 494392 methods obtained in 0.780995693 seconds. >> 494392 methods obtained in 0.759593461 seconds. >> 494392 methods obtained in 0.766528355 seconds. >> 494392 methods obtained in 0.756567663 seconds. >> 494392 methods obtained in 0.739177848 seconds. >> 494392 methods obtained in 0.729245613 seconds. >> 494392 methods obtained in 0.74081083 seconds. >> 494392 methods obtained in 0.731749505 seconds. >> >> >> Martin's ManyMethodsBenchmark shows this algorithm has O(n) time >> complexity too: >> >> Original: >> >> Base class load time: 131.95 ms >> getDeclaredMethods: 65521 methods, 32.00 ms total time, 0.0005 ms per >> method >> getMethods : 65530 methods, 44.24 ms total time, 0.0007 ms per >> method >> Derived class load time: 32525.23 ms >> getDeclaredMethods: 65521 methods, 30.37 ms total time, 0.0005 ms per >> method >> getMethods : 65530 methods, 7897.03 ms total time, 0.1205 ms per >> method >> >> Patched: >> >> Base class load time: 129.72 ms >> getDeclaredMethods: 65521 methods, 32.76 ms total time, 0.0005 ms per >> method >> getMethods : 65530 methods, 42.68 ms total time, 0.0007 ms per >> method >> Derived class load time: 31620.47 ms >> getDeclaredMethods: 65521 methods, 30.49 ms total time, 0.0005 ms per >> method >> getMethods : 65530 methods, 88.23 ms total time, 0.0013 ms per >> method >> >> >> I have also run Martin's LoadAllClassesAndMethods test (Thanks Martin, I >> changed it slightly so that exceptions are collected and reported at the >> end instead of bailing-out on first exception). >> >> Original LoadAllClassesAndMethods write classlist.txt: >> >> class load: 23052 classes, 1563.75 ms total time, 0.0678 ms per class >> 4 exceptions encountered: >> java.lang.IncompatibleClassChangeError: jdk.nashorn.internal.codegen.CompilationPhase$10 >> and jdk.nashorn.internal.codegen.CompilationPhase$10$1 disagree on >> InnerClasses attribute >> java.lang.IncompatibleClassChangeError: jdk.nashorn.internal.codegen.CompilationPhase$5 >> and jdk.nashorn.internal.codegen.CompilationPhase$5$1 disagree on >> InnerClasses attribute >> java.lang.IncompatibleClassChangeError: java.security.ProtectionDomain$3 >> and java.security.ProtectionDomain$3$1 disagree on InnerClasses attribute >> java.lang.IncompatibleClassChangeError: java.lang.Compiler and >> java.lang.Compiler$1 disagree on InnerClasses attribute >> getMethods: 23052 classes, 831.87 ms total time, 0.0361 ms per class >> >> Patched LoadAllClassesAndMethods diff classlist.txt: >> >> class load: 23051 classes, 1596.58 ms total time, 0.0693 ms per class >> 5 exceptions encountered: >> java.lang.IncompatibleClassChangeError: jdk.nashorn.internal.codegen.CompilationPhase$10 >> and jdk.nashorn.internal.codegen.CompilationPhase$10$1 disagree on >> InnerClasses attribute >> java.lang.IncompatibleClassChangeError: jdk.nashorn.internal.codegen.CompilationPhase$5 >> and jdk.nashorn.internal.codegen.CompilationPhase$5$1 disagree on >> InnerClasses attribute >> java.lang.IncompatibleClassChangeError: java.lang.Class and >> java.lang.Class$MethodArray disagree on InnerClasses attribute >> java.lang.IncompatibleClassChangeError: java.security.ProtectionDomain$3 >> and java.security.ProtectionDomain$3$1 disagree on InnerClasses attribute >> java.lang.IncompatibleClassChangeError: java.lang.Compiler and >> java.lang.Compiler$1 disagree on InnerClasses attribute >> getMethods: 23051 classes, 799.99 ms total time, 0.0347 ms per class >> The following classes were expected, but not found: >> [java.lang.Class$MethodArray] >> >> >> The reason for Class$MethodArray to not be loaded by patched code is the >> way I tested patched j.l.Class. I prepended the boot classpath with a >> directory holding patched Class/MethodTable. Martin's >> LoadAllClassesAndMethods tries to load Class$MethodArray anyway, since it's >> in rt.jar, but this class is gone in patched j.l.Class, so >> "IncompatibleClassChangeError: java.lang.Class and >> java.lang.Class$MethodArray disagree on InnerClasses attribute" is expected >> in this case. Otherwise this test shows that original and patched code >> agree on results returned from getMethods() for all system and extension >> JDK classes. >> >> All 86 jtreg tests in java/lang/Class/ and java/lang/reflect/ pass. >> >> I still have to create a test case for inconsistency I discovered in >> previous iteration. >> >> Regards, Peter >> >> >> >> >>> cheers >>> /Joel >>> >>> On 29 okt 2014, at 12:26, Peter Levart wrote: >>> >>> Hi Joel, >>>> I found an inconsistency between getMethod() and getMethods() results >>>> that is present in current JDK8/9 code and in my latest webrev.02. The >>>> following program: >>>> >>>> import java.util.stream.Collectors; >>>> import java.util.stream.Stream; >>>> >>>> public class GetMethodTest { >>>> >>>> static void test(Class clazz) throws Exception { >>>> >>>> System.out.println(clazz.getName() + ".class.getMethods(): " + >>>> Stream >>>> .of(clazz.getMethods()) >>>> .filter(m -> m.getDeclaringClass() != >>>> Object.class) >>>> .collect(Collectors.toList())); >>>> >>>> System.out.println(clazz.getName() + ".class.getMethod(\"m\"): >>>> " + >>>> clazz.getMethod("m")); >>>> >>>> System.out.println(); >>>> } >>>> >>>> public static void main(String[] args) throws Exception { >>>> test(I.class); >>>> test(J.class); >>>> test(A.class); >>>> test(B.class); >>>> } >>>> } >>>> >>>> interface I { >>>> void m(); >>>> } >>>> >>>> interface J extends I { >>>> default void m() {} >>>> } >>>> >>>> abstract class A implements I {} >>>> >>>> abstract class B extends A implements J {} >>>> >>>> >>>> prints: >>>> >>>> I.class.getMethods(): [public abstract void I.m()] >>>> I.class.getMethod("m"): public abstract void I.m() >>>> >>>> J.class.getMethods(): [public default void J.m()] >>>> J.class.getMethod("m"): public default void J.m() >>>> >>>> A.class.getMethods(): [public abstract void I.m()] >>>> A.class.getMethod("m"): public abstract void I.m() >>>> >>>> B.class.getMethods(): [public default void J.m()] >>>> B.class.getMethod("m"): public abstract void I.m() >>>> >>>> B.class.getMethods() reports default method J.m() (which I think is >>>> correct), but B.class.getMethod("m") reports the abstract I.m() inherited >>>> from A, because here the getMethod0() algorithm stops searching for and >>>> consolidating any methods in (super)interfaces. Do you agree that this is a >>>> bug? >>>> >>>> >>>> Regards, Peter >>>> >>>> On 10/27/2014 02:45 PM, Joel Borggr?n-Franck wrote: >>>> >>>>> Hi Peter, >>>>> >>>>> As always, thanks for doing this! It has been on my todolist for a >>>>> while but never quite bubbling up to the top. >>>>> >>>>> I don't have time to look att his right now, but I expect to have some >>>>> free time next week, but i have two short comments >>>>> >>>>> First, I have been thinking about moving MethodArray to its's own >>>>> top-level class, isn't it about time? >>>>> >>>>> Second I would expect testing for the missing cases you uncovered (good >>>>> catch!). >>>>> >>>>> I'll try to get back to you asap. >>>>> >>>>> cheers >>>>> /Joel >>>>> >>>>> >>>>> On 26 okt 2014, at 23:53, Peter Levart wrote: >>>>> >>>>> On 10/26/2014 09:25 PM, Peter Levart wrote: >>>>>>> 19657 classes loaded in 1.987373401 seconds. >>>>>>> 494141 methods obtained in 1.02493941 seconds. >>>>>>> >>>>>>> vs. >>>>>>> >>>>>>> 19657 classes loaded in 2.084409717 seconds. >>>>>>> 494124 methods obtained in 0.915928578 seconds. >>>>>>> >>>>>> Hi, >>>>>> >>>>>> As you might have noticed, the number of methods obtained from patched >>>>>> code differed from original code. I have investigated this and found that >>>>>> original code treats abstract class methods the same as abstract interface >>>>>> methods as far as multiple inheritance is concerned (it keeps them together >>>>>> in the returned array). So I fixed this and here's new webrev which behaves >>>>>> the same as original code: >>>>>> >>>>>> http://cr.openjdk.java.net/~plevart/jdk9-dev/Class. >>>>>> getMethods/webrev.02/ >>>>>> >>>>>> Comparing original vs. patched code still shows speed-up: >>>>>> >>>>>> Original: >>>>>> >>>>>> 19657 classes loaded in 1.980493029 seconds. >>>>>> 494141 methods obtained in 0.976318927 seconds. >>>>>> 494141 methods obtained in 0.886504437 seconds. >>>>>> 494141 methods obtained in 0.911153722 seconds. >>>>>> 494141 methods obtained in 0.880550509 seconds. >>>>>> 494141 methods obtained in 0.875526704 seconds. >>>>>> 494141 methods obtained in 0.877258894 seconds. >>>>>> 494141 methods obtained in 0.871794344 seconds. >>>>>> 494141 methods obtained in 0.884159644 seconds. >>>>>> 494141 methods obtained in 0.892648522 seconds. >>>>>> 494141 methods obtained in 0.884581841 seconds. >>>>>> >>>>>> Patched: >>>>>> >>>>>> 19657 classes loaded in 2.055697675 seconds. >>>>>> 494141 methods obtained in 0.853922188 seconds. >>>>>> 494141 methods obtained in 0.776203794 seconds. >>>>>> 494141 methods obtained in 0.858774803 seconds. >>>>>> 494141 methods obtained in 0.778178867 seconds. >>>>>> 494141 methods obtained in 0.760043997 seconds. >>>>>> 494141 methods obtained in 0.756352444 seconds. >>>>>> 494141 methods obtained in 0.740826372 seconds. >>>>>> 494141 methods obtained in 0.744264782 seconds. >>>>>> 494141 methods obtained in 0.73805894 seconds. >>>>>> 494141 methods obtained in 0.746852752 seconds. >>>>>> >>>>>> >>>>>> 55 java/lang/reflect jtreg tests still pass. As they did before, which >>>>>> means that we don't have a coverage for such cases. I'll see where I can >>>>>> add such a case (EnumSet for example, which inherits from Set interface and >>>>>> AbstractColection class via two different paths, so Set.size()/iterator() >>>>>> and AbstractCollection.size()/iterator() are both returned from >>>>>> getMethods())... >>>>>> >>>>>> >>>>>> Regards, Peter >>>>>> >>>>>> From peter.levart at gmail.com Thu Oct 30 09:43:20 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 30 Oct 2014 10:43:20 +0100 Subject: Loading classes with many methods is very expensive In-Reply-To: <545204E1.6000702@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <5450CEE9.7060707@gmail.com> <545120D2.5010301@gmail.com> <545204E1.6000702@gmail.com> Message-ID: <54520838.7050400@gmail.com> On 10/30/2014 10:29 AM, Peter Levart wrote: > I might get away with excluding seq from hashCode computation and only > use it in equals(). This way Key(s) could be modified in-place > (hashCode would not change, entry would stay in same bucket), it would > just become equal to some other Key. Modification operations would > keep the invariant that there are no duplicate Key(s) at any time in > the Map. All entries sharing same method signature would end-up in the > same bucket (and maybe share it with entries that just happen to have > the same hashCode mod capacity) and we would get a similar linked list > of entries as with previous approach - only without another level of > indirection... That would not work. I would have to have the Key object accessible. Since Map does not have a getKey(key) operation, I would have to store the Key as a value too. And we're back to MethodList approach... Peter From david.holmes at oracle.com Thu Oct 30 09:45:34 2014 From: david.holmes at oracle.com (David Holmes) Date: Thu, 30 Oct 2014 19:45:34 +1000 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: <5451FAFF.3060007@oracle.com> References: <20141029204640.9995417FDA3@rebar.astron.com> <5451FAFF.3060007@oracle.com> Message-ID: <545208BE.90104@oracle.com> On 30/10/2014 6:46 PM, Alan Bateman wrote: > On 29/10/2014 21:15, Mario Torre wrote: >> >> +1 >> >> We should have spotted it in the review though. >> > > We should but the ultimate rat catcher should be the tests, it's > possible that we have a hole there. Not sure how the presence or absence of CLOEXEC would be visible to any test - especially given all the other uses of raw open in the JDK sources. David From aleksey.shipilev at oracle.com Thu Oct 30 09:47:13 2014 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Thu, 30 Oct 2014 12:47:13 +0300 Subject: Loading classes with many methods is very expensive In-Reply-To: <54520838.7050400@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <5450CEE9.7060707@gmail.com> <545120D2.5010301@gmail.com> <545204E1.6000702@gmail.com> <54520838.7050400@gmail.com> Message-ID: <54520921.9040905@oracle.com> Guys, can you please start a new RFR thread for Peter's change? You have a bug ID now, and the discussion should be searchable by bug ID. Also, you are spamming two aliases (corelibs + hotspot-runtime) instead of one ;) -Aleksey. On 10/30/2014 12:43 PM, Peter Levart wrote: > On 10/30/2014 10:29 AM, Peter Levart wrote: >> I might get away with excluding seq from hashCode computation and only >> use it in equals(). This way Key(s) could be modified in-place >> (hashCode would not change, entry would stay in same bucket), it would >> just become equal to some other Key. Modification operations would >> keep the invariant that there are no duplicate Key(s) at any time in >> the Map. All entries sharing same method signature would end-up in the >> same bucket (and maybe share it with entries that just happen to have >> the same hashCode mod capacity) and we would get a similar linked list >> of entries as with previous approach - only without another level of >> indirection... > > That would not work. I would have to have the Key object accessible. > Since Map does not have a getKey(key) operation, I would have to store > the Key as a value too. And we're back to MethodList approach... > > Peter > From peter.levart at gmail.com Thu Oct 30 09:48:30 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 30 Oct 2014 10:48:30 +0100 Subject: Loading classes with many methods is very expensive In-Reply-To: <54520921.9040905@oracle.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <5450CEE9.7060707@gmail.com> <545120D2.5010301@gmail.com> <545204E1.6000702@gmail.com> <54520838.7050400@gmail.com> <54520921.9040905@oracle.com> Message-ID: <5452096E.1040101@gmail.com> Sorry, I apologize. I'll start a new thread on core-libs only. Peter On 10/30/2014 10:47 AM, Aleksey Shipilev wrote: > Guys, can you please start a new RFR thread for Peter's change? You have > a bug ID now, and the discussion should be searchable by bug ID. > > Also, you are spamming two aliases (corelibs + hotspot-runtime) instead > of one ;) > > -Aleksey. > > On 10/30/2014 12:43 PM, Peter Levart wrote: >> On 10/30/2014 10:29 AM, Peter Levart wrote: >>> I might get away with excluding seq from hashCode computation and only >>> use it in equals(). This way Key(s) could be modified in-place >>> (hashCode would not change, entry would stay in same bucket), it would >>> just become equal to some other Key. Modification operations would >>> keep the invariant that there are no duplicate Key(s) at any time in >>> the Map. All entries sharing same method signature would end-up in the >>> same bucket (and maybe share it with entries that just happen to have >>> the same hashCode mod capacity) and we would get a similar linked list >>> of entries as with previous approach - only without another level of >>> indirection... >> That would not work. I would have to have the Key object accessible. >> Since Map does not have a getKey(key) operation, I would have to store >> the Key as a value too. And we're back to MethodList approach... >> >> Peter >> > From neugens.limasoftware at gmail.com Thu Oct 30 10:16:26 2014 From: neugens.limasoftware at gmail.com (Mario Torre) Date: Thu, 30 Oct 2014 11:16:26 +0100 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: <545208BE.90104@oracle.com> References: <20141029204640.9995417FDA3@rebar.astron.com> <5451FAFF.3060007@oracle.com> <545208BE.90104@oracle.com> Message-ID: This is exactly what I was about to reply. One can only spot those things if there is a standardised API, and even in this case it's not at all easy. That doesn't stop from trying :) but removing the API was likely a mistake, which would not be a terrible one because of what David points, except the fact that it's invalidating a fix (at least this is what I understood from Martin's original mail). On a related note, some time ago there was a process of standardising and documenting the VM abstraction (Andrew Hughes was doing that), does anybody knows what's the state of that? Afaik there's a lot of infrastructure in place, but it seems more like "we have it more or less when it makes sense" rather than a carefully planned long term project. But I think it may be worth expanding over this rather than reducing it. This would benefit external VM implementation, which is a good thing, but the main goal for me would be to have a clearly documented and logical API with the overall benefit that if we abstract those things out, we have one single place where bugs can possible be [fixed]. What do you think? Cheers, Mario 2014-10-30 10:45 GMT+01:00 David Holmes : > On 30/10/2014 6:46 PM, Alan Bateman wrote: >> >> On 29/10/2014 21:15, Mario Torre wrote: >>> >>> >>> +1 >>> >>> We should have spotted it in the review though. >>> >> >> We should but the ultimate rat catcher should be the tests, it's >> possible that we have a hole there. > > > Not sure how the presence or absence of CLOEXEC would be visible to any test > - especially given all the other uses of raw open in the JDK sources. > > David > -- pgp key: http://subkeys.pgp.net/ PGP Key ID: 80F240CF Fingerprint: BA39 9666 94EC 8B73 27FA FC7C 4086 63E3 80F2 40CF Java Champion - Blog: http://neugens.wordpress.com - Twitter: @neugens Proud GNU Classpath developer: http://www.classpath.org/ OpenJDK: http://openjdk.java.net/projects/caciocavallo/ Please, support open standards: http://endsoftpatents.org/ From neugens.limasoftware at gmail.com Thu Oct 30 10:24:05 2014 From: neugens.limasoftware at gmail.com (Mario Torre) Date: Thu, 30 Oct 2014 11:24:05 +0100 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: References: <20141029204640.9995417FDA3@rebar.astron.com> <5451FAFF.3060007@oracle.com> <545208BE.90104@oracle.com> Message-ID: I've been thinking perhaps one can use fcntl to check what flags are passed given we can retrieve all the file descriptors that have been opened? Using raw open complicates the matter though. Cheers, Mario 2014-10-30 11:16 GMT+01:00 Mario Torre : > This is exactly what I was about to reply. One can only spot those > things if there is a standardised API, and even in this case it's not > at all easy. That doesn't stop from trying :) but removing the API was > likely a mistake, which would not be a terrible one because of what > David points, except the fact that it's invalidating a fix (at least > this is what I understood from Martin's original mail). > > On a related note, some time ago there was a process of standardising > and documenting the VM abstraction (Andrew Hughes was doing that), > does anybody knows what's the state of that? Afaik there's a lot of > infrastructure in place, but it seems more like "we have it more or > less when it makes sense" rather than a carefully planned long term > project. But I think it may be worth expanding over this rather than > reducing it. > > This would benefit external VM implementation, which is a good thing, > but the main goal for me would be to have a clearly documented and > logical API with the overall benefit that if we abstract those things > out, we have one single place where bugs can possible be [fixed]. > > What do you think? > > Cheers, > Mario > > 2014-10-30 10:45 GMT+01:00 David Holmes : >> On 30/10/2014 6:46 PM, Alan Bateman wrote: >>> >>> On 29/10/2014 21:15, Mario Torre wrote: >>>> >>>> >>>> +1 >>>> >>>> We should have spotted it in the review though. >>>> >>> >>> We should but the ultimate rat catcher should be the tests, it's >>> possible that we have a hole there. >> >> >> Not sure how the presence or absence of CLOEXEC would be visible to any test >> - especially given all the other uses of raw open in the JDK sources. >> >> David >> > > > > -- > pgp key: http://subkeys.pgp.net/ PGP Key ID: 80F240CF > Fingerprint: BA39 9666 94EC 8B73 27FA FC7C 4086 63E3 80F2 40CF > > Java Champion - Blog: http://neugens.wordpress.com - Twitter: @neugens > Proud GNU Classpath developer: http://www.classpath.org/ > OpenJDK: http://openjdk.java.net/projects/caciocavallo/ > > Please, support open standards: > http://endsoftpatents.org/ -- pgp key: http://subkeys.pgp.net/ PGP Key ID: 80F240CF Fingerprint: BA39 9666 94EC 8B73 27FA FC7C 4086 63E3 80F2 40CF Java Champion - Blog: http://neugens.wordpress.com - Twitter: @neugens Proud GNU Classpath developer: http://www.classpath.org/ OpenJDK: http://openjdk.java.net/projects/caciocavallo/ Please, support open standards: http://endsoftpatents.org/ From Alan.Bateman at oracle.com Thu Oct 30 13:08:12 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 30 Oct 2014 13:08:12 +0000 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: References: Message-ID: <5452383C.2030208@oracle.com> On 29/10/2014 20:12, Martin Buchholz wrote: > Hi guys, > > In your change > > 8057777: Cleanup of old and unused VM interfaces > > you have made changes like this: > > - zfd = JVM_Open(path, flag, 0); > + zfd = open(path, flag, 0); > > throwing away use of old shared infrastructure and replacing with > "naked" calls to the OS. Although understandable, this abandons > benefits of using shared infrastructure. Here I'm thinking of the > close-on-exec flag. I just added use of O_CLOEXEC to linux hotspot, > but e.g. zip file opening no longer uses JVM_Open, which is a code > hygiene regression. > > What we want is to have almost all file descriptors have the > close-on-exec flag automatically set at fd creation time, using > O_CLOEXEC where available, and FD_CLOEXEC where not. How do we get there? > I think Frederic's clean-up was generally good, it gets rid of a lot of crud from early JDK versions. In early versions of the JDK then it was important for the library code to go through the VM because the JDK could be run on green threads so every potentially-blocking syscall had to wrapped in the VM. There was also an attempt at a porting interface at the time but this bit rotted a long time ago (much of it was orphaned when we moved from the the classic VM to HotSpot). The remaining bits of that porting interface were finally removed in JDK 7 but that still left the JVM interface with a lot of functions, networking and some file I/O, that aren't interesting for the JVM interface. So I think it's good to have these removed from the JVM interface. Also good to see the no-op functions to support java.lang.Compiler and Runtime.traceXXX go away too. The change in behavior from JVM_Open ito open was missed but there is a long way to go in JDK 9 so lots of time to fix the issue (if there is an issue). As was noted in one of the replies, the only usages of JVM_Open were in the zip code, it hasn't been used consistently used in the libraries for at least 10+ years. When doing significant changes then thorough code reviews are important but good tests are equally, and sometimes more, important. I understand that having a test for the O_CLOEXEC might be too hard so I'm interested to know how you ran into it. Maybe it was inspection? Maybe an app that opens lots of zip files and executes fork/exec itself? For ProcessBuilder and Runtime.exec usages then the I thought the childproc code handled this by looping over the open file descriptors and closing them. So even if O_CLOEXEC or fcntl(FD_CLOEXEC) isn't used then it should be closed in the child. As to whether we need a JVM_Open replacement in libjava then maybe we do but I think it needs a discussion as to whether the JDK really needs a porting interface or just useful infrastructure. Also I think going forward then I assume that the amount of native code will reduce, particularly when FFI comes along and we start to get rid of some of the native code (at least I hope that happens). In the mean-time then I think I'd like to understand more as to whether the O_CLOEXEC is an issue or not. Aside from the zip code then I don't think we've been using it consistently so I'm wondering if the issue is some native code calling fork+exec or something else? -Alan From Alan.Bateman at oracle.com Thu Oct 30 13:10:01 2014 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 30 Oct 2014 13:10:01 +0000 Subject: RFR 9 8062513: doclint warnings in HijrahChronology In-Reply-To: <5451A256.1020608@oracle.com> References: <5451A256.1020608@oracle.com> Message-ID: <545238A9.7060206@oracle.com> On 30/10/2014 02:28, roger riggs wrote: > Please review a correction to address a doclint warning in > HijrahChronology. > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-doclint-8062513/ > > Issue: > 8062513: doclint warnings in HijrahChronology This looks to me, you might to just split the line as it otherwise sticks out compared to the rest of the paragraph. -Alan. From roger.riggs at oracle.com Thu Oct 30 13:14:43 2014 From: roger.riggs at oracle.com (roger riggs) Date: Thu, 30 Oct 2014 09:14:43 -0400 Subject: RFR 9 8062513: doclint warnings in HijrahChronology In-Reply-To: <545238A9.7060206@oracle.com> References: <5451A256.1020608@oracle.com> <545238A9.7060206@oracle.com> Message-ID: <545239C3.6090806@oracle.com> Thanks Joe, Alan, On 10/30/2014 9:10 AM, Alan Bateman wrote: > On 30/10/2014 02:28, roger riggs wrote: >> Please review a correction to address a doclint warning in >> HijrahChronology. >> >> Webrev: >> http://cr.openjdk.java.net/~rriggs/webrev-doclint-8062513/ >> >> Issue: >> 8062513: doclint warnings in HijrahChronology > This looks to me, you might to just split the line as it otherwise > sticks out compared to the rest of the paragraph. done > > -Alan. From karen.kinnear at oracle.com Thu Oct 30 13:32:12 2014 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Thu, 30 Oct 2014 09:32:12 -0400 Subject: RFR (M) 8061651 - Interface to the Lookup Index Cache to improve URLClassPath search time (round 3) In-Reply-To: <5451CBE9.4020800@oracle.com> References: <54469778.8090008@oracle.com> <5446BA6B.5030803@oracle.com> <5449D6EB.8010105@oracle.com> <544AC5BD.4010407@oracle.com> <544AE2DC.2030107@oracle.com> <544D8371.3000606@oracle.com> <544EC7FA.8070902@oracle.com> <544EF9A3.8090109@oracle.com> <544F1DCA.9040304@oracle.com> <253BAE47-9732-4085-A221-16285AA62782@oracle.com> <5450521F.2050609@oracle.com> <5450837F.6090802@oracle.com> <54508B28.2000105@oracle.com> <63D2F1B3-1F79-4624-BDF2-DF3EEAFAD479@oracle.com> <54513B9A.9010606@oracle.com> <5451CBE9.4020800@oracle.com> Message-ID: <983C3BC3-6D2D-4C41-9F35-B11B6C6DEC84@oracle.com> Thanks Ioi - looks good. thanks, Karen On Oct 30, 2014, at 1:26 AM, Ioi Lam wrote: > OK, here's the latest version. I removed the synchronization but kept the resolveClass just for completeness, even if it currently does nothing. > > class Launcher$AppClassLoader { > .... > public Class loadClass(String name, boolean resolve) > throws ClassNotFoundException > { > int i = name.lastIndexOf('.'); > if (i != -1) { > SecurityManager sm = System.getSecurityManager(); > if (sm != null) { > sm.checkPackageAccess(name.substring(0, i)); > } > } > > if (ucp.knownToNotExist(name)) { > // The class of the given name is not found in the parent > // class loader as well as its local URLClassPath. > // Check if this class has already been defined dynamically; > // if so, return the loaded class; otherwise, skip the parent > // delegation and findClass. > Class c = findLoadedClass(name); > if (c != null) { > if (resolve) { > resolveClass(c); > } > return c; > } > throw new ClassNotFoundException(name); > } > > return (super.loadClass(name, resolve)); > } > > Thanks > > - Ioi > > On 10/29/14, 12:10 PM, Mandy Chung wrote: >> >> On 10/29/2014 7:16 AM, Karen Kinnear wrote: >>> Sorry, I was confused about who wrote what. >>> >>> Sounds like David and I are in agreement that you can remove the synchronization - I believe that would be much cleaner. >> >> I agree that the class loader lock is not really needed in >> the knownToNotExist case as it's checking if the class is >> loaded or not. Good catch, Karen. >> >> Mandy >> >>> And resolveClass does nothing and is final so no worries there. >>> >>> thanks, >>> Karen >>> >>> On Oct 29, 2014, at 2:37 AM, David Holmes wrote: >>> >>>> On 29/10/2014 4:04 PM, Ioi Lam wrote: >>>>> On 10/28/14, 7:34 PM, David Holmes wrote: >>>>>> Hi Karen, >>>>>> >>>>>> I haven't been tracking the details of this and am unclear on the >>>>>> overall caching strategy however ... >>>>>> >>>>>> On 29/10/2014 8:49 AM, Karen Kinnear wrote: >>>>>>> Ioi, >>>>>>> >>>>>>> Looks good! Thanks to all who have contributed! >>>>>>> >>>>>>> A couple of minor comments/questions: >>>>>>> >>>>>>> 1. jvm.h (hotspot and jdk) >>>>>>> All three APIs talk about loader_type, but the code uses loader. >>>>>>> >>>>>>> 2. Launcher.java >>>>>>> To the best of my understanding - the call to findLoadedClass does >>>>>>> not require synchronizing on the class loader lock, >>>>>>> that is needed to ensure find/define atomicity - so that we do not >>>>>>> call defineClass twice on the same class - i.e. in >>>>>>> loadClass - it is needed around the findLoadedClass / >>>>>>> findClass(defineClass) calls. This call is just a SystemDictionary >>>>>>> lookup >>>>>>> and does not require the lock to be held. >>>>>> If the class can be defined dynamically - which it appears it can >>>>>> (though I'm not sure what that means) - then you can have a race >>>>>> between the thread doing the defining and the thread doing the >>>>>> findLoadedClass. By doing findLoadedClass with the lock held you >>>>>> enforce some serialization of the actions, but there is still a race. >>>>>> So the only way the lock could matter is if user code could trigger >>>>>> the second thread's lookup of the class after the lock has been taken >>>>>> by the thread doing the dynamic definition - whether that is possible >>>>>> depends on what this dynamic definition actually is. >>>>>> >>>>> I copied the code from ClassLoader.loadClass, which does it it a >>>>> synchronized block: >>>>> >>>>> class ClassLoader { >>>>> protected Class loadClass(String name, boolean resolve) >>>>> throws ClassNotFoundException >>>>> { >>>>> synchronized (getClassLoadingLock(name)) { >>>>> // First, check if the class has already been loaded >>>>> Class c = findLoadedClass(name); >>>>> if (c == null) { >>>>> long t0 = System.nanoTime(); >>>>> try { >>>>> if (parent != null) { >>>>> c = parent.loadClass(name, false); >>>>> } else { >>>>> c = findBootstrapClassOrNull(name); >>>>> } >>>>> } catch (ClassNotFoundException e) { >>>>> // ClassNotFoundException thrown if class not found >>>>> // from the non-null parent class loader >>>>> } >>>>> >>>>> if (c == null) { >>>>> // If still not found, then invoke findClass in order >>>>> // to find the class. >>>>> long t1 = System.nanoTime(); >>>>> c = findClass(name); >>>>> >>>>> // this is the defining class loader; record the stats >>>>> sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); >>>>> sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); >>>>> sun.misc.PerfCounter.getFindClasses().increment(); >>>>> } >>>>> } >>>>> if (resolve) { >>>>> resolveClass(c); >>>>> } >>>>> return c; >>>>> } >>>>> } >>>>> >>>>> So I guess it should look like this in Launcher$AppClassLoader, just to >>>>> ensure the same things are done (regardless of whether it's necessary or >>>>> not)? >>>> In ClassLoader.loadClass it is providing atomicity across a number of actions in the worst-case: >>>> - checking for already loaded; if not then >>>> - try to load through parent; if not then >>>> - findClass (which will do defineClass) >>>> >>>> You don't have those atomicity constraints because you are only doing one thing - checking to see if the class is loaded. >>>> >>>> Your locking is probably harmless but those are famous last words when it comes to classloading. :) >>>> >>>>> Does resolveClass need to be done inside the synchronized block? >>>> Depends on whether it depends on the classloader locking to prevent concurrent resolve attempts. >>>> >>>> David >>>> ----- >>>> >>>>> class Launcher$AppClassLoader { >>>>> public Class loadClass(String name, boolean resolve) >>>>> throws ClassNotFoundException >>>>> { >>>>> int i = name.lastIndexOf('.'); >>>>> if (i != -1) { >>>>> SecurityManager sm = System.getSecurityManager(); >>>>> if (sm != null) { >>>>> sm.checkPackageAccess(name.substring(0, i)); >>>>> } >>>>> } >>>>> >>>>> if (ucp.knownToNotExist(name)) { >>>>> // The class of the given name is not found in the parent >>>>> // class loader as well as its local URLClassPath. >>>>> // Check if this class has already been defined >>>>> dynamically; >>>>> // if so, return the loaded class; otherwise, skip the >>>>> parent >>>>> // delegation and findClass. >>>>>> >from here >>>>> * synchronized (getClassLoadingLock(name)) {** >>>>> ** Class c = findLoadedClass(name);** >>>>> ** if (c != null) {** >>>>> ** if (resolve) {** >>>>> ** resolveClass(c);** >>>>> ** }** >>>>> ** return c;** >>>>> ** }** >>>>> ** }* >>>>> <>>>> throw new ClassNotFoundException(name); >>>>> } >>>>> >>>>> return (super.loadClass(name, resolve)); >>>>> } >>>>> >>>>> Thanks >>>>> - Ioi >>>>> >>>>> >>>>>> David >>>>>> >>>>>>> David H and Mandy - does that make sense to you both? >>>>>>> >>>>>>> thanks, >>>>>>> Karen >>>>>>> >>>>>>> On Oct 28, 2014, at 12:38 AM, Ioi Lam wrote: >>>>>>> >>>>>>>> On 10/27/14, 7:04 PM, Mandy Chung wrote: >>>>>>>>> On 10/27/2014 3:32 PM, Ioi Lam wrote: >>>>>>>>>> Hi David, I have update the latest webrev at: >>>>>>>>>> >>>>>>>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/ >>>>>>>>>> >>>>>>>>> The update looks good. Thanks. >>>>>>>>> >>>>>>>>>> This version also contains the JDK test case that Mandy requested: >>>>>>>>>> >>>>>>>>>> http://cr.openjdk.java.net/~iklam/8061651-lookup-index-open-v3/jdk/test/sun/misc/URLClassPath/EnableLookupCache.java.html >>>>>>>>>> >>>>>>>>>> >>>>>>>>> What I request to add is a test setting the system property >>>>>>>>> (-Dsun.cds.enableSharedLookupCache=true) and continue to load class >>>>>>>>> A and B. Removing line 44-58 should do it and also no need to set >>>>>>>>> -Dfoo.foo.bar. >>>>>>>>> >>>>>>>> Do you mean change the test to call >>>>>>>> System.setProperty("sun.cds.enableSharedLookupCache", "true")? >>>>>>>> >>>>>>>> But we know that the property is checked only once, before any app >>>>>>>> classes are loaded. So calling System.setProperty in an application >>>>>>>> class won't test anything. >>>>>>>>> It'd be good if you run this test and turn on the debug traces to >>>>>>>>> make sure that the application class loader and ext class loader >>>>>>>>> will start up with the lookup cache enabled and make up call to the >>>>>>>>> VM. As it doesn't have the app cds archive, it will invalidate the >>>>>>>>> cache right away and continue the class lookup with null cache array. >>>>>>>> In the latest code, if CDS is not available, lookupCacheEnabled will >>>>>>>> be set to false inside the static initializer of URLClassPath: >>>>>>>> >>>>>>>> private static volatile boolean lookupCacheEnabled >>>>>>>> = >>>>>>>> "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache")); >>>>>>>> >>>>>>>> later, when the boot/ext/app loaders call into here: >>>>>>>> >>>>>>>> synchronized void initLookupCache(ClassLoader loader) { >>>>>>>> if ((lookupCacheURLs = getLookupCacheURLs(loader)) != null) { >>>>>>>> lookupCacheLoader = loader; >>>>>>>> } else { >>>>>>>> // This JVM instance does not support lookup cache. >>>>>>>> disableAllLookupCaches(); >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>>>>> their lookupCacheURLs[] fields will all be set to null. As a result, >>>>>>>> getLookupCacheForClassLoader and knownToNotExist0 will never be called. >>>>>>>> >>>>>>>> I can add a DEBUG_LOOKUP_CACHE trace inside disableAllLookupCaches >>>>>>>> to print "lookup cache disabled", and check for that in the test. Is >>>>>>>> this OK? >>>>>>>> >>>>>>>> Thanks >>>>>>>> - Ioi >>>>>>>> >>>>>>>> >>>>>>>> >> > From peter.levart at gmail.com Thu Oct 30 16:53:36 2014 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 30 Oct 2014 17:53:36 +0100 Subject: RFR: 8061950: Class.getMethods() exhibits quadratic time complexity In-Reply-To: <545120D2.5010301@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <5450CEE9.7060707@gmail.com> <545120D2.5010301@gmail.com> Message-ID: <54526D10.5060101@gmail.com> Hi, Here's a patch: http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.04/ for the following issue: https://bugs.openjdk.java.net/browse/JDK-8061950 For those following the thread "Loading classes with many methods is very expensive", this is a 4th iteration of this patch. I stepped back from the approach taken in 3rd webrev and rather refined approach taken in 2nd webrev. Instead of using a LinkedHashMap with values being linked-lists of nodes holding Method objects with same signature, which couldn't be made so that iteration would follow insertion order, I used plain HashMap this time. MethodNode(s) holding Method objects form a linked list of those sharing the same signature. In addition MethodNode(s) form a separate doubly-linked list of all nodes which is used to keep insertion order. The space use should be the same as I traded two object pointers in MethodNode for two less pointers in HashMap.Entry (vs. LinkedHashMap.Entry that was used before). So insertion order is not tracked by Map but instead by MethodTable now. I also track size of MethodTable now so there's no pre-traversing pass to allocate Method[] when requested. This version seems to be the fastest from all tried so far (measured by http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/GetAllRtMethods.java using "-Dsun.reflect.noCaches=true"): Original: 19658 classes loaded in 2.027207954 seconds. 494392 methods obtained in 0.945519006 seconds. 494392 methods obtained in 0.95250834 seconds. 494392 methods obtained in 0.917841393 seconds. 494392 methods obtained in 0.971922977 seconds. 494392 methods obtained in 0.947145131 seconds. 494392 methods obtained in 0.937122672 seconds. 494392 methods obtained in 0.893975586 seconds. 494392 methods obtained in 0.90307736 seconds. 494392 methods obtained in 0.918782446 seconds. 494392 methods obtained in 0.881968668 seconds. Patched: 19658 classes loaded in 2.034081706 seconds. 494392 methods obtained in 0.8082686 seconds. 494392 methods obtained in 0.743307034 seconds. 494392 methods obtained in 0.751591979 seconds. 494392 methods obtained in 0.726954964 seconds. 494392 methods obtained in 0.761067189 seconds. 494392 methods obtained in 0.70825252 seconds. 494392 methods obtained in 0.696489363 seconds. 494392 methods obtained in 0.692555238 seconds. 494392 methods obtained in 0.695150116 seconds. 494392 methods obtained in 0.697665068 seconds. I also updated the test that checks multiple inheritance of abstract methods as I found that my 1st iteration of the algorithm was not getting the same results as original code although all jtreg tests were passing. I added 4 cases that include abstract classes as well as interfaces to the mix. Some of them would fail with my 1st version of algorithm. All 86 jtreg tests in java/lang/reflect/ and java/lang/Class/ pass with this patch applied. Regards, Peter From martinrb at google.com Thu Oct 30 17:15:10 2014 From: martinrb at google.com (Martin Buchholz) Date: Thu, 30 Oct 2014 10:15:10 -0700 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: <5452383C.2030208@oracle.com> References: <5452383C.2030208@oracle.com> Message-ID: Here's the state of the world: - the Unix designers made a design mistake that file descriptors are inherited by subprocesses by default. - all library code (almost all the code in the universe, including the JDK) needs to coexist with foreign code that might fork+exec at any time - to ensure that file descriptors don't leak into subprocesses, (almost) all library calls that create file descriptors must ensure that they have the close-on-exec bit set. (yes, this has been broken for a long time) - this is difficult enough that all creations of file descriptors must be wrapped using some kind of common infrastructure - JVM_Open (aka os::open) was terrible infrastructure (essentially undocumented) but at least it *was* infrastructure - we need openjdk-level or at least core-libraries-level native infrastructure, a place to put things like os::open and readFully. A project-wide commitment From martinrb at google.com Thu Oct 30 17:26:05 2014 From: martinrb at google.com (Martin Buchholz) Date: Thu, 30 Oct 2014 10:26:05 -0700 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: <5452383C.2030208@oracle.com> References: <5452383C.2030208@oracle.com> Message-ID: On Thu, Oct 30, 2014 at 6:08 AM, Alan Bateman wrote: > The change in behavior from JVM_Open ito open was missed but there is a long > way to go in JDK 9 so lots of time to fix the issue (if there is an issue). The changes to zip file file descriptors is just the one most visible to me. > As was noted in one of the replies, the only usages of JVM_Open were in the > zip code, it hasn't been used consistently used in the libraries for at > least 10+ years. When doing significant changes then thorough code reviews > are important but good tests are equally, and sometimes more, important. I > understand that having a test for the O_CLOEXEC might be too hard so I'm > interested to know how you ran into it. Maybe it was inspection? My hobby is running strace on the JDK and counting the fds with close-on-exec flag. I noticed that the calls to fcntl(...FD_CLOEXEC) had disappeared! You're unlikely to get bug reports because of the action-at-a-distance non-debuggability. > Maybe an > app that opens lots of zip files and executes fork/exec itself? For > ProcessBuilder and Runtime.exec usages then the I thought the childproc code > handled this by looping over the open file descriptors and closing them. So > even if O_CLOEXEC or fcntl(FD_CLOEXEC) isn't used then it should be closed > in the child. In general, Java is just a guest inside some Unix process, and should be well-behaved. > As to whether we need a JVM_Open replacement in libjava then maybe we do but > I think it needs a discussion as to whether the JDK really needs a porting > interface or just useful infrastructure. Also I think going forward then I > assume that the amount of native code will reduce, particularly when FFI > comes along and we start to get rid of some of the native code (at least I > hope that happens). I think it will just become more convenient to call the native code. Perhaps the common infrastructure can be written in Java, but it should still exist. > In the mean-time then I think I'd like to understand more as to whether the > O_CLOEXEC is an issue or not. Aside from the zip code then I don't think > we've been using it consistently so I'm wondering if the issue is some > native code calling fork+exec or something else? Yes. All broken since forever. I'm focused on close-on-exec, but there's also restartable system calls to consider. And partial reads ... From martinrb at google.com Thu Oct 30 17:30:13 2014 From: martinrb at google.com (Martin Buchholz) Date: Thu, 30 Oct 2014 10:30:13 -0700 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: References: <20141029204640.9995417FDA3@rebar.astron.com> <5451FAFF.3060007@oracle.com> <545208BE.90104@oracle.com> Message-ID: On Thu, Oct 30, 2014 at 3:24 AM, Mario Torre wrote: > I've been thinking perhaps one can use fcntl to check what flags are > passed given we can retrieve all the file descriptors that have been > opened? It's possible to find all the open file descriptors (e.g. using /proc/self/fd), but they may not "belong" to the JDK. From lance.andersen at oracle.com Thu Oct 30 17:38:26 2014 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 30 Oct 2014 13:38:26 -0400 Subject: RFR: 8062558, Add javax/sql/rowset/spi tests Message-ID: <9FC758BA-78EC-47D7-BC1B-5DF0918DFB83@oracle.com> Hi all, Looking for a reviewer for the javax/sql/rowset/spi tests The webrev can be found at http://cr.openjdk.java.net/~lancea/8062558/webrev.00/ Best Lance Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From neugens.limasoftware at gmail.com Thu Oct 30 17:52:30 2014 From: neugens.limasoftware at gmail.com (Mario Torre) Date: Thu, 30 Oct 2014 18:52:30 +0100 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: References: <20141029204640.9995417FDA3@rebar.astron.com> <5451FAFF.3060007@oracle.com> <545208BE.90104@oracle.com> Message-ID: Indeed, but /proc/$PID/fd can perhaps be useful here? Not sure if this can make a reasonable test though. Cheers, Mario 2014-10-30 18:30 GMT+01:00 Martin Buchholz : > On Thu, Oct 30, 2014 at 3:24 AM, Mario Torre > wrote: >> I've been thinking perhaps one can use fcntl to check what flags are >> passed given we can retrieve all the file descriptors that have been >> opened? > > It's possible to find all the open file descriptors (e.g. using > /proc/self/fd), but they may not "belong" to the JDK. -- pgp key: http://subkeys.pgp.net/ PGP Key ID: 80F240CF Fingerprint: BA39 9666 94EC 8B73 27FA FC7C 4086 63E3 80F2 40CF Java Champion - Blog: http://neugens.wordpress.com - Twitter: @neugens Proud GNU Classpath developer: http://www.classpath.org/ OpenJDK: http://openjdk.java.net/projects/caciocavallo/ Please, support open standards: http://endsoftpatents.org/ From frederic.parain at oracle.com Thu Oct 30 17:54:02 2014 From: frederic.parain at oracle.com (frederic parain) Date: Thu, 30 Oct 2014 18:54:02 +0100 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: References: <5452383C.2030208@oracle.com> Message-ID: <54527B3A.6010904@oracle.com> My bad. I missed the FD_CLOEXEC flag added by os::open() when I replaced JVM_Open with open in zip native code. However, I still think that removing those interfaces was a good move. But I understand that the change it introduces with zip file descriptors is an issue. Reverting the changeset to re-introduce JVM_Open is not a solution. Maintaining a VM interface only adding a flag for only 2 call sites doesn't make sense to me. Either the file descriptor leak issue is specific to the zip package and can be fixed locally. Or the issue impacts more native code and adding an infrastructure to libjava should be discussed. Quickly grepping the code, I found many naked calls to open, but only one use of FD_CLOEXEC. Further investigations would be required to track potential file descriptor leaks in all libraries. Did you create a bug to track this issue yet? Regards, Fred On 30/10/2014 18:15, Martin Buchholz wrote: > Here's the state of the world: > - the Unix designers made a design mistake that file descriptors are > inherited by subprocesses by default. > - all library code (almost all the code in the universe, including the > JDK) needs to coexist with foreign code that might fork+exec at any > time > - to ensure that file descriptors don't leak into subprocesses, > (almost) all library calls that create file descriptors must ensure > that they have the close-on-exec bit set. (yes, this has been broken > for a long time) > - this is difficult enough that all creations of file descriptors must > be wrapped using some kind of common infrastructure > - JVM_Open (aka os::open) was terrible infrastructure (essentially > undocumented) but at least it *was* infrastructure > - we need openjdk-level or at least core-libraries-level native > infrastructure, a place to put things like os::open and readFully. A > project-wide commitment > -- Frederic Parain - Oracle Grenoble Engineering Center - France Phone: +33 4 76 18 81 17 Email: Frederic.Parain at oracle.com From martinrb at google.com Thu Oct 30 18:13:30 2014 From: martinrb at google.com (Martin Buchholz) Date: Thu, 30 Oct 2014 11:13:30 -0700 Subject: RFR: 8061950: Class.getMethods() exhibits quadratic time complexity In-Reply-To: <54526D10.5060101@gmail.com> References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <5450CEE9.7060707@gmail.com> <545120D2.5010301@gmail.com> <54526D10.5060101@gmail.com> Message-ID: Hi Peter! Thanks for all your hard work. Your patch is hard to digest, but some initial comments anyways: --- I'm surprised you got this much performance gain loading rt.jar methods. It looks like you are creating a more sophisticated data structure with more garbage, which won't show up as much on our small-memory benchmarks. Which is why I was expecting to have to write an adaptive data structure that switches from linear search to hash-based when some threshold is exceeded. --- (The introduction of default methods into openjdk makes method lookup even more confusing, and scares me, especially since I am uncertain we have enough tests...) --- If your changes to StarInheritance.java are general improvements, we could/should just check them in now (TDD?). --- Use javadoc comments /** even for private methods + /* This method returns 'root' Constructor object. It MUST be copied with ReflectionFactory + * before handed to any code outside java.lang.Class or modified. + */ private Constructor getConstructor0(Class[] parameterTypes, --- The java way is to spell intfcsMethods "interfacesMethods" On Thu, Oct 30, 2014 at 9:53 AM, Peter Levart wrote: > Hi, > > Here's a patch: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.04/ > > for the following issue: > > https://bugs.openjdk.java.net/browse/JDK-8061950 > > For those following the thread "Loading classes with many methods is very > expensive", this is a 4th iteration of this patch. I stepped back from the > approach taken in 3rd webrev and rather refined approach taken in 2nd > webrev. Instead of using a LinkedHashMap with values being linked-lists of > nodes holding Method objects with same signature, which couldn't be made so > that iteration would follow insertion order, I used plain HashMap this time. > MethodNode(s) holding Method objects form a linked list of those sharing the > same signature. In addition MethodNode(s) form a separate doubly-linked list > of all nodes which is used to keep insertion order. The space use should be > the same as I traded two object pointers in MethodNode for two less pointers > in HashMap.Entry (vs. LinkedHashMap.Entry that was used before). So > insertion order is not tracked by Map but instead by MethodTable now. I also > track size of MethodTable now so there's no pre-traversing pass to allocate > Method[] when requested. > > This version seems to be the fastest from all tried so far (measured by > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/GetAllRtMethods.java > using "-Dsun.reflect.noCaches=true"): > > Original: > > 19658 classes loaded in 2.027207954 seconds. > 494392 methods obtained in 0.945519006 seconds. > 494392 methods obtained in 0.95250834 seconds. > 494392 methods obtained in 0.917841393 seconds. > 494392 methods obtained in 0.971922977 seconds. > 494392 methods obtained in 0.947145131 seconds. > 494392 methods obtained in 0.937122672 seconds. > 494392 methods obtained in 0.893975586 seconds. > 494392 methods obtained in 0.90307736 seconds. > 494392 methods obtained in 0.918782446 seconds. > 494392 methods obtained in 0.881968668 seconds. > > Patched: > > 19658 classes loaded in 2.034081706 seconds. > 494392 methods obtained in 0.8082686 seconds. > 494392 methods obtained in 0.743307034 seconds. > 494392 methods obtained in 0.751591979 seconds. > 494392 methods obtained in 0.726954964 seconds. > 494392 methods obtained in 0.761067189 seconds. > 494392 methods obtained in 0.70825252 seconds. > 494392 methods obtained in 0.696489363 seconds. > 494392 methods obtained in 0.692555238 seconds. > 494392 methods obtained in 0.695150116 seconds. > 494392 methods obtained in 0.697665068 seconds. > > > I also updated the test that checks multiple inheritance of abstract methods > as I found that my 1st iteration of the algorithm was not getting the same > results as original code although all jtreg tests were passing. I added 4 > cases that include abstract classes as well as interfaces to the mix. Some > of them would fail with my 1st version of algorithm. > > All 86 jtreg tests in java/lang/reflect/ and java/lang/Class/ pass with this > patch applied. > > > Regards, Peter > From martinrb at google.com Thu Oct 30 18:26:06 2014 From: martinrb at google.com (Martin Buchholz) Date: Thu, 30 Oct 2014 11:26:06 -0700 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: References: <20141029204640.9995417FDA3@rebar.astron.com> <5451FAFF.3060007@oracle.com> <545208BE.90104@oracle.com> Message-ID: On Thu, Oct 30, 2014 at 10:52 AM, Mario Torre wrote: > Indeed, but /proc/$PID/fd can perhaps be useful here? Not sure if this > can make a reasonable test though. Mario, I'm not sure what you mean. Even if we can find and inspect each fd, and even if we knew the stacktrace of where every fd was created, we still wouldn't know which close-on-exec flag should be cleared. From christos at zoulas.com Thu Oct 30 18:35:36 2014 From: christos at zoulas.com (Christos Zoulas) Date: Thu, 30 Oct 2014 14:35:36 -0400 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: from Martin Buchholz (Oct 30, 11:26am) Message-ID: <20141030183536.E77BD17FDA3@rebar.astron.com> On Oct 30, 11:26am, martinrb at google.com (Martin Buchholz) wrote: -- Subject: Re: Losing features of JVM_Open, e.g. CLOEXEC | On Thu, Oct 30, 2014 at 10:52 AM, Mario Torre | wrote: | > Indeed, but /proc/$PID/fd can perhaps be useful here? Not sure if this | > can make a reasonable test though. | | Mario, I'm not sure what you mean. | | Even if we can find and inspect each fd, and even if we knew the | stacktrace of where every fd was created, we still wouldn't know which | close-on-exec flag should be cleared. Let's not forget O_NOSIGPIPE, (and the equivalent SOCK_CLOEXEC and SOCK_NOSIGPIPE, for socket(2)). Also all the dup*(), pipe*(), kqueue*(), and fcntl() calls -- (in general all the system calls that can create file descriptors). christos From martinrb at google.com Thu Oct 30 18:42:32 2014 From: martinrb at google.com (Martin Buchholz) Date: Thu, 30 Oct 2014 11:42:32 -0700 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: <54527B3A.6010904@oracle.com> References: <5452383C.2030208@oracle.com> <54527B3A.6010904@oracle.com> Message-ID: Hi Frederic, On Thu, Oct 30, 2014 at 10:54 AM, frederic parain wrote: > My bad. I missed the FD_CLOEXEC flag added by os::open() > when I replaced JVM_Open with open in zip native code. > > However, I still think that removing those interfaces > was a good move. But I understand that the change it > introduces with zip file descriptors is an issue. By itself, it is not so bad - I I've been saying, the overall situation has been broken since forever. > Reverting the changeset to re-introduce JVM_Open is > not a solution. Maintaining a VM interface only adding > a flag for only 2 call sites doesn't make sense to me. I agree this should not be a "VM interface", so in that sense your change is an improvement! But we still need a common infrastructure/porting layer... and instead we're working on dismantling any that we have... > Either the file descriptor leak issue is specific to > the zip package and can be fixed locally. Or the issue > impacts more native code and adding an infrastructure > to libjava should be discussed. Quickly grepping the > code, I found many naked calls to open, but only one > use of FD_CLOEXEC. Further investigations would be > required to track potential file descriptor leaks in > all libraries. > > Did you create a bug to track this issue yet? Nope. But if I did, what component/sub-component would it go into.? We don't even seem to have a place to report cross-library bugs! We have no infrastructure to work on the "no infrastructure" problem! From stuart.marks at oracle.com Thu Oct 30 19:12:17 2014 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 30 Oct 2014 12:12:17 -0700 Subject: RFR (s): 4354680: Runtime.runFinalization() silently clears interrupted flag in the calling thread In-Reply-To: References: <54518EAD.3060504@oracle.com> <5451A0DB.3030303@oracle.com> <5451E967.3060900@oracle.com> Message-ID: <54528D91.6020703@oracle.com> On 10/30/14 2:21 AM, Chris Hegarty wrote: > On 30 Oct 2014, at 07:31, David Holmes wrote: >> On 30/10/2014 4:00 PM, Stanimir Simeonoff wrote: >>> It could be defense vs Thread.currentThread().run() in finalizer that >>> would cause calling run() of Thread.target. I am not sure if that would >>> cause invocation, though. >> >> That is an excellent point! But it deserves a comment in the code. > > Adding a comment is fine, but please to not remove this field. ?hg log? may reveal more about it?s origins. Oh yes, quite right. I'll leave the field as-is, and add a comment here and to the other locations in this file to inform future maintainers. s'marks From eric.mccorkle at oracle.com Thu Oct 30 23:41:23 2014 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Thu, 30 Oct 2014 19:41:23 -0400 Subject: Review request: JDK-8062556: Add jdk tests for JDK-8058322 and JDK-8058313 Message-ID: <5452CCA3.5040001@oracle.com> Hello, Please review this patch which adds tests to the JDK test suite for two reflection bugs that require hotspot changes (JDK-8058322 and JDK-8058313) The webrev is here: http://cr.openjdk.java.net/~emc/8062556/ From brian.goetz at oracle.com Thu Oct 30 23:45:51 2014 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 30 Oct 2014 19:45:51 -0400 Subject: Review request: JDK-8062556: Add jdk tests for JDK-8058322 and JDK-8058313 In-Reply-To: <5452CCA3.5040001@oracle.com> References: <5452CCA3.5040001@oracle.com> Message-ID: <5452CDAF.2020601@oracle.com> I realize you are just adding new bad class files to an existing test, so you're just copying the idiom in the test, but it would be 1000 times more helpful if the comments included a javap or similar listing or even a description of what (bad) class this byte[] array purports to be. Otherwise, how can anyone review that the test does what it claims, other than by hand-disassembling this byte array? On 10/30/2014 7:41 PM, Eric McCorkle wrote: > Hello, > > Please review this patch which adds tests to the JDK test suite for two > reflection bugs that require hotspot changes (JDK-8058322 and JDK-8058313) > > The webrev is here: > http://cr.openjdk.java.net/~emc/8062556/ > From huizhe.wang at oracle.com Thu Oct 30 23:46:43 2014 From: huizhe.wang at oracle.com (huizhe wang) Date: Thu, 30 Oct 2014 16:46:43 -0700 Subject: RFR: 8062558, Add javax/sql/rowset/spi tests In-Reply-To: <9FC758BA-78EC-47D7-BC1B-5DF0918DFB83@oracle.com> References: <9FC758BA-78EC-47D7-BC1B-5DF0918DFB83@oracle.com> Message-ID: <5452CDE3.70303@oracle.com> +1. Nice to improve test coverage. -Joe On 10/30/2014 10:38 AM, Lance Andersen wrote: > Hi all, > > Looking for a reviewer for the javax/sql/rowset/spi tests > > The webrev can be found at http://cr.openjdk.java.net/~lancea/8062558/webrev.00/ > > > Best > Lance > > > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 > Oracle Java Engineering > 1 Network Drive > Burlington, MA 01803 > Lance.Andersen at oracle.com > > > From david.holmes at oracle.com Fri Oct 31 01:59:17 2014 From: david.holmes at oracle.com (David Holmes) Date: Fri, 31 Oct 2014 11:59:17 +1000 Subject: Review request: JDK-8062556: Add jdk tests for JDK-8058322 and JDK-8058313 In-Reply-To: <5452CCA3.5040001@oracle.com> References: <5452CCA3.5040001@oracle.com> Message-ID: <5452ECF5.7020607@oracle.com> Hi Erik, On 31/10/2014 9:41 AM, Eric McCorkle wrote: > Hello, > > Please review this patch which adds tests to the JDK test suite for two > reflection bugs that require hotspot changes (JDK-8058322 and JDK-8058313) > > The webrev is here: > http://cr.openjdk.java.net/~emc/8062556/ I second Brian's comment re the source of the bad classes. Your webrev is broken btw - no top-level html files. The new test needs a copyright year of 2014 not 2013. Thanks, David From konstantin.shefov at oracle.com Fri Oct 31 10:17:17 2014 From: konstantin.shefov at oracle.com (Konstantin Shefov) Date: Fri, 31 Oct 2014 03:17:17 -0700 (PDT) Subject: [9] Review request : JDK-8059070: [TESTBUG] java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java failed - timeout Message-ID: Please, review a test bug fix. http://cr.openjdk.java.net/~kshefov/8059070/webrev.01/ -Konstantin On 27.10.2014 13:16, Konstantin Shefov wrote: > Kindly reminder > > On 23.10.2014 19:04, Paul Sandoz wrote: >> On Oct 23, 2014, at 1:25 PM, Konstantin Shefov >> wrote: >>> Gently reminder >>> >>> On 17.10.2014 13:38, Konstantin Shefov wrote: >>>> Hi, >>>> >>>> I have updated the webrev: >>>> http://cr.openjdk.java.net/~kshefov/8059070/webrev.01/ >>>> >> +1 >> >> Sorry for the delay, >> Paul. > From stanimir at riflexo.com Fri Oct 31 10:50:31 2014 From: stanimir at riflexo.com (Stanimir Simeonoff) Date: Fri, 31 Oct 2014 12:50:31 +0200 Subject: RFR: 8061950: Class.getMethods() exhibits quadratic time complexity In-Reply-To: References: <900D2AE3-B3A6-4B1B-B25A-C564B10334AA@oracle.com> <54492255.3040108@gmail.com> <544D58D4.7020909@gmail.com> <544D7B74.5060607@gmail.com> <5450CEE9.7060707@gmail.com> <545120D2.5010301@gmail.com> <54526D10.5060101@gmail.com> Message-ID: Hi, Personally I have no objections to the latest webrev. > It looks like you are creating a more sophisticated data structure > with more garbage, which won't show up as much on our small-memory > benchmarks. Which is why I was expecting to have to write an adaptive > data structure that switches from linear search to hash-based when > some threshold is exceeded. > > There is a hidden cost in calling Method.getParameterTypes() even with linear search. Although it can be optimized to always first check Method.getName() for reference equality So the new approach creates 2 more short lived objects per Method - HashMap.Node and the MethodList. MethodTable.Impl and its underlying Object[] are one time off as they are properly sized. I have no objection if the instances die trivially in the young gen. A possible optimization would be using a short-circuit in case of no interfaces and extending directly java.lang.Object (quite a common case). But even then the Object has quite a few public methods [getClass(), notify(), notiftyAll(), wait(), wait(long, int), wait(long), toString(), hashCode(), equals(Object)], so it requires another HashMap and checking how many of them are overridden. That also reminds me: Object methods should always be cached, regardless of the config flag. Object class cannot be redefined and the memory is constant. Stanimir --- > > (The introduction of default methods into openjdk makes method lookup > even more confusing, and scares me, especially since I am uncertain we > have enough tests...) > > --- > > If your changes to StarInheritance.java are general improvements, we > could/should just check them in now (TDD?). > > --- > > Use javadoc comments /** even for private methods > > + /* This method returns 'root' Constructor object. It MUST be > copied with ReflectionFactory > + * before handed to any code outside java.lang.Class or modified. > + */ > private Constructor getConstructor0(Class[] parameterTypes, > > > --- > > The java way is to spell intfcsMethods "interfacesMethods" > > > > On Thu, Oct 30, 2014 at 9:53 AM, Peter Levart > wrote: > > Hi, > > > > Here's a patch: > > > > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.04/ > > > > for the following issue: > > > > https://bugs.openjdk.java.net/browse/JDK-8061950 > > > > For those following the thread "Loading classes with many methods is very > > expensive", this is a 4th iteration of this patch. I stepped back from > the > > approach taken in 3rd webrev and rather refined approach taken in 2nd > > webrev. Instead of using a LinkedHashMap with values being linked-lists > of > > nodes holding Method objects with same signature, which couldn't be made > so > > that iteration would follow insertion order, I used plain HashMap this > time. > > MethodNode(s) holding Method objects form a linked list of those sharing > the > > same signature. In addition MethodNode(s) form a separate doubly-linked > list > > of all nodes which is used to keep insertion order. The space use should > be > > the same as I traded two object pointers in MethodNode for two less > pointers > > in HashMap.Entry (vs. LinkedHashMap.Entry that was used before). So > > insertion order is not tracked by Map but instead by MethodTable now. I > also > > track size of MethodTable now so there's no pre-traversing pass to > allocate > > Method[] when requested. > > > > This version seems to be the fastest from all tried so far (measured by > > > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/GetAllRtMethods.java > > using "-Dsun.reflect.noCaches=true"): > > > > Original: > > > > 19658 classes loaded in 2.027207954 seconds. > > 494392 methods obtained in 0.945519006 seconds. > > 494392 methods obtained in 0.95250834 seconds. > > 494392 methods obtained in 0.917841393 seconds. > > 494392 methods obtained in 0.971922977 seconds. > > 494392 methods obtained in 0.947145131 seconds. > > 494392 methods obtained in 0.937122672 seconds. > > 494392 methods obtained in 0.893975586 seconds. > > 494392 methods obtained in 0.90307736 seconds. > > 494392 methods obtained in 0.918782446 seconds. > > 494392 methods obtained in 0.881968668 seconds. > > > > Patched: > > > > 19658 classes loaded in 2.034081706 seconds. > > 494392 methods obtained in 0.8082686 seconds. > > 494392 methods obtained in 0.743307034 seconds. > > 494392 methods obtained in 0.751591979 seconds. > > 494392 methods obtained in 0.726954964 seconds. > > 494392 methods obtained in 0.761067189 seconds. > > 494392 methods obtained in 0.70825252 seconds. > > 494392 methods obtained in 0.696489363 seconds. > > 494392 methods obtained in 0.692555238 seconds. > > 494392 methods obtained in 0.695150116 seconds. > > 494392 methods obtained in 0.697665068 seconds. > > > > > > I also updated the test that checks multiple inheritance of abstract > methods > > as I found that my 1st iteration of the algorithm was not getting the > same > > results as original code although all jtreg tests were passing. I added 4 > > cases that include abstract classes as well as interfaces to the mix. > Some > > of them would fail with my 1st version of algorithm. > > > > All 86 jtreg tests in java/lang/reflect/ and java/lang/Class/ pass with > this > > patch applied. > > > > > > Regards, Peter > > > From frederic.parain at oracle.com Fri Oct 31 12:27:31 2014 From: frederic.parain at oracle.com (frederic parain) Date: Fri, 31 Oct 2014 13:27:31 +0100 Subject: Losing features of JVM_Open, e.g. CLOEXEC In-Reply-To: References: <5452383C.2030208@oracle.com> <54527B3A.6010904@oracle.com> Message-ID: <54538033.50600@oracle.com> On 30/10/2014 19:42, Martin Buchholz wrote: >> Either the file descriptor leak issue is specific to >> the zip package and can be fixed locally. Or the issue >> impacts more native code and adding an infrastructure >> to libjava should be discussed. Quickly grepping the >> code, I found many naked calls to open, but only one >> use of FD_CLOEXEC. Further investigations would be >> required to track potential file descriptor leaks in >> all libraries. >> >> Did you create a bug to track this issue yet? > > Nope. But if I did, what component/sub-component would it go into.? > We don't even seem to have a place to report cross-library bugs! We > have no infrastructure to work on the "no infrastructure" problem! I'd suggest to create a first bug in core-libs to create the infrastructure, and then other libs can refer to this bug to fix their own code. But it would be better to have core-libs team opinion before doing this. Regards, Fred -- Frederic Parain - Oracle Grenoble Engineering Center - France Phone: +33 4 76 18 81 17 Email: Frederic.Parain at oracle.com From eric.mccorkle at oracle.com Fri Oct 31 14:01:09 2014 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Fri, 31 Oct 2014 10:01:09 -0400 Subject: Review request: JDK-8062556: Add jdk tests for JDK-8058322 and JDK-8058313 In-Reply-To: <5452ECF5.7020607@oracle.com> References: <5452CCA3.5040001@oracle.com> <5452ECF5.7020607@oracle.com> Message-ID: <54539625.7070302@oracle.com> I went through and added comments in the binary data indicating where the MethodParameters attributes are, and a breakdown of their contents. I went ahead and did this for all the bad class files, not just the new ones. There is a larger picture here: there's an outstanding task I filed around the time these tests were written to find a better way for langtools to run jtreg tests that involve bad class files. Unfortunately, doing that is rather difficult, as you can see. The only real way to do it is to generate a class file, convert it to signed bytes (you can't even use hex; you get an unsigned/signed byte conversion problem), then modify the data by hand. The intent is to replace this with a better method at some point. On 10/30/14 21:59, David Holmes wrote: > Hi Erik, > > On 31/10/2014 9:41 AM, Eric McCorkle wrote: >> Hello, >> >> Please review this patch which adds tests to the JDK test suite for two >> reflection bugs that require hotspot changes (JDK-8058322 and >> JDK-8058313) >> >> The webrev is here: >> http://cr.openjdk.java.net/~emc/8062556/ > > I second Brian's comment re the source of the bad classes. > > Your webrev is broken btw - no top-level html files. > > The new test needs a copyright year of 2014 not 2013. > > Thanks, > David > From eric.mccorkle at oracle.com Fri Oct 31 16:15:06 2014 From: eric.mccorkle at oracle.com (Eric McCorkle) Date: Fri, 31 Oct 2014 12:15:06 -0400 Subject: Review request for 8055063: Parameter#toString() fails w/ AIOOBE for ctr of inner class w/ generic type Message-ID: <5453B58A.1090507@oracle.com> Hello, Please review this patch which fixes issues that arise with getGenericParameterTypes() and getAnnotatedParameterTypes() when there are generic signatures and synthetic parameters. Please note that a complete fix is not possible for all cases. See discussion on https://bugs.openjdk.java.net/browse/JDK-8062582 for details. This patch will cause Executable.getAnnotatedParameterTypes(), Parameter.getAnnotatedType(), and Parameter.getParameterizedType() to report the correct types in the following cases: * No generic signature is present. * Both a generic signature and method parameters information are present * A generic signature is present, but method parameters information is not present, but the number of parameters in the generic signature and the number of parameters in the method descriptor are the same. In the problematic case, where there is a generic signature, no method parameters information, and the generic signature does not match the method descriptor, these methods will return the correct /non/-generic type, as there is no general way of associating parameters in the generic signature with those in the method descriptor in this case. Please also note that there is currently a bug in javac which causes type annotations' parameter indexes to be wrong when synthetic parameters are generated: https://bugs.openjdk.java.net/browse/JDK-8029012. The bug report is here: https://bugs.openjdk.java.net/browse/JDK-8055063 The webrev is here: http://cr.openjdk.java.net/~emc/8055063/ From tristan.yan at oracle.com Fri Oct 31 19:16:53 2014 From: tristan.yan at oracle.com (Tristan Yan) Date: Fri, 31 Oct 2014 12:16:53 -0700 Subject: RFR 8047962: XML test colocation: AuctionPortal test for bid.com Message-ID: Hi Joe, Alan and all others Would you please help reviewing these tests? The intent is moving some JAXP tests from closed to open. The associated bug number is https://bugs.openjdk.java.net/browse/JDK-8047962 . These tests have been ran with and without the Security Manager. All the tests pass under both scenarios. http://cr.openjdk.java.net/~tyan/JDK-8047962/webrev.01/ Thank you. Tristan