From david.holmes at oracle.com Mon Apr 1 04:27:04 2019 From: david.holmes at oracle.com (David Holmes) Date: Mon, 1 Apr 2019 14:27:04 +1000 Subject: RFR: 8221477: Inject os/cpu-specific constants into Unsafe from JVM In-Reply-To: <2a26715f-fa64-9de4-1071-b18d07c05511@redhat.com> References: <2fc62430-2e2e-9ee5-ccf1-f1cde5cea416@redhat.com> <8b0f5b4c-0386-1440-6939-646daf36aa55@redhat.com> <24b4bb72-732e-0447-d1be-dd71507e7787@redhat.com> <945d9546-5195-ab33-0e20-57871c2f1ef9@oracle.com> <2a26715f-fa64-9de4-1071-b18d07c05511@redhat.com> Message-ID: <936d213e-9c75-6af4-a7f6-bab6a0f320bb@oracle.com> Hi Andrew, On 29/03/2019 8:40 pm, Andrew Dinn wrote: > Hi David, > > Thanks very much for reviewing this patch. > > On 29/03/2019 01:25, David Holmes wrote: >> This seems fine in general but I have a few queries on some details: >> >> src/hotspot/share/classfile/javaClasses.hpp >> >> ??? f(java_lang_Thread) \ >> +?? f(jdk_internal_misc_UnsafeConstants) \ >> ??? f(java_lang_ThreadGroup) \ >> >> Is there a reason this needs to be shoved in there? Similarly with >> src/hotspot/share/classfile/systemDictionary.hpp: >> >> ?? do_klass(Thread_klass, >> java_lang_Thread????????????????????????????????????? ) \ >> +?? do_klass(UnsafeConstants_klass, >> jdk_internal_misc_UnsafeConstants???????????????????? ) \ >> ??? do_klass(ThreadGroup_klass, >> java_lang_ThreadGroup???????????????????????????????? ) \ >> >> ? > > I'm not sure what you are asking here. Are you talking about the > positioning of these entries? If so then the reason for choosing those > positions was because they match the position of the corresponding class > initialization calls in the file thread.cpp. As to that choice ... see > below. Yes I'm asking about the positioning ... >> src/hotspot/share/runtime/thread.cpp >> >> ??? main_thread->set_threadObj(thread_object); >> + >> +?? // initialize the hardware-specific constants needed by Unsafe >> +?? initialize_class(vmSymbols::jdk_internal_misc_UnsafeConstants(), >> CHECK); >> +?? jdk_internal_misc_UnsafeConstants::set_unsafe_constants(); >> + >> ??? // Set thread status to running since main thread has >> ??? // been started and running. >> ??? java_lang_Thread::set_thread_status(thread_object, >> >> That seems a very odd place to insert the new initialization. I can't >> see any reason you'd need to split the Thread object initialization like >> that. ?? > > Well, yes, indeed :-). I was not sure where this init needed to go so I > simply put it in as early as I thought was safe. Clearly, it is an > interloper into intitialise_java_lang_classes() but I was not sure where > else was more appropriate. > > I don't think it matters too much where this init happens so long as it > is early enough to precede any clinit dependencies on Unsafe (see > below). I'm very happy to take advice on this (indeed I was hoping/ > expecting it would be brought up at review) and also on where the > entries in the headers would best be placed. > >> More generally exactly when do you need to initialize this new class by >> and how does the initialization order change before/after this fix? (I'm >> expecting only to see the new class inserted where needed without any >> other perturbations.) > > As I said, I put the class initialization in at this early point simply > to guarantee that the constants are available before Unsafe or any class > which might recursively initialize Unsafe could end up needing them. I > am sure they could move later and also earlier, although the latter > would probably not make any sense. The important thing is that they > don't really have any hard dependencies on other class inits apart, > perhaps, from 'magic' classes like Object, Class etc which need to exist > in order to init /any/ other class. I did some analysis of the class loading and initialization sequence and added my suggestions to bug report. In summary loading seems somewhat immaterial so I suggest: - javaClasses.hpp: Add UnsafeConstants at the end of BASIC_JAVA_CLASSES_DO_PART2 - systemDictionary.hpp: Add UnsafeConstants immediately before Unsafe Then for init: - thread.cpp: initialize UnsafeConstants immediately after j.l.Module It would be desirable to detect if we happen to execute the earlier (by accident) so I suggest adding a "not initialized" assertion prior to your code calling initialize_class. Actually that might be a useful addition to the initialize_class method, as if it fires it means we're not initializing in the expected order ... I'll run a little adding that ... Thanks, David P.S. This missing space in javaClasses.cpp was reported by Thomas but hasn't been fixed yet: 4026 }else { > I deliberately factored these constants out of Unsafe into a separate > all static class UnsafeConstants so as to decouple this init from any > current or future dependencies on Unsafe (and also to make them more > clearly visible). Since the fields only hold os/hw specific constants > they can be set any time after VM_Version/CPU-specific init and > OS-specific init has completed. > >> src/hotspot/share/classfile/vmSymbols.hpp >> >> +?? template(big_endian_name,?????????????????????????? "BIG_ENDIAN") >> ?????????????????????????? \ >> +?? template(use_unaligned_access_name, >> "UNALIGNED_ACCESS")??????????????????????? \ >> >> Nit: There's an extra space before "UNALIGNED... > > Thanks. Thomas Stuefe already spotted that and I have updated the webrev > in place to fix it. > >> src/java.base/share/classes/jdk/internal/misc/UnsafeConstants.java >> >> 31? * package-protected? ... >> >> s/protected/private/ > > Thanks, will correct it. > >> ?37? * The JVM injects values into all the static fields of this class >> ?... >> ?43? * hardware-specific constants installed by the JVM. >> >> I get this gist of this note but still found it rather difficult to >> intepret. There are I think two key points: >> >> 1. The fields must not be constant variables, hence the need for the >> static initialization block. >> 2. The true value of each field is injected by the VM. >> >> How about: >> >> * The JVM injects hardware-specific values into all the static fields >> * of this class during JVM initialization. The static initialization >> * block exists to prevent the fields from being considered constant >> * variables, so the field values will be not be compiled directly into >> * any class that uses them. > > Yes, I agree that is clearer. > >> 60????? * @implNote >> 61????? * The actual value for this field is injected by JVM. A static >> 62????? * initialization block is used to set the value here to >> 63????? * communicate that this static final field is not statically >> 64????? * foldable, and to avoid any possible circular dependency during >> 65????? * vm initialization. >> >> I think all you need for each field is just: >> >> * @implNote >> * The actual value for this field is injected by _the_ JVM. > > Yes, also better. > >> 85????? * flag whose value ... >> 92????? * flag whose value ... >> >> s/flag/Flag/ > > Thanks, will correct this. > > regards, > > > Andrew Dinn > ----------- > Senior Principal Software Engineer > Red Hat UK Ltd > Registered in England and Wales under Company Registration No. 03798903 > Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander > From naoto.sato at oracle.com Mon Apr 1 05:33:09 2019 From: naoto.sato at oracle.com (naoto.sato at oracle.com) Date: Sun, 31 Mar 2019 22:33:09 -0700 Subject: [13] RFR: 8205432: Replace the placeholder Japanese era name Message-ID: <85115e38-c571-65ec-f6de-ef82e0aac6ca@oracle.com> Hello, Please review the fix to the following issue: https://bugs.openjdk.java.net/browse/JDK-8205432 The CSR and the proposed changeset are located at: https://bugs.openjdk.java.net/browse/JDK-8218207 http://cr.openjdk.java.net/~naoto/8205432/webrev.03/ The fix is simply to replace all the occurrences of the placeholder name "NewEra"/"??" with "Reiwa"/"??", which is the government declared era name. Naoto From naoto.sato at oracle.com Mon Apr 1 05:33:15 2019 From: naoto.sato at oracle.com (naoto.sato at oracle.com) Date: Sun, 31 Mar 2019 22:33:15 -0700 Subject: [13]: RFR: 8174268: Declare a public field in JapaneseEra for the era starting May 2019 Message-ID: Hello, Please review the fix to the following issue: https://bugs.openjdk.java.net/browse/JDK-8174268 The CSR and the proposed changeset are located at: https://bugs.openjdk.java.net/browse/JDK-8193826 http://cr.openjdk.java.net/~naoto/8174268/webrev.02/ This is the other part of change of the Japanese new era support, which is to declare a public era instance. Naoto From goetz.lindenmaier at sap.com Mon Apr 1 07:12:06 2019 From: goetz.lindenmaier at sap.com (Lindenmaier, Goetz) Date: Mon, 1 Apr 2019 07:12:06 +0000 Subject: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null. In-Reply-To: <342a394b-9798-cd83-3c18-cb7f24da712e@gmail.com> References: <7c4b0bc27961471e91195bef9e767226@sap.com> <01361236-c046-0cac-e09d-be59ea6499e0@oracle.com> <2d38e96dcd214dd091f4d79d2a9e71e3@sap.com> <440e685b-b528-056d-385f-9dc010d65e97@oracle.com> <7189ff5f-a73f-5109-1d6b-aa8a2635543a@oracle.com> <20190314143804.400279193@eggemoggin.niobe.net> <172abe6c-e95d-515b-9e8c-8cfa402f4a7c@oracle.com> <3265336b-b483-dc69-b8f7-787139a44183@oracle.com> <33a092ca-9949-bac0-3160-6d018b5e27c4@oracle.com> <850cce9d-619c-b6c0-495c-eebbfff801cc@gmail.com> <342a394b-9798-cd83-3c18-cb7f24da712e@gmail.com> Message-ID: Hi Peter, > -----Original Message----- > From: Peter Levart > Sent: Freitag, 29. M?rz 2019 16:44 > To: Lindenmaier, Goetz ; 'Mandy Chung' > > Cc: core-libs-dev at openjdk.java.net; maurizio.cimadamore at oracle.com; > hotspot-runtime-dev at openjdk.java.net > Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException > describing what is null. > > > > On 3/29/19 4:36 PM, Peter Levart wrote: > > > > > > On 3/29/19 8:49 AM, Lindenmaier, Goetz wrote: > >> So I want to withdraw my claim that NPEs are thrown frequently. > >> Probably I was biased by my compiler construction background, > >> remembering NPE checks are all over the place in the code. > >> > >> But I think I can still keep the claim that the message is > >> printed rarely. > >> > >> I'll adapt the JEP saying something like this: > >> "While exceptions are supposed to be thrown rarely, i.e., only > >> In exceptional situations, most are swallowed without ever > >> looking at the message. Thus, overhead in getMessage() will > >> not fall into account." > > > > Is this really a realistic assumption? That NPE exceptions are mostly > > swallowed in most programs despite the fact that swallowing exceptions > > (and throwing them to control the flow) is an anti-pattern? Is > > majority of code really so badly written? I would expect that most > > programs contain an exception handler of some kind that at least logs > > all unexpected exceptions. > > > > I think JDK should assume that NPEs are not frequent in most well > > written programs. Because in well written programs all unexpected > > exceptions are at least logged somewhere and this alone guarantees > > that programs are eventually "fixed" to not throw them frequently... > > > > Regards, Peter > > So I would say that there are two kinds of programs (which kind is in > majority doesn't matter): > > a - programs that throw and catch exceptions for exceptional situations > only (i.e. non frequently) - they also print the exceptions' messages > b - programs that throw and swallow exceptions frequently, but they > mostly don't print their messages > > In either case .getMessage() is not called frequently for kind (a) and > hopefully also for kind (b). > > Regards, Peter Hi, I agree with this, and my numbers show that the message is not printed frequently in any case. Best regards, Goetz. From david.holmes at oracle.com Mon Apr 1 07:15:36 2019 From: david.holmes at oracle.com (David Holmes) Date: Mon, 1 Apr 2019 17:15:36 +1000 Subject: RFR: 8221477: Inject os/cpu-specific constants into Unsafe from JVM In-Reply-To: <936d213e-9c75-6af4-a7f6-bab6a0f320bb@oracle.com> References: <2fc62430-2e2e-9ee5-ccf1-f1cde5cea416@redhat.com> <8b0f5b4c-0386-1440-6939-646daf36aa55@redhat.com> <24b4bb72-732e-0447-d1be-dd71507e7787@redhat.com> <945d9546-5195-ab33-0e20-57871c2f1ef9@oracle.com> <2a26715f-fa64-9de4-1071-b18d07c05511@redhat.com> <936d213e-9c75-6af4-a7f6-bab6a0f320bb@oracle.com> Message-ID: <21b14ecd-4b24-8601-4b07-50d7ac516493@oracle.com> Follow up ... On 1/04/2019 2:27 pm, David Holmes wrote: > Hi Andrew, > > On 29/03/2019 8:40 pm, Andrew Dinn wrote: >> Hi David, >> >> Thanks very much for reviewing this patch. >> >> On 29/03/2019 01:25, David Holmes wrote: >>> This seems fine in general but I have a few queries on some details: >>> >>> src/hotspot/share/classfile/javaClasses.hpp >>> >>> ???? f(java_lang_Thread) \ >>> +?? f(jdk_internal_misc_UnsafeConstants) \ >>> ???? f(java_lang_ThreadGroup) \ >>> >>> Is there a reason this needs to be shoved in there? Similarly with >>> src/hotspot/share/classfile/systemDictionary.hpp: >>> >>> ??? do_klass(Thread_klass, >>> java_lang_Thread????????????????????????????????????? ) \ >>> +?? do_klass(UnsafeConstants_klass, >>> jdk_internal_misc_UnsafeConstants???????????????????? ) \ >>> ???? do_klass(ThreadGroup_klass, >>> java_lang_ThreadGroup???????????????????????????????? ) \ >>> >>> ? >> >> I'm not sure what you are asking here. Are you talking about the >> positioning of these entries? If so then the reason for choosing those >> positions was because they match the position of the corresponding class >> initialization calls in the file thread.cpp. As to that choice ... see >> below. > > Yes I'm asking about the positioning ... > >>> src/hotspot/share/runtime/thread.cpp >>> >>> ???? main_thread->set_threadObj(thread_object); >>> + >>> +?? // initialize the hardware-specific constants needed by Unsafe >>> +?? initialize_class(vmSymbols::jdk_internal_misc_UnsafeConstants(), >>> CHECK); >>> +?? jdk_internal_misc_UnsafeConstants::set_unsafe_constants(); >>> + >>> ???? // Set thread status to running since main thread has >>> ???? // been started and running. >>> ???? java_lang_Thread::set_thread_status(thread_object, >>> >>> That seems a very odd place to insert the new initialization. I can't >>> see any reason you'd need to split the Thread object initialization like >>> that. ?? >> >> Well, yes, indeed :-). I was not sure where this init needed to go so I >> simply put it in as early as I thought was safe. Clearly, it is an >> interloper into intitialise_java_lang_classes() but I was not sure where >> else was more appropriate. >> >> I don't think it matters too much where this init happens so long as it >> is early enough to precede any clinit dependencies on Unsafe (see >> below). I'm very happy to take advice on this (indeed I was hoping/ >> expecting it would be brought up at review) and also on where the >> entries in the headers would best be placed. >> >>> More generally exactly when do you need to initialize this new class by >>> and how does the initialization order change before/after this fix? (I'm >>> expecting only to see the new class inserted where needed without any >>> other perturbations.) >> >> As I said, I put the class initialization in at this early point simply >> to guarantee that the constants are available before Unsafe or any class >> which might recursively initialize Unsafe could end up needing them. I >> am sure they could move later and also earlier, although the latter >> would probably not make any sense. The important thing is that they >> don't really have any hard dependencies on other class inits apart, >> perhaps, from 'magic' classes like Object, Class etc which need to exist >> in order to init /any/ other class. > > I did some analysis of the class loading and initialization sequence and > added my suggestions to bug report. In summary loading seems somewhat > immaterial so I suggest: > > - javaClasses.hpp: Add UnsafeConstants at the end of > BASIC_JAVA_CLASSES_DO_PART2 > - systemDictionary.hpp: Add UnsafeConstants immediately before Unsafe > > Then for init: > - thread.cpp: initialize UnsafeConstants immediately after j.l.Module > > It would be desirable to detect if we happen to execute the > earlier (by accident) so I suggest adding a "not initialized" assertion > prior to your code calling initialize_class. Actually that might be a > useful addition to the initialize_class method, as if it fires it means > we're not initializing in the expected order ... I'll run a little > adding that ... I meant to say "run a little test". Turns out you can't put the assertion in initialize_class as the initialization can vary for some of the exception classes (at least) depending on VM flags used (e.g. -Xrs, and I think certain logging options). Thanks, David > > Thanks, > David > > P.S. This missing space in javaClasses.cpp was reported by Thomas but > hasn't been fixed yet: > > 4026???? }else { > > >> I deliberately factored these constants out of Unsafe into a separate >> all static class UnsafeConstants so as to decouple this init from any >> current or future dependencies on Unsafe (and also to make them more >> clearly visible). Since the fields only hold os/hw specific constants >> they can be set any time after VM_Version/CPU-specific init and >> OS-specific init has completed. >> >>> src/hotspot/share/classfile/vmSymbols.hpp >>> >>> +?? template(big_endian_name,?????????????????????????? "BIG_ENDIAN") >>> ??????????????????????????? \ >>> +?? template(use_unaligned_access_name, >>> "UNALIGNED_ACCESS")??????????????????????? \ >>> >>> Nit: There's an extra space before "UNALIGNED... >> >> Thanks. Thomas Stuefe already spotted that and I have updated the webrev >> in place to fix it. >> >>> src/java.base/share/classes/jdk/internal/misc/UnsafeConstants.java >>> >>> 31? * package-protected? ... >>> >>> s/protected/private/ >> >> Thanks, will correct it. >> >>> ??37? * The JVM injects values into all the static fields of this class >>> ??... >>> ??43? * hardware-specific constants installed by the JVM. >>> >>> I get this gist of this note but still found it rather difficult to >>> intepret. There are I think two key points: >>> >>> 1. The fields must not be constant variables, hence the need for the >>> static initialization block. >>> 2. The true value of each field is injected by the VM. >>> >>> How about: >>> >>> * The JVM injects hardware-specific values into all the static fields >>> * of this class during JVM initialization. The static initialization >>> * block exists to prevent the fields from being considered constant >>> * variables, so the field values will be not be compiled directly into >>> * any class that uses them. >> >> Yes, I agree that is clearer. >> >>> 60????? * @implNote >>> 61????? * The actual value for this field is injected by JVM. A static >>> 62????? * initialization block is used to set the value here to >>> 63????? * communicate that this static final field is not statically >>> 64????? * foldable, and to avoid any possible circular dependency during >>> 65????? * vm initialization. >>> >>> I think all you need for each field is just: >>> >>> * @implNote >>> * The actual value for this field is injected by _the_ JVM. >> >> Yes, also better. >> >>> 85????? * flag whose value ... >>> 92????? * flag whose value ... >>> >>> s/flag/Flag/ >> >> Thanks, will correct this. >> >> regards, >> >> >> Andrew Dinn >> ----------- >> Senior Principal Software Engineer >> Red Hat UK Ltd >> Registered in England and Wales under Company Registration No. 03798903 >> Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander >> From chris.hegarty at oracle.com Mon Apr 1 11:18:23 2019 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Mon, 1 Apr 2019 12:18:23 +0100 Subject: [13] RFR: 8205432: Replace the placeholder Japanese era name In-Reply-To: <85115e38-c571-65ec-f6de-ef82e0aac6ca@oracle.com> References: <85115e38-c571-65ec-f6de-ef82e0aac6ca@oracle.com> Message-ID: <76f9d06a-1514-12fe-121b-7272c2cb57ea@oracle.com> On 01/04/2019 06:33, naoto.sato at oracle.com wrote: > Hello, > > Please review the fix to the following issue: > > https://bugs.openjdk.java.net/browse/JDK-8205432 > > The CSR and the proposed changeset are located at: > > https://bugs.openjdk.java.net/browse/JDK-8218207 > http://cr.openjdk.java.net/~naoto/8205432/webrev.03/ Looks good to me. -Chris. From chris.hegarty at oracle.com Mon Apr 1 11:20:10 2019 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Mon, 1 Apr 2019 12:20:10 +0100 Subject: [13]: RFR: 8174268: Declare a public field in JapaneseEra for the era starting May 2019 In-Reply-To: References: Message-ID: <7a93a920-b072-ee15-f529-c4b935a3c040@oracle.com> On 01/04/2019 06:33, naoto.sato at oracle.com wrote: > Hello, > > Please review the fix to the following issue: > > https://bugs.openjdk.java.net/browse/JDK-8174268 > > The CSR and the proposed changeset are located at: > > https://bugs.openjdk.java.net/browse/JDK-8193826 > http://cr.openjdk.java.net/~naoto/8174268/webrev.02/ Looks good Naoto. -Chris. From claes.redestad at oracle.com Mon Apr 1 11:57:20 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 1 Apr 2019 13:57:20 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash Message-ID: Hi, when a String has a calculated hash code value of 0, we recalculate and store a 0 to the String.hash field every time (except for the empty String, which is special cased). To make String objects more amenable to storage in shared read-only memory, e.g., CDS archives, we should avoid this redundant store. Bug: https://bugs.openjdk.java.net/browse/JDK-8221723 Webrev: http://cr.openjdk.java.net/~redestad/8221723/ Testing: tier1-3, no regression on existing and new StringHashCode micros /Claes From pavel.rappo at oracle.com Mon Apr 1 12:20:53 2019 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Mon, 1 Apr 2019 13:20:53 +0100 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: Message-ID: <0DFEC52E-C016-4F3E-8F47-D1D87F889EBB@oracle.com> Hi Claes, > To make String objects more amenable to storage in shared read-only memory, > e.g., CDS archives, we should avoid this redundant store. Could you please elaborate on that? From claes.redestad at oracle.com Mon Apr 1 12:36:21 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 1 Apr 2019 14:36:21 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: <0DFEC52E-C016-4F3E-8F47-D1D87F889EBB@oracle.com> References: <0DFEC52E-C016-4F3E-8F47-D1D87F889EBB@oracle.com> Message-ID: Hi Pavel, On 2019-04-01 14:20, Pavel Rappo wrote: > Hi Claes, > >> To make String objects more amenable to storage in shared read-only memory, >> e.g., CDS archives, we should avoid this redundant store. > > Could you please elaborate on that? > currently, heap archiving excludes Strings with hash 0 from being archived. This includes "" etc. I intend to fix that in JDK-8221724[1] but that'd then lead to read-only memory pages backed by the archive to be dirtied when getting the hash code of such Strings (it wouldn't break, but it'd be effectively copy-on-write and diminish the benefit of storing Strings in archives and similar solutions). This patch merely ensures that such dirtying doesn't happen and that we can archive 0-hashcode Strings without repercussions. Makes sense? /Claes https://bugs.openjdk.java.net/browse/JDK-8221724 From shade at redhat.com Mon Apr 1 13:03:52 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 1 Apr 2019 15:03:52 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: Message-ID: On 4/1/19 1:57 PM, Claes Redestad wrote: > when a String has a calculated hash code value of 0, we recalculate and > store a 0 to the String.hash field every time (except for the empty > String, which is special cased). To make String objects more amenable to > storage in shared read-only memory, e.g., CDS archives, we should avoid > this redundant store. > > Bug:??? https://bugs.openjdk.java.net/browse/JDK-8221723 > Webrev: http://cr.openjdk.java.net/~redestad/8221723/ Looks fine. I recall we were fixing something like this, but I might be confusing it with the other RFE [0]. The comment might emphasize we are doing it for RO memory: // Avoid issuing a store if the calculated value is also zero: // in addition to minor optimization benefit, this also allows storing // Strings with zero hash code in read-only memory. -Aleksey [0] https://bugs.openjdk.java.net/browse/JDK-6921374 From pavel.rappo at oracle.com Mon Apr 1 13:17:40 2019 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Mon, 1 Apr 2019 14:17:40 +0100 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: <0DFEC52E-C016-4F3E-8F47-D1D87F889EBB@oracle.com> Message-ID: > On 1 Apr 2019, at 13:36, Claes Redestad wrote: > > Makes sense? It does, thanks. I wonder though what portion of strings in a typical app has a calculated `hash` of 0? My naive estimate would be 1E-9. Unless I'm mistaken, is that really of concern? From claes.redestad at oracle.com Mon Apr 1 13:23:41 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 1 Apr 2019 15:23:41 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: Message-ID: <46f4de12-eca7-ff6a-d862-d583b4139223@oracle.com> Hi Aleksey, On 2019-04-01 15:03, Aleksey Shipilev wrote: > On 4/1/19 1:57 PM, Claes Redestad wrote: >> when a String has a calculated hash code value of 0, we recalculate and >> store a 0 to the String.hash field every time (except for the empty >> String, which is special cased). To make String objects more amenable to >> storage in shared read-only memory, e.g., CDS archives, we should avoid >> this redundant store. >> >> Bug:??? https://bugs.openjdk.java.net/browse/JDK-8221723 >> Webrev: http://cr.openjdk.java.net/~redestad/8221723/ > > Looks fine. I recall we were fixing something like this, but I might be confusing it with the other > RFE [0]. digging up the history I did a regression fix due some benchmarks regressing during JDK 9: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/6837759aa403 (closed bug due some clerical errors linking to internal systems..) Cause of regression was https://bugs.openjdk.java.net/browse/JDK-8058643 The approach of avoiding the store for any String was however lost when the JEP work for Compact Strings was integrated, and since the performance benefit for anything by "" is comparatively slim I didn't insist on fixing this at the time. With the added motivation that it helps storing Strings on read-only memory it feels worthwhile, though. > The comment might emphasize we are doing it for RO memory: > > // Avoid issuing a store if the calculated value is also zero: > // in addition to minor optimization benefit, this also allows storing > // Strings with zero hash code in read-only memory. Yes, that reads better and better emphasizes the point I'm trying to make. Updated in place. Thanks! /Claes From Roger.Riggs at oracle.com Mon Apr 1 13:25:47 2019 From: Roger.Riggs at oracle.com (Roger Riggs) Date: Mon, 1 Apr 2019 09:25:47 -0400 Subject: [13]: RFR: 8174268: Declare a public field in JapaneseEra for the era starting May 2019 In-Reply-To: <7a93a920-b072-ee15-f529-c4b935a3c040@oracle.com> References: <7a93a920-b072-ee15-f529-c4b935a3c040@oracle.com> Message-ID: <73250794-fd8b-36a8-513f-81a1e4b8bb11@oracle.com> Looks good. On 04/01/2019 07:20 AM, Chris Hegarty wrote: > > On 01/04/2019 06:33, naoto.sato at oracle.com wrote: >> Hello, >> >> Please review the fix to the following issue: >> >> https://bugs.openjdk.java.net/browse/JDK-8174268 >> >> The CSR and the proposed changeset are located at: >> >> https://bugs.openjdk.java.net/browse/JDK-8193826 >> http://cr.openjdk.java.net/~naoto/8174268/webrev.02/ > > Looks good Naoto. > > -Chris. From claes.redestad at oracle.com Mon Apr 1 13:28:24 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 1 Apr 2019 15:28:24 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: <0DFEC52E-C016-4F3E-8F47-D1D87F889EBB@oracle.com> Message-ID: On 2019-04-01 15:17, Pavel Rappo wrote: >> On 1 Apr 2019, at 13:36, Claes Redestad wrote: >> >> Makes sense? > > It does, thanks. I wonder though what portion of strings in a typical app has a > calculated `hash` of 0? My naive estimate would be 1E-9. Unless I'm mistaken, > is that really of concern? > Specifically I'm looking at an archiving RFE that is blocked by the fact that interned empty String literals loses identity when archived and reconstituted, and there exists code that does identity comparisons on such interned empty String, e.g.: http://hg.openjdk.java.net/jdk/jdk/file/d02f1f4ff3a6/src/java.base/share/classes/java/util/ResourceBundle.java#l3455 /Claes From claes.redestad at oracle.com Mon Apr 1 13:33:24 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 1 Apr 2019 15:33:24 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: <0DFEC52E-C016-4F3E-8F47-D1D87F889EBB@oracle.com> Message-ID: On 2019-04-01 15:28, Claes Redestad wrote: > On 2019-04-01 15:17, Pavel Rappo wrote: >>> On 1 Apr 2019, at 13:36, Claes Redestad >>> wrote: >>> >>> Makes sense? >> >> It does, thanks. I wonder though what portion of strings in a typical >> app has a >> calculated `hash` of 0? My naive estimate would be 1E-9. Unless I'm >> mistaken, >> is that really of concern? >> > > Specifically I'm looking at an archiving RFE that is blocked by the fact > that interned empty String literals loses identity when archived and > reconstituted, and there exists code that does identity comparisons on > such interned empty String, e.g.: > > http://hg.openjdk.java.net/jdk/jdk/file/d02f1f4ff3a6/src/java.base/share/classes/java/util/ResourceBundle.java#l3455 > RFE in question: https://bugs.openjdk.java.net/browse/JDK-8221701 Technically we could special-case the empty String, but I much prefer a more general solution like this + JDK-8221724 /Claes From Roger.Riggs at oracle.com Mon Apr 1 13:33:48 2019 From: Roger.Riggs at oracle.com (Roger Riggs) Date: Mon, 1 Apr 2019 09:33:48 -0400 Subject: [13] RFR: 8205432: Replace the placeholder Japanese era name In-Reply-To: <76f9d06a-1514-12fe-121b-7272c2cb57ea@oracle.com> References: <85115e38-c571-65ec-f6de-ef82e0aac6ca@oracle.com> <76f9d06a-1514-12fe-121b-7272c2cb57ea@oracle.com> Message-ID: <81e188db-50bc-aff2-999b-e026d29fc8ca@oracle.com> +1 On 04/01/2019 07:18 AM, Chris Hegarty wrote: > On 01/04/2019 06:33, naoto.sato at oracle.com wrote: >> Hello, >> >> Please review the fix to the following issue: >> >> https://bugs.openjdk.java.net/browse/JDK-8205432 >> >> The CSR and the proposed changeset are located at: >> >> https://bugs.openjdk.java.net/browse/JDK-8218207 >> http://cr.openjdk.java.net/~naoto/8205432/webrev.03/ > > Looks good to me. > > -Chris. From christoph.langer at sap.com Mon Apr 1 13:38:24 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Mon, 1 Apr 2019 13:38:24 +0000 Subject: RFR 8213031: (zipfs) Add support for POSIX file permissions In-Reply-To: References: <7b513a34196141f595cd5d194fb9d8a2@sap.com> <46af4f9d-60f9-c60d-e6f1-8fb97df3ba2e@oracle.com> <5d28b0715d2041ff892a3c44e024f120@sap.com> <8e9231ff-b7d5-bc2f-2643-713f3c670a1d@oracle.com> <3aeba9a64a434a968fc1d82a44077745@sap.com> <953449f0913340f6a94ae3d83611fd92@sap.com> <9b3c9cfe-63e9-94ea-1af0-7ba9e2db52fd@oracle.com> Message-ID: Hi Alan, thanks for getting back on this. > One thing that is puzzling is that > ZipFileAttributeView/ZipFileAttributes extend > PosixFileAttributeView/PosixFileAttributes. I don't think that will work > because the "zip" view is supported by default whereas "posix" view > needs the file system to be created with enablePosixFileAttributes=true. Hm, when I was looking at it initially, I was also wondering if it would be cleaner either have a default ZipFileAttributeView/ZipFileAttributes implementation that doesn't extend Posix or an "Enhanced" ZipFileAttributeView/ZipFileAttributes that would extend Posix. But I saw in the implementation of ZipFileAttributeView::get that this is already the "gate" where the requester would get the ZipFileAttributeView implementation with the requested behavior set. So I was hoping that it'd be fine to handle the Posix extension this way. Do you really think that wouldn't work? Alternatively, I could explore a different class hierarchy for ZipFileAttributeView/ZipFileAttributes... > I saw your comment about naming the file permissions attribute > "storedPermissions" in the zip view but if the zip and posix view are > separated then I think it would be clearer to name it "permissions" in > the zip view. If code is using Files.getAttribute then it will need the > view name so they won't get mixed up. Let me think about it... > You asked about the fallback when defaultOwner/defaultGroup aren't set. > If getOwner fails with an IOException then I think that exception should > be propagated. The UOE case will fallback to the value of "user.name". I > think the fallback for the group owner should be the file owner rather > than " > "". The default.policy file will need to be updated to > grant jdk.zipfs RuntimePermission("accessUserInfo") so that you won't > need to deal with security exceptions. Sounds fine. I'll implement that. > As regards next steps then I think we need to agree the spec changes, as > in the the javadoc in module-info.java. Once we have the spec agreed > then the CSR can be updated and finalized. The code review can be done > in parallel of course. I think Lance is going to help review the changes. Ok, I guess this eventually boils down to agree upon the right way of doing the "permissions" attribute or is there something more related to the spec? Thanks Christoph From Roger.Riggs at oracle.com Mon Apr 1 15:06:47 2019 From: Roger.Riggs at oracle.com (Roger Riggs) Date: Mon, 1 Apr 2019 11:06:47 -0400 Subject: Request for sponsor: JDK-8221430: StringBuffer(CharSequence) constructor truncates when -XX:-CompactStrings specified In-Reply-To: <257e94c4-2429-89a0-50df-ed020c0093d2@oracle.com> References: <755e2c2a-943b-562f-e10c-e2ae29e8ba8a@oracle.com> <08ffa0f7-4cbd-c946-2250-ddcb8bed612f@oracle.com> <64ea5dc1-990f-f772-d970-1b0b24f3dc9b@oracle.com> <5160cae7-d4d7-3edd-5045-e09c0a52ad71@oracle <257e94c4-2429-89a0-50df-ed020c0093d2@oracle.com> Message-ID: <61d962e5-4e52-c401-25be-4eb1e848e422@oracle.com> Hi Ivan, Thanks for running the micro benchmarks. This version has more code duplication than Andrew's original proposal that calculated the coder only CharSequence and had a single AbstractStringBuilder constructor for computing the size and allocating the byte[]/ http://cr.openjdk.java.net/~aleonard/8221430/webrev.00/ I'd be curious to know the JMH tests for that version compared. Another comment is whether the 'instanceof' code is the best performer for checking if the argument is a String. I might think that 'seq.getClass().equals(String.class)' is faster. And in this most recent webrev that has separated the AbstractStringBuilder constructors for String from CharSequence, is it more likely that the argument will be an AbstractStringBuilder than a String so that comparison should be done first. Thanks, Roger On 03/30/2019 02:29 AM, Ivan Gerasimov wrote: > It was a good suggestion to run micro benchmarks! > > First, it turned out that (at least in some scenarios) > StringBuilder(String) is not intrinsified. > I.e., running benchmarks with/without '-XX:+UnlockDiagnosticVMOptions > -XX:DisableIntrinsic=_StringBuilder_String' led to the same numbers. > > Here they are prior the fix: > Benchmark?????????????????????????????? Mode? Cnt?? Score Error Units > StringBuilders.fromLatin1String???????? avgt?? 18? 16.378 ? 0.378 ns/op > StringBuilders.fromLatin1StringBuilder? avgt?? 18? 19.975 ? 0.195 ns/op > StringBuilders.fromUtf8String?????????? avgt?? 18? 19.946 ? 2.774 ns/op > StringBuilders.fromUtf8StringBuilder??? avgt?? 18? 34.317 ? 0.415 ns/op > > Second, with the fix from the webrev.01, the performance has degraded: > Benchmark?????????????????????????????? Mode? Cnt?? Score Error Units > StringBuilders.fromLatin1String???????? avgt?? 18? 24.517 ? 0.965 ns/op > StringBuilders.fromLatin1StringBuilder? avgt?? 18? 20.025 ? 0.678 ns/op > StringBuilders.fromUtf8String?????????? avgt?? 18? 26.102 ? 0.627 ns/op > StringBuilders.fromUtf8StringBuilder??? avgt?? 18? 23.141 ? 0.394 ns/op > > So, it appears to be necessary to handle the case > StringBuilder(String) separately from the general case. > > And here there is the new webrev: > http://cr.openjdk.java.net/~igerasim/8221430/02/webrev/ > > This variant restores the performance, and shows some improvement in a > case of StringBuilder(StringBuilder-with-UTF8-content): > Benchmark?????????????????????????????? Mode? Cnt?? Score Error Units > StringBuilders.fromLatin1String???????? avgt?? 18? 15.742 ? 0.189 ns/op > StringBuilders.fromLatin1StringBuilder? avgt?? 18? 18.671 ? 0.109 ns/op > StringBuilders.fromUtf8String?????????? avgt?? 18? 17.172 ? 0.100 ns/op > StringBuilders.fromUtf8StringBuilder??? avgt?? 18? 21.885 ? 0.138 ns/op > > With kind regards, > Ivan > > > On 3/28/19 2:24 PM, Ivan Gerasimov wrote: >> Apologize for the delay, got distracted by other urgent things. >> >> I've got some surprising micro-benchmark results, and need to >> understand them before pushing the fix. >> >> I'll verify the results and then share details. >> >> With kind regards, >> Ivan >> >> >> On 3/28/19 9:41 AM, Roger Riggs wrote: >>> Hi Andrew, >>> >>> I'm fine with Ivan's version too. >>> >>> Roger >>> >>> >>> On 03/28/2019 12:13 PM, Andrew Leonard wrote: >>>> Roger, Ivan, thanks for your help discussing this issue. Fyi, I am >>>> off on leave for the next week, so I +1 Ivan's last webrev if >>>> that's the way you decide to go.. >>>> Thanks >>>> Andrew >>>> >>>> Andrew Leonard >>>> Java Runtimes Development >>>> IBM Hursley >>>> IBM United Kingdom Ltd >>>> Phone internal: 245913, external: 01962 815913 >>>> internet email: andrew_m_leonard at uk.ibm.com >>>> >>>> >>>> >>>> >>>> From: Roger Riggs >>>> To: Ivan Gerasimov , Andrew Leonard >>>> >>>> Cc: core-libs-dev at openjdk.java.net >>>> Date: 27/03/2019 13:39 >>>> Subject: Re: Request for sponsor: JDK-8221430: >>>> StringBuffer(CharSequence) constructor truncates when >>>> -XX:-CompactStrings specified >>>> ------------------------------------------------------------------------ >>>> >>>> >>>> >>>> >>>> Hi Ivan, >>>> >>>> On 03/26/2019 07:30 PM, Ivan Gerasimov wrote: >>>> The main source of confusion here seems to be due to that the coder >>>> is passed in as an argument, so it either needs to be trusted or >>>> has to be verified in the constructor. >>>> >>>> The design for coder is that it *is* trusted in all >>>> internal/implementation APIs. >>>> Subsequent changes should not weaken this invariant, it will cause >>>> doubt >>>> in the code and cast doubt on all of the performance work that has >>>> been done to optimize its use. >>>> >>>> So, let's instead introduce AbstractStringBuilder(CharSequence) and >>>> make it do all manipulations. >>>> _ >>>> __http://cr.openjdk.java.net/~igerasim/8221430/01/webrev/_ >>>> >>>> >>>> Note that the common case of StringBuilder(String) already gets >>>> intrinsified by hotspot. >>>> >>>> What do you think? >>>> >>>> This looks good, the logic is in one place. >>>> >>>> Since StringBuilder(String) is an intrinsic, my doubt about a >>>> slight performance >>>> impact is unwarranted in that specific case. >>>> >>>> Are there any StringBuffer/Builder jmh tests than be easily rerun >>>> to compare? >>>> >>>> Thanks, Roger >>>> >>>> >>>> With kind regards, >>>> Ivan >>>> >>>> On 3/26/19 1:04 PM, Ivan Gerasimov wrote: >>>> From the design point of view, I believe it is better to have the >>>> constructor AbstractStringBuilder(int, int, int) to check if the >>>> coder argument makes sense with respect to the value of >>>> COMPACT_STRING, so it won't be possible to create a StringBuilder >>>> with the coder==LATIN1, when it is not supported. >>>> >>>> For calculating the coderHint then, it is not necessary to check >>>> COMPACT_STRING:? If the CharSequence argument is in fact String or >>>> AbstractStringBuilder, the coder is known, otherwise LATIN1 can be >>>> passed in as a hint (for an arbitrary CharSequence it is not 100% >>>> accurate anyway). >>>> The constructor AbstractStringBuilder(int, int, int) will then >>>> either use the provided coder, or adjust it if necessary. >>>> >>>> Will we agree on something like following? >>>> _ >>>> __http://cr.openjdk.java.net/~igerasim/8221430/00/webrev/_ >>>> >>>> >>>> With kind regards, >>>> >>>> Ivan >>>> >>>> >>>> On 3/26/19 12:14 PM, Roger Riggs wrote: >>>> Hi, >>>> >>>> We've got the subject open and its fresh, there's no need for a >>>> separate review cycle. >>>> >>>> The first fix (-01) does not seem to be consistent with the >>>> original design >>>> and handling of the coder.? The StringBuilder(String) and >>>> StringBuffer(String) >>>> constructors are the pattern that should be followed for determining >>>> the coder for the new instance. >>>> >>>> Checking for COMPACT_STRING in two places (the >>>> AbstractStringBuilder and >>>> the sub classes) is unnecessary and distributes the information >>>> about the >>>> correct coder across two classes where determining what it should be >>>> in the subclass has more complete? information and can correctly >>>> determine >>>> the coder once. >>>> >>>> We can likely find a reviewer to be a tie-breaker if Ivan sees it >>>> as desirable. >>>> >>>> Thanks, Roger >>>> >>>> >>>> On 03/26/2019 02:38 PM, Andrew Leonard wrote: >>>> Sorry chaps, I think my brain is getting confused!, I think we have >>>> conflicting reviews here? >>>> >>>> Roger, I added the getCharSequenceCoder() to AbstractStringBuilder >>>> so it was only defined in one place.. >>>> I agree with this being called in StringBuffer/Builder then we >>>> don't need the change to AbstractStringBuild() constuctor, however >>>> Ivan wants getCharSequenceCoder() that done as a separate "bug". >>>> >>>> So I think it comes down to do we do this as 2 "bugs" or 1 ? >>>> >>>> Thanks >>>> Andrew >>>> >>>> Andrew Leonard >>>> Java Runtimes Development >>>> IBM Hursley >>>> IBM United Kingdom Ltd >>>> Phone internal: 245913, external: 01962 815913 >>>> internet email: _andrew_m_leonard at uk.ibm.com_ >>>> >>>> >>>> >>>> >>>> >>>> From: Roger Riggs __ >>>> >>>> To: Andrew Leonard __ >>>> , Ivan Gerasimov >>>> __ >>>> Cc: _core-libs-dev at openjdk.java.net_ >>>> >>>> Date: 26/03/2019 18:19 >>>> Subject: Re: Request for sponsor: JDK-8221430: >>>> StringBuffer(CharSequence) constructor truncates when >>>> -XX:-CompactStrings specified >>>> ------------------------------------------------------------------------ >>>> >>>> >>>> >>>> >>>> Hi Andrew, >>>> >>>> You are going to have to change the same code twice >>>> because the changes should be the StringBuffer and StringBuilder >>>> constructors and would remove the code that is added to >>>> the AbstractStringBuilder constructor.? That's a waste of review >>>> cycles. >>>> >>>> >>>> On 03/26/2019 11:45 AM, Andrew Leonard wrote: >>>> Hi Roger, >>>> No worries, the more the merrier! >>>> So that was one of my reasoning for adding getCharSequenceCode() >>>> was, I think what you're suggesting is my webrev.01, >>>> __http://cr.openjdk.java.net/~aleonard/8221430/webrev.01/__ >>>> __ >>>> >>>> Ivan's view is that behaviour was an extended issue, which it is, >>>> but I thought it was nice to add.. >>>> >>>> Which patch do we favour? webrev-01 or -02 ? >>>> >>>> Neither, there should be no change to the AbstractStringBuilder >>>> constructor >>>> and the change should be done in the subclass constructors. >>>> >>>> Roger >>>> >>>> >>>> Thanks >>>> Andrew >>>> >>>> Andrew Leonard >>>> Java Runtimes Development >>>> IBM Hursley >>>> IBM United Kingdom Ltd >>>> Phone internal: 245913, external: 01962 815913 >>>> internet email: _andrew_m_leonard at uk.ibm.com_ >>>> __ >>>> >>>> >>>> >>>> >>>> >>>> From: Roger Riggs ___ >>>> _ __ >>>> >>>> To: _core-libs-dev at openjdk.java.net_ >>>> __ >>>> >>>> Date: 26/03/2019 15:24 >>>> Subject: Re: Request for sponsor: JDK-8221430: >>>> StringBuffer(CharSequence) constructor truncates when >>>> -XX:-CompactStrings specified >>>> Sent by: "core-libs-dev" >>>> ___ >>>> _ >>>> __ >>>> >>>> ------------------------------------------------------------------------ >>>> >>>> >>>> >>>> >>>> Hi Andrew, >>>> >>>> Sorry to be late to the review. >>>> >>>> For symmetry with the constructors StringBuffer(String), and >>>> StringBuilder(String) >>>> the determine the coder based on the input argument, I would recommend >>>> using the getCharSequenceCoder added in the -01 webrev and calling >>>> it from the StringBuffer(CharSeq...), and StringBuilder(CharSeq...) >>>> constructors. >>>> >>>> It would be symmetric with the getCoder() method (line 1635) >>>> and select the appropriate coder base on the input value (if known.) >>>> >>>> Thanks, Roger >>>> >>>> >>>> >>>> On 03/26/2019 10:57 AM, Andrew Leonard wrote: >>>> > Hi Ivan, >>>> > Yes, i'm happy with that, as you say the simple constructor >>>> change fixes >>>> > the immediate issue, but not necessarily the extended issue of a >>>> > non-compactable CharSequence in COMPACT_STRINGS mode, but that's >>>> probably >>>> > an enhanced issue to cover in a separate bug... >>>> > I've created a new webrev.02 with just the constructor change and >>>> the >>>> > testcase: >>>> > __http://cr.openjdk.java.net/~aleonard/8221430/webrev.02/__ >>>> __ >>>> >>>> > >>>> > Thanks >>>> > Andrew >>>> > >>>> > Andrew Leonard >>>> > Java Runtimes Development >>>> > IBM Hursley >>>> > IBM United Kingdom Ltd >>>> > Phone internal: 245913, external: 01962 815913 >>>> > internet email: _andrew_m_leonard at uk.ibm.com_ >>>> __ >>>> >>>> > >>>> > >>>> > >>>> > >>>> > From:?? Ivan Gerasimov ___ >>>> _ >>>> __ >>>> >>>> > To:???? Andrew Leonard ___ >>>> _ >>>> __ >>>> >>>> > Cc: _core-libs-dev at openjdk.java.net_ >>>> __ >>>> >>>> > Date:?? 26/03/2019 01:18 >>>> > Subject:??????? Re: Request for sponsor: JDK-8221430: >>>> > StringBuffer(CharSequence) constructor truncates when >>>> -XX:-CompactStrings >>>> > specified >>>> > >>>> > >>>> > >>>> > Thanks Andrew! >>>> > Introducing getCharSequenceCoder() is actually an enhancement, >>>> which may >>>> > improve pre-allocation in certain cases. >>>> > It's not actually required to restore correctness of >>>> StringBuilder/Buffer >>>> > constructors. >>>> > I recommend to separate it from this bug fix, so it can be discussed >>>> > separately, and determined if this is the best approach to this >>>> > enhancement. >>>> > If you agree, I can adjust your latest patch accordingly, run it >>>> through >>>> > the Mach5 test systems and push it on your behalf. >>>> > With kind regards, >>>> > Ivan >>>> > >>>> > On 3/25/19 5:00 PM, Andrew Leonard wrote: >>>> > Hi Ivan, >>>> > Here is my updated webrev: >>>> > __http://cr.openjdk.java.net/~aleonard/8221430/webrev.01/__ >>>> __ >>>> >>>> > >>>> > Thanks >>>> > Andrew >>>> > >>>> > Andrew Leonard >>>> > Java Runtimes Development >>>> > IBM Hursley >>>> > IBM United Kingdom Ltd >>>> > Phone internal: 245913, external: 01962 815913 >>>> > internet email: _andrew_m_leonard at uk.ibm.com_ >>>> __ >>>> >>>> > >>>> > >>>> > >>>> > >>>> > From:??????? Ivan Gerasimov ___ >>>> _ >>>> __ >>>> >>>> > To:??????? Andrew Leonard ___ >>>> _ >>>> __ >>>> >>>> > Cc: _core-libs-dev at openjdk.java.net_ >>>> __ >>>> >>>> > Date:??????? 25/03/2019 22:55 >>>> > Subject:??????? Re: Request for sponsor: JDK-8221430: >>>> > StringBuffer(CharSequence) constructor truncates when >>>> -XX:-CompactStrings >>>> > specified >>>> > >>>> > >>>> > >>>> > I was thinking of organizing code similar to what is done in >>>> > AbstractStringBuilder(int): >>>> > >>>> > if (COMPACT_STRINGS && coderHint == LATIN1) { >>>> >????? value = new byte[capacity]; >>>> >????? coder = LATIN1; >>>> > } else { >>>> >????? value = StringUTF16.newBytesFor(capacity); >>>> >????? coder = UTF16; >>>> > } >>>> > >>>> > With kind regards, >>>> > Ivan >>>> > >>>> > On 3/25/19 3:45 PM, Andrew Leonard wrote: >>>> > Hi Ivan, >>>> > I think I see what you're saying, you mean we also need to >>>> correct this >>>> > line in AbstractStringBuilder >>>> > constructor: >>>> > value = (coder == LATIN1) >>>> >???????????????? ? new byte[capacity] : >>>> StringUTF16.newBytesFor(capacity); >>>> > to be maybe: >>>> > value = (COMPACT_STRINGS && coder == LATIN1) >>>> >???????????????? ? new byte[capacity] : >>>> StringUTF16.newBytesFor(capacity); >>>> > >>>> > The passed in coder stills need to be correct, since with >>>> COMPACT_STRINGS >>>> > a string could be UTF16 if >>>> > it cannot be compacted, so it's more than just a hint isn't it? >>>> > >>>> > Thanks >>>> > Andrew >>>> > >>>> > Andrew Leonard >>>> > Java Runtimes Development >>>> > IBM Hursley >>>> > IBM United Kingdom Ltd >>>> > Phone internal: 245913, external: 01962 815913 >>>> > internet email: _andrew_m_leonard at uk.ibm.com_ >>>> __ >>>> >>>> > >>>> > >>>> > >>>> > >>>> > From:??????? Ivan Gerasimov ___ >>>> _ >>>> __ >>>> >>>> > To:??????? Andrew Leonard ___ >>>> _ >>>> __ >>>> , >>>> > _core-libs-dev at openjdk.java.net_ >>>> __ >>>> >>>> > Date:??????? 25/03/2019 22:20 >>>> > Subject:??????? Re: Request for sponsor: JDK-8221430: >>>> > StringBuffer(CharSequence) constructor truncates when >>>> -XX:-CompactStrings >>>> > specified >>>> > >>>> > >>>> > >>>> > Hi Andrew! >>>> > >>>> > Thanks for finding this bug! >>>> > >>>> > Your fix solves the problem. >>>> > >>>> > However, I think the main issue is that the constructor >>>> > AbstractStringBuilder(byte,int,int) is now broken:? as you >>>> discovered, >>>> > it allows to create a string buffer with the coder LATIN1 when >>>> > COMPACT_STRINGS is false. >>>> > >>>> > Wouldn't it make sense to rename the argument of the constructor to, >>>> > say, coderHint, and then either use it as the coder if >>>> > COMPACT_STRINGS==true, or discard it otherwise. >>>> > >>>> > What do you think? >>>> > >>>> > With kind regards, >>>> > Ivan >>>> > >>>> > On 3/25/19 12:45 PM, Andrew Leonard wrote: >>>> >> Hi, >>>> >> Please can I request a sponsor for this fix to a JDK-13 regression? >>>> >> >>>> >> Patch with jtreg testcase here: >>>> >> __http://cr.openjdk.java.net/~aleonard/8221430/webrev.00/__ >>>> __ >>>> >>>> >> >>>> >> bug: __https://bugs.openjdk.java.net/browse/JDK-8221430__ >>>> >> >>>> >> Many thanks >>>> >> Andrew >>>> >> >>>> >> Andrew Leonard >>>> >> Java Runtimes Development >>>> >> IBM Hursley >>>> >> IBM United Kingdom Ltd >>>> >> Phone internal: 245913, external: 01962 815913 >>>> >> internet email: _andrew_m_leonard at uk.ibm.com_ >>>> __ >>>> >>>> >> >>>> >> Unless stated otherwise above: >>>> >> IBM United Kingdom Limited - Registered in England and Wales >>>> with number >>>> >> 741598. >>>> >> Registered office: PO Box 41, North Harbour, Portsmouth, >>>> Hampshire PO6 >>>> > 3AU >>>> >>>> >>>> >>>> >>>> >>>> Unless stated otherwise above: >>>> IBM United Kingdom Limited - Registered in England and Wales with >>>> number 741598. >>>> Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire >>>> PO6 3AU >>>> >>>> >>>> >>>> Unless stated otherwise above: >>>> IBM United Kingdom Limited - Registered in England and Wales with >>>> number 741598. >>>> Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire >>>> PO6 3AU >>>> >>>> >>>> >>>> >>>> >>>> >>>> Unless stated otherwise above: >>>> IBM United Kingdom Limited - Registered in England and Wales with >>>> number 741598. >>>> Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire >>>> PO6 3AU >>> >> > From jianglizhou at google.com Mon Apr 1 15:21:33 2019 From: jianglizhou at google.com (Jiangli Zhou) Date: Mon, 1 Apr 2019 08:21:33 -0700 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: Message-ID: On Mon, Apr 1, 2019 at 4:59 AM Claes Redestad wrote: > Hi, > > when a String has a calculated hash code value of 0, we recalculate and > store a 0 to the String.hash field every time (except for the empty > String, which is special cased). To make String objects more amenable to > storage in shared read-only memory, e.g., CDS archives, we should avoid > this redundant store. > That was exactly the reason why 0-hash string was excluded from the closed archive heap region. > Bug: https://bugs.openjdk.java.net/browse/JDK-8221723 > Webrev: http://cr.openjdk.java.net/~redestad/8221723/ Looks good to me. Thanks and regards, Jiangli > > > Testing: tier1-3, no regression on existing and new StringHashCode > micros > > /Claes > > From claes.redestad at oracle.com Mon Apr 1 15:46:12 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 1 Apr 2019 17:46:12 +0200 Subject: RFR: 8221701: Archive constant BaseLocales Message-ID: <621b7ca9-acbc-02df-0ed4-7689ab234726@oracle.com> Hi, by archiving constant BaseLocale objects, we can simplify (and speed up) creation of the constant Locale objects in java.util.Locale which are unconditionally created during startup. Bug: https://bugs.openjdk.java.net/browse/JDK-8221701 Webrev: http://cr.openjdk.java.net/~redestad/8221701/open.00/ Testing: tier1-3, along with patches for JDK-8221723 and JDK-8221724 Performance: a small reduction in bytecode executed during startup (-6k, or ~1% of bootstrap), a small reduction in number of classes loaded on small applications (458 -> 451 on a simple Hello World). Thanks! /Claes From claes.redestad at oracle.com Mon Apr 1 15:47:24 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 1 Apr 2019 17:47:24 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: Message-ID: <4e136b1e-3c20-44d5-8ecf-c1fd406967aa@oracle.com> Hi Jiangli, On 2019-04-01 17:21, Jiangli Zhou wrote: > > > On Mon, Apr 1, 2019 at 4:59 AM Claes Redestad > wrote: > > Hi, > > when a String has a calculated hash code value of 0, we recalculate and > store a 0 to the String.hash field every time (except for the empty > String, which is special cased). To make String objects more amenable to > storage in shared read-only memory, e.g., CDS archives, we should avoid > this redundant store. > > > That was exactly the reason why 0-hash string was excluded from the > closed archive heap region. Thanks for confirming! > > > Bug: https://bugs.openjdk.java.net/browse/JDK-8221723 > Webrev: http://cr.openjdk.java.net/~redestad/8221723/ > > > Looks good to me. Thanks! /Claes From forax at univ-mlv.fr Mon Apr 1 16:15:15 2019 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 1 Apr 2019 18:15:15 +0200 (CEST) Subject: [13] RFR: 8205432: Replace the placeholder Japanese era name In-Reply-To: <85115e38-c571-65ec-f6de-ef82e0aac6ca@oracle.com> References: <85115e38-c571-65ec-f6de-ef82e0aac6ca@oracle.com> Message-ID: <153540925.377740.1554135315401.JavaMail.zimbra@u-pem.fr> Hi Naoto, just for my education, what is the translation of "Reiwa" ? regards, R?mi ----- Mail original ----- > De: "naoto sato" > ?: i18n-dev at openjdk.java.net, "core-libs-dev" > Envoy?: Lundi 1 Avril 2019 07:33:09 > Objet: [13] RFR: 8205432: Replace the placeholder Japanese era name > Hello, > > Please review the fix to the following issue: > > https://bugs.openjdk.java.net/browse/JDK-8205432 > > The CSR and the proposed changeset are located at: > > https://bugs.openjdk.java.net/browse/JDK-8218207 > http://cr.openjdk.java.net/~naoto/8205432/webrev.03/ > > The fix is simply to replace all the occurrences of the placeholder name > "NewEra"/"??" with "Reiwa"/"??", which is the government declared era > name. > > Naoto From martinrb at google.com Mon Apr 1 16:39:25 2019 From: martinrb at google.com (Martin Buchholz) Date: Mon, 1 Apr 2019 09:39:25 -0700 Subject: [13] RFR: 8205432: Replace the placeholder Japanese era name In-Reply-To: <153540925.377740.1554135315401.JavaMail.zimbra@u-pem.fr> References: <85115e38-c571-65ec-f6de-ef82e0aac6ca@oracle.com> <153540925.377740.1554135315401.JavaMail.zimbra@u-pem.fr> Message-ID: https://en.wikipedia.org/wiki/Reiwa_period On Mon, Apr 1, 2019 at 9:16 AM Remi Forax wrote: > Hi Naoto, > just for my education, > what is the translation of "Reiwa" ? > From martinrb at google.com Mon Apr 1 17:13:16 2019 From: martinrb at google.com (Martin Buchholz) Date: Mon, 1 Apr 2019 10:13:16 -0700 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: <4e136b1e-3c20-44d5-8ecf-c1fd406967aa@oracle.com> References: <4e136b1e-3c20-44d5-8ecf-c1fd406967aa@oracle.com> Message-ID: I'm confused. We have always had if (h == 0 && value.length > 0) { so we have already been special-casing empty strings (maybe we should stop?). Java has guaranteed that string literals are unique strings, but the empty string is not special in this regard. Archiving any string literal and restoring it later should be identity-preserving, no? Whenever we test or benchmark zero-hash Strings, there are 3 cases that should be covered - literal "", new String(), and (rare!) non-empty Strings that happen to hash to 0. We could avoid archiving those rare non-empty Strings that happen to hash to 0 at archive time if it saved us a branch at runtime. From claes.redestad at oracle.com Mon Apr 1 17:32:44 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 1 Apr 2019 19:32:44 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: <4e136b1e-3c20-44d5-8ecf-c1fd406967aa@oracle.com> Message-ID: <8a4c138b-5050-45a4-8c9e-ceb5b18a8dd8@oracle.com> We could remove value.length > 0 and be net-neutral in #branches for the general slow path (calculate the hash), but that would add a branch to the emptyString.hashCode() _fast path_ (consistently add ~0.5ns/op on my workstation with provided micro). We've been bitten before that adding cost to "".hashCode() has effect on some benchmarks, e.g., our internal XML implementation has some odd corner cases. Thus optimizing away a single branch from the calculating slow path (5% for the empty string, quickly diminishing overhead with increased String size) didn't seem worthwhile to me. /Claes On 2019-04-01 19:13, Martin Buchholz wrote: > I'm confused. > > We have always had > ? ? ? ? ?if (h == 0 && value.length > 0) { > so we have already been special-casing empty strings (maybe we should > stop?). > > Java has guaranteed that string literals are unique strings, but the > empty string is not special in this regard.? Archiving any string > literal and restoring it later should be identity-preserving, no? > > Whenever we test or benchmark zero-hash Strings, there are 3 cases that > should be covered - literal "", new String(), and (rare!) non-empty > Strings that happen to hash to 0. > > We could avoid archiving those rare?non-empty Strings that happen to > hash to 0 at archive time if it saved us a branch at runtime. From martinrb at google.com Mon Apr 1 18:01:21 2019 From: martinrb at google.com (Martin Buchholz) Date: Mon, 1 Apr 2019 11:01:21 -0700 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: <8a4c138b-5050-45a4-8c9e-ceb5b18a8dd8@oracle.com> References: <4e136b1e-3c20-44d5-8ecf-c1fd406967aa@oracle.com> <8a4c138b-5050-45a4-8c9e-ceb5b18a8dd8@oracle.com> Message-ID: Let me try again... We exclude 0-hash Strings from archiving because we might write to the hash field, BUT the existing guard value.length > 0 ensures that won't happen for empty Strings ... so WHY were we excluding empty Strings from archiving? On Mon, Apr 1, 2019 at 10:32 AM Claes Redestad wrote: > We could remove value.length > 0 and be net-neutral in #branches > for the general slow path (calculate the hash), but that would add a > branch to the emptyString.hashCode() _fast path_ (consistently add > ~0.5ns/op on my workstation with provided micro). We've been bitten > before that adding cost to "".hashCode() has effect on some benchmarks, > e.g., our internal XML implementation has some odd corner cases. > > Thus optimizing away a single branch from the calculating slow path (5% > for the empty string, quickly diminishing overhead with increased String > size) didn't seem worthwhile to me. > > /Claes > > On 2019-04-01 19:13, Martin Buchholz wrote: > > I'm confused. > > > > We have always had > > if (h == 0 && value.length > 0) { > > so we have already been special-casing empty strings (maybe we should > > stop?). > > > > Java has guaranteed that string literals are unique strings, but the > > empty string is not special in this regard. Archiving any string > > literal and restoring it later should be identity-preserving, no? > > > > Whenever we test or benchmark zero-hash Strings, there are 3 cases that > > should be covered - literal "", new String(), and (rare!) non-empty > > Strings that happen to hash to 0. > > > > We could avoid archiving those rare non-empty Strings that happen to > > hash to 0 at archive time if it saved us a branch at runtime. > From claes.redestad at oracle.com Mon Apr 1 18:08:15 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 1 Apr 2019 20:08:15 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: <4e136b1e-3c20-44d5-8ecf-c1fd406967aa@oracle.com> <8a4c138b-5050-45a4-8c9e-ceb5b18a8dd8@oracle.com> Message-ID: On 2019-04-01 20:01, Martin Buchholz wrote: > Let me try again...? We exclude 0-hash Strings from archiving because we > might write to the hash field, > BUT the existing guard > value.length > 0 > ensures that won't happen for empty Strings ... so WHY were we excluding > empty Strings from archiving? I don't think there was a strong reason for that, except maybe unwillingness to convolute the VM code. I'm now trying to remove this exclusion/limitation altogether with 8221724 alongside this RFE. Thanks! /Claes From dean.long at oracle.com Mon Apr 1 19:50:37 2019 From: dean.long at oracle.com (dean.long at oracle.com) Date: Mon, 1 Apr 2019 12:50:37 -0700 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: Message-ID: Wouldn't it be better to write a non-0 value when the computed hash code is 0, so we don't have to recompute it?? Is there some advantage to writing 0 instead of any other value, such as 1? dl On 4/1/19 4:57 AM, Claes Redestad wrote: > Hi, > > when a String has a calculated hash code value of 0, we recalculate and > store a 0 to the String.hash field every time (except for the empty > String, which is special cased). To make String objects more amenable to > storage in shared read-only memory, e.g., CDS archives, we should avoid > this redundant store. > > Bug:??? https://bugs.openjdk.java.net/browse/JDK-8221723 > Webrev: http://cr.openjdk.java.net/~redestad/8221723/ > > Testing: tier1-3, no regression on existing and new StringHashCode > micros > > /Claes > From martinrb at google.com Mon Apr 1 19:55:05 2019 From: martinrb at google.com (Martin Buchholz) Date: Mon, 1 Apr 2019 12:55:05 -0700 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: Message-ID: The spec says that "".hashCode() must be 0. https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#hashCode() On Mon, Apr 1, 2019 at 12:51 PM wrote: > Wouldn't it be better to write a non-0 value when the computed hash code > is 0, so we don't have to recompute it? Is there some advantage to > writing 0 instead of any other value, such as 1? > > dl > > On 4/1/19 4:57 AM, Claes Redestad wrote: > > Hi, > > > > when a String has a calculated hash code value of 0, we recalculate and > > store a 0 to the String.hash field every time (except for the empty > > String, which is special cased). To make String objects more amenable to > > storage in shared read-only memory, e.g., CDS archives, we should avoid > > this redundant store. > > > > Bug: https://bugs.openjdk.java.net/browse/JDK-8221723 > > Webrev: http://cr.openjdk.java.net/~redestad/8221723/ > > > > Testing: tier1-3, no regression on existing and new StringHashCode > > micros > > > > /Claes > > > > From dean.long at oracle.com Mon Apr 1 20:02:46 2019 From: dean.long at oracle.com (dean.long at oracle.com) Date: Mon, 1 Apr 2019 13:02:46 -0700 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: Message-ID: OK, I guess there's no ideal solution.? Adding a separate "not-computed" boolean adds space, and using a different sentinel value for "not-computed" would probably be slower on CPUs that have a fast compare-and-branch-against-zero instruction. dl On 4/1/19 12:55 PM, Martin Buchholz wrote: > The spec says that "".hashCode() must be 0. > https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#hashCode() > > > On Mon, Apr 1, 2019 at 12:51 PM > wrote: > > Wouldn't it be better to write a non-0 value when the computed > hash code > is 0, so we don't have to recompute it?? Is there some advantage to > writing 0 instead of any other value, such as 1? > > dl > > On 4/1/19 4:57 AM, Claes Redestad wrote: > > Hi, > > > > when a String has a calculated hash code value of 0, we > recalculate and > > store a 0 to the String.hash field every time (except for the empty > > String, which is special cased). To make String objects more > amenable to > > storage in shared read-only memory, e.g., CDS archives, we > should avoid > > this redundant store. > > > > Bug: https://bugs.openjdk.java.net/browse/JDK-8221723 > > Webrev: http://cr.openjdk.java.net/~redestad/8221723/ > > > > Testing: tier1-3, no regression on existing and new StringHashCode > > micros > > > > /Claes > > > From brian.goetz at oracle.com Mon Apr 1 20:08:16 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 1 Apr 2019 16:08:16 -0400 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: Message-ID: <534b4dff-7574-7982-1b75-fed813be8659@oracle.com> There's another reason to avoid these writes, besides CDS optimizations: do-nothing writes generate useless card mark activity. On 4/1/2019 7:57 AM, Claes Redestad wrote: > Hi, > > when a String has a calculated hash code value of 0, we recalculate and > store a 0 to the String.hash field every time (except for the empty > String, which is special cased). To make String objects more amenable to > storage in shared read-only memory, e.g., CDS archives, we should avoid > this redundant store. > > Bug:??? https://bugs.openjdk.java.net/browse/JDK-8221723 > Webrev: http://cr.openjdk.java.net/~redestad/8221723/ > > Testing: tier1-3, no regression on existing and new StringHashCode > micros > > /Claes > From shade at redhat.com Mon Apr 1 20:13:04 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 1 Apr 2019 22:13:04 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: <534b4dff-7574-7982-1b75-fed813be8659@oracle.com> References: <534b4dff-7574-7982-1b75-fed813be8659@oracle.com> Message-ID: On 4/1/19 10:08 PM, Brian Goetz wrote: > There's another reason to avoid these writes, besides CDS optimizations: do-nothing writes generate > useless card mark activity. Not for primitive stores, like hash code. But you can construct a funny workload where storing zero hash code would false-share with something important. I think CDS is the major use case here, and it is a legit one. -Aleksey From claes.redestad at oracle.com Mon Apr 1 20:44:46 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 1 Apr 2019 22:44:46 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: Message-ID: <865ae456-2c89-dd1b-17f9-457663584cba@oracle.com> We actually looked at this idea earlier today, and squeezing a "not- computed" value into String might be "free" since there seems to be a padding gap on all VM varieties (at least according to JOL estimates[1]) That'd be a larger endeavor, though, since there are places in VM that calculates and injects the String.hash value. /Claes [1] https://openjdk.java.net/projects/code-tools/jol/ On 2019-04-01 22:02, dean.long at oracle.com wrote: > OK, I guess there's no ideal solution.? Adding a separate "not-computed" > boolean adds space, and using a different sentinel value for > "not-computed" would probably be slower on CPUs that have a fast > compare-and-branch-against-zero instruction. > > dl > > On 4/1/19 12:55 PM, Martin Buchholz wrote: >> The spec says that "".hashCode() must be 0. >> https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#hashCode() >> >> >> >> On Mon, Apr 1, 2019 at 12:51 PM > > wrote: >> >> ??? Wouldn't it be better to write a non-0 value when the computed >> ??? hash code >> ??? is 0, so we don't have to recompute it?? Is there some advantage to >> ??? writing 0 instead of any other value, such as 1? >> >> ??? dl >> >> ??? On 4/1/19 4:57 AM, Claes Redestad wrote: >> ??? > Hi, >> ??? > >> ??? > when a String has a calculated hash code value of 0, we >> ??? recalculate and >> ??? > store a 0 to the String.hash field every time (except for the empty >> ??? > String, which is special cased). To make String objects more >> ??? amenable to >> ??? > storage in shared read-only memory, e.g., CDS archives, we >> ??? should avoid >> ??? > this redundant store. >> ??? > >> ??? > Bug: https://bugs.openjdk.java.net/browse/JDK-8221723 >> ??? > Webrev: http://cr.openjdk.java.net/~redestad/8221723/ >> ??? > >> ??? > Testing: tier1-3, no regression on existing and new StringHashCode >> ??? > micros >> ??? > >> ??? > /Claes >> ??? > >> > From forax at univ-mlv.fr Mon Apr 1 21:02:54 2019 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 1 Apr 2019 23:02:54 +0200 (CEST) Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: <865ae456-2c89-dd1b-17f9-457663584cba@oracle.com> References: <865ae456-2c89-dd1b-17f9-457663584cba@oracle.com> Message-ID: <1615756613.427016.1554152574451.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Claes Redestad" > ?: "Dean Long" , "Martin Buchholz" > Cc: "core-libs-dev" > Envoy?: Lundi 1 Avril 2019 22:44:46 > Objet: Re: RFR: 8221723: Avoid storing zero to String.hash > We actually looked at this idea earlier today, and squeezing a "not- > computed" value into String might be "free" since there seems to be a > padding gap on all VM varieties (at least according to JOL estimates[1]) Also the header of the underlying array (the array of bytes/chars) has space for a hashCode (the system one) but that value is never visible from the user POV, so you can use one bit of it. > > That'd be a larger endeavor, though, since there are places in VM that > calculates and injects the String.hash value. > > /Claes R?mi > > [1] https://openjdk.java.net/projects/code-tools/jol/ > > On 2019-04-01 22:02, dean.long at oracle.com wrote: >> OK, I guess there's no ideal solution.? Adding a separate "not-computed" >> boolean adds space, and using a different sentinel value for >> "not-computed" would probably be slower on CPUs that have a fast >> compare-and-branch-against-zero instruction. >> >> dl >> >> On 4/1/19 12:55 PM, Martin Buchholz wrote: >>> The spec says that "".hashCode() must be 0. >>> https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#hashCode() >>> >>> >>> >>> On Mon, Apr 1, 2019 at 12:51 PM >> > wrote: >>> >>> ??? Wouldn't it be better to write a non-0 value when the computed >>> ??? hash code >>> ??? is 0, so we don't have to recompute it?? Is there some advantage to >>> ??? writing 0 instead of any other value, such as 1? >>> >>> ??? dl >>> >>> ??? On 4/1/19 4:57 AM, Claes Redestad wrote: >>> ??? > Hi, >>> ??? > >>> ??? > when a String has a calculated hash code value of 0, we >>> ??? recalculate and >>> ??? > store a 0 to the String.hash field every time (except for the empty >>> ??? > String, which is special cased). To make String objects more >>> ??? amenable to >>> ??? > storage in shared read-only memory, e.g., CDS archives, we >>> ??? should avoid >>> ??? > this redundant store. >>> ??? > >>> ??? > Bug: https://bugs.openjdk.java.net/browse/JDK-8221723 >>> ??? > Webrev: http://cr.openjdk.java.net/~redestad/8221723/ >>> ??? > >>> ??? > Testing: tier1-3, no regression on existing and new StringHashCode >>> ??? > micros >>> ??? > >>> ??? > /Claes >>> ??? > >>> From john.r.rose at oracle.com Mon Apr 1 21:26:10 2019 From: john.r.rose at oracle.com (John Rose) Date: Mon, 1 Apr 2019 14:26:10 -0700 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: Message-ID: <14E51691-7357-485F-9C9D-349C37CB8666@oracle.com> On Apr 1, 2019, at 12:50 PM, dean.long at oracle.com wrote: > > Wouldn't it be better to write a non-0 value when the computed hash code is 0, so we don't have to recompute it? Is there some advantage to writing 0 instead of any other value, such as 1? Zero is the easiest sentinel value because it's the default value for int. *Any* 32-bit sentinel you choose will be the legitimate hashCode of *some* string. That is to say, the range of String.hashCode is all 2^32 points of the int domain. That's why we need an extra bit somewhere if we want to distinguish a sentinel (like zero) from an identical legitimate hash code that has been cached. Luckily, there is plenty of "slack" in the memory layout of String. We can find a bit, if we want to go there. ? John From peter.levart at gmail.com Mon Apr 1 21:54:04 2019 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 1 Apr 2019 23:54:04 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: <865ae456-2c89-dd1b-17f9-457663584cba@oracle.com> References: <865ae456-2c89-dd1b-17f9-457663584cba@oracle.com> Message-ID: On 4/1/19 10:44 PM, Claes Redestad wrote: > We actually looked at this idea earlier today, and squeezing a "not- > computed" value into String might be "free" since there seems to be a > padding gap on all VM varieties (at least according to JOL estimates[1]) > > That'd be a larger endeavor, though, since there are places in VM that > calculates and injects the String.hash value. In addition, this might not be easy from another point of view. You all know that there's no synchronization performed when caching the hash value. This works, because 32 bits are always read or written atomically. If there was another byte to be read or written together with 32 bit value, it would be tricky to get the ordering right and still keep the performance. Regards, Peter > > /Claes > > [1] https://openjdk.java.net/projects/code-tools/jol/ > > On 2019-04-01 22:02, dean.long at oracle.com wrote: >> OK, I guess there's no ideal solution. Adding a separate >> "not-computed" boolean adds space, and using a different sentinel >> value for "not-computed" would probably be slower on CPUs that have a >> fast compare-and-branch-against-zero instruction. >> >> dl >> >> On 4/1/19 12:55 PM, Martin Buchholz wrote: >>> The spec says that "".hashCode() must be 0. >>> https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#hashCode() >>> >>> >>> >>> On Mon, Apr 1, 2019 at 12:51 PM >> > wrote: >>> >>> ??? Wouldn't it be better to write a non-0 value when the computed >>> ??? hash code >>> ??? is 0, so we don't have to recompute it?? Is there some advantage to >>> ??? writing 0 instead of any other value, such as 1? >>> >>> ??? dl >>> >>> ??? On 4/1/19 4:57 AM, Claes Redestad wrote: >>> ??? > Hi, >>> ??? > >>> ??? > when a String has a calculated hash code value of 0, we >>> ??? recalculate and >>> ??? > store a 0 to the String.hash field every time (except for the >>> empty >>> ??? > String, which is special cased). To make String objects more >>> ??? amenable to >>> ??? > storage in shared read-only memory, e.g., CDS archives, we >>> ??? should avoid >>> ??? > this redundant store. >>> ??? > >>> ??? > Bug: https://bugs.openjdk.java.net/browse/JDK-8221723 >>> ??? > Webrev: http://cr.openjdk.java.net/~redestad/8221723/ >>> ??? > >>> ??? > Testing: tier1-3, no regression on existing and new >>> StringHashCode >>> ??? > micros >>> ??? > >>> ??? > /Claes >>> ??? > >>> >> From lance.andersen at oracle.com Tue Apr 2 00:22:07 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Mon, 1 Apr 2019 20:22:07 -0400 Subject: RFR: 8216539: tools/jar/modularJar/Basic.java timed out In-Reply-To: <832172a3-28e7-40ee-79d4-aa63be7b94ae@oracle.com> References: <238DBE20-3974-4900-81BB-1AE8A4E3021B@oracle.com> <554f9e31-e9bc-7a26-ad17-ccb3df910983@oracle.com> <2084129B-A859-44C6-BBC4-7C8DD9EB7C81@oracle.com> <832172a3-28e7-40ee-79d4-aa63be7b94ae@oracle.com> Message-ID: <877EC524-DA34-4365-9C63-19A2A458262A@oracle.com> A follow-up on this. I ran this test 300+ times without failure on the internal Mach 5 machines including the one that it failed on (which was only 4 times since January). This one system would run the test in approximately 6-7 minutes on average where as the the other window systems were running running around 1 - 1.5 minutes on average. After a side-bar conversation with Mandy/Alan it was suggested to try to use the ToolProvider API vs ProcessBuilder where applicable for invoking the javac and jar commands. With the change, the system that was running 6-7 minutes was down to 28 seconds on average on the slow machine. The webrev can be found at: http://cr.openjdk.java.net/~lancea/8216539/webrev.01/index.html > On Mar 27, 2019, at 8:23 PM, Mandy Chung wrote: > > > > On 3/27/19 4:56 PM, Lance Andersen wrote: >> Hi Mandy, >> >> >>> On Mar 27, 2019, at 7:23 PM, Mandy Chung > wrote: >>> >>> Hi Lance, >>> >>> Do you understand what takes so long for this test to run? >> >> Well it is executing a lot of jar commands. I did not see anything that sticks out in the failed logs that point to anything obvious. > > One thing you could do is to instrument the test to gather the timing statistics. > >>> Is it running fastdebug and -Xcomp or other flag? >> >> It is just a standard windows run. > > This is even strange if it's running normal product build. > > Mandy > >>> >>> Mandy >>> >>> On 3/27/19 1:55 PM, Lance Andersen wrote: >>>> Hi all , >>>> >>>> Please review this fix for https://bugs.openjdk.java.net/browse/JDK-8216539 which increases the timeout value for this test which fails once in a blue moon on windows. >>>> >>>> >>>> ??????? >>>> $ hg diff >>>> diff -r dc66ada06693 test/jdk/tools/jar/modularJar/Basic.java >>>> --- a/test/jdk/tools/jar/modularJar/Basic.java Tue Mar 26 15:36:19 2019 -0700 >>>> +++ b/test/jdk/tools/jar/modularJar/Basic.java Wed Mar 27 16:50:53 2019 -0400 >>>> @@ -54,7 +54,7 @@ >>>> * jdk.test.lib.util.FileUtils >>>> * jdk.test.lib.JDKToolFinder >>>> * @compile Basic.java >>>> - * @run testng Basic >>>> + * @run testng/timeout=300 Basic >>>> * @summary Tests for plain Modular jars & Multi-Release Modular jars >>>> */ >>>> >>>> >>>> ?????????? >>>> >>>> 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 >>>> >>>> >>>> >>> >> >> >> >> 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 mandy.chung at oracle.com Tue Apr 2 01:03:26 2019 From: mandy.chung at oracle.com (Mandy Chung) Date: Mon, 1 Apr 2019 18:03:26 -0700 Subject: RFR: 8216539: tools/jar/modularJar/Basic.java timed out In-Reply-To: <877EC524-DA34-4365-9C63-19A2A458262A@oracle.com> References: <238DBE20-3974-4900-81BB-1AE8A4E3021B@oracle.com> <554f9e31-e9bc-7a26-ad17-ccb3df910983@oracle.com> <2084129B-A859-44C6-BBC4-7C8DD9EB7C81@oracle.com> <832172a3-28e7-40ee-79d4-aa63be7b94ae@oracle.com> <877EC524-DA34-4365-9C63-19A2A458262A@oracle.com> Message-ID: <16b45794-9777-7301-3dc0-460f1c8d13a4@oracle.com> On 4/1/19 5:22 PM, Lance Andersen wrote: > ?A follow-up on this. > > I ran this test 300+ times without failure on the internal Mach 5 > machines including the one that it failed on (which was only 4 times > since January). ?This one system would run the test in approximately > 6-7 minutes on average where as the the other window systems were > running running around ?1 - 1.5 minutes on average. > > After a side-bar conversation with Mandy/Alan it was ?suggested to > ?try to ?use the ToolProvider API vs ProcessBuilder where applicable > for invoking the ?javac and jar commands. > > With the change, the system that was running 6-7 minutes was down to > 28 seconds on average on the slow machine. > This is very good improvement. > > The webrev can be found at: > http://cr.openjdk.java.net/~lancea/8216539/webrev.01/index.html > Looks okay to me. Mandy From brian.burkhalter at oracle.com Tue Apr 2 01:13:51 2019 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Mon, 1 Apr 2019 18:13:51 -0700 Subject: RFR: 8216539: tools/jar/modularJar/Basic.java timed out In-Reply-To: <16b45794-9777-7301-3dc0-460f1c8d13a4@oracle.com> References: <238DBE20-3974-4900-81BB-1AE8A4E3021B@oracle.com> <554f9e31-e9bc-7a26-ad17-ccb3df910983@oracle.com> <2084129B-A859-44C6-BBC4-7C8DD9EB7C81@oracle.com> <832172a3-28e7-40ee-79d4-aa63be7b94ae@oracle.com> <877EC524-DA34-4365-9C63-19A2A458262A@oracle.com> <16b45794-9777-7301-3dc0-460f1c8d13a4@oracle.com> Message-ID: > On Apr 1, 2019, at 6:03 PM, Mandy Chung wrote: > > On 4/1/19 5:22 PM, Lance Andersen wrote: >> A follow-up on this. >> >> I ran this test 300+ times without failure on the internal Mach 5 machines including the one that it failed on (which was only 4 times since January). This one system would run the test in approximately 6-7 minutes on average where as the the other window systems were running running around 1 - 1.5 minutes on average. >> >> After a side-bar conversation with Mandy/Alan it was suggested to try to use the ToolProvider API vs ProcessBuilder where applicable for invoking the javac and jar commands. >> >> With the change, the system that was running 6-7 minutes was down to 28 seconds on average on the slow machine. >> > > This is very good improvement. +1 >> >> The webrev can be found at: http://cr.openjdk.java.net/~lancea/8216539/webrev.01/index.html >> > > Looks okay to me. +1 Brian From amy.lu at oracle.com Tue Apr 2 06:40:39 2019 From: amy.lu at oracle.com (Amy Lu) Date: Tue, 2 Apr 2019 14:40:39 +0800 Subject: [JDK 13] RFR 8178335: fake pass: jdk/internal/ref/Cleaner/ExitOnThrow.java Message-ID: Please review the patch to fix a fake passed test: jdk/internal/ref/Cleaner/ExitOnThrow.java It expects the target test program exists with '1', and throws an exception. Due to the target test program be wrongly forked (missed --add-exports ), it exists with '1' but with unexpected java.lang.IllegalAccessError. bug: https://bugs.openjdk.java.net/browse/JDK-8178335 webrev: http://cr.openjdk.java.net/~amlu/8178335/webrev.00 Thanks, Amy From claes.redestad at oracle.com Tue Apr 2 08:29:15 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 2 Apr 2019 10:29:15 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: <865ae456-2c89-dd1b-17f9-457663584cba@oracle.com> Message-ID: Hi Peter, On 2019-04-01 23:54, Peter Levart wrote: > > On 4/1/19 10:44 PM, Claes Redestad wrote: >> We actually looked at this idea earlier today, and squeezing a "not- >> computed" value into String might be "free" since there seems to be a >> padding gap on all VM varieties (at least according to JOL estimates[1]) >> >> That'd be a larger endeavor, though, since there are places in VM that >> calculates and injects the String.hash value. > > In addition, this might not be easy from another point of view. You all > know that there's no synchronization performed when caching the hash > value. This works, because 32 bits are always read or written > atomically. If there was another byte to be read or written together > with 32 bit value, it would be tricky to get the ordering right and > still keep the performance. I won't do this for the current RFE, but it's an interesting topic for a future one. :-) Disclaimer: As I'm trying to be clever about concurrency I'm likely missing something... ... but I think a couple of barriers would be enough to ensure sufficient visibility/atomicity for this case, since the only catastrophic situation would be if another thread observes hash = 0 and hashCalculated = true when the real hash value is != 0. private boolean hashCalculated; private static Unsafe U = Unsafe.getUnsafe(); public int hashCode() { int h = hash; if (h == 0 && !hashCalculated) { if (!hashCalculated) { hash = h = isLatin1() ? StringLatin1.hashCode(value) : StringUTF16.hashCode(value); // Ensure the store of the hashCalculated value is not // reordered with the store of the hash value U.storeStoreFence(); hashCalculated = true; } else { // We could have lost a race where we read hash = 0, // then another thread stored hash and hashCalculated, // then we read hashCalculated = true when the real hash // value is not 0. // A re-read behind a load fence should be sufficient U.loadLoadFence(); h = hash; } } return h; } This is performance neutral on the fast-path (hash is calculated and non-zero), and the extra fences cost ~1.2ns/op on my machine for cases where the calculated hash code is 0, which is more or less the same overhead as the extra branches we have now. The benefit of course is that for non-empty Strings with hash 0 then repeated hashCode() invocation is now as fast as "".hashCode() (One performance risk is that the added calls to U.*Fence will mess up inlining heuristics.) Thanks! /Claes From adinn at redhat.com Tue Apr 2 09:12:45 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 2 Apr 2019 10:12:45 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes Message-ID: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> Could I please have reviews for the following enhancement: JIRA: https://bugs.openjdk.java.net/browse/JDK-8221397 webrev: http://cr.openjdk.java.net/~adinn/8221397/webrev.00/ Testing tier1 tests passed locally Submit job completed without error regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From Alan.Bateman at oracle.com Tue Apr 2 09:53:35 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 2 Apr 2019 10:53:35 +0100 Subject: RFR 8213031: (zipfs) Add support for POSIX file permissions In-Reply-To: References: <7b513a34196141f595cd5d194fb9d8a2@sap.com> <46af4f9d-60f9-c60d-e6f1-8fb97df3ba2e@oracle.com> <5d28b0715d2041ff892a3c44e024f120@sap.com> <8e9231ff-b7d5-bc2f-2643-713f3c670a1d@oracle.com> <3aeba9a64a434a968fc1d82a44077745@sap.com> <953449f0913340f6a94ae3d83611fd92@sap.com> <9b3c9cfe-63e9-94ea-1af0-7ba9e2db52fd@oracle.com> Message-ID: <84ec224a-e0d2-e843-310c-bbf41638f928@oracle.com> On 01/04/2019 14:38, Langer, Christoph wrote: > : > Hm, when I was looking at it initially, I was also wondering if it would be cleaner either have a default ZipFileAttributeView/ZipFileAttributes implementation that doesn't extend Posix or an "Enhanced" ZipFileAttributeView/ZipFileAttributes that would extend Posix. But I saw in the implementation of ZipFileAttributeView::get that this is already the "gate" where the requester would get the ZipFileAttributeView implementation with the requested behavior set. So I was hoping that it'd be fine to handle the Posix extension this way. Do you really think that wouldn't work? > > Alternatively, I could explore a different class hierarchy for ZipFileAttributeView/ZipFileAttributes... The issue with ZipFileAttributeView extending PosixFileAttributeView is that it change the attributes defined by the latter to optional, e.g. try readAttributes "zip:*" when enablePosixFileAttributes is enabled and disabled. I think it would be simpler, as least for the specification, to separate them. > : > >> As regards next steps then I think we need to agree the spec changes, as >> in the the javadoc in module-info.java. Once we have the spec agreed >> then the CSR can be updated and finalized. The code review can be done >> in parallel of course. I think Lance is going to help review the changes. > Ok, I guess this eventually boils down to agree upon the right way of doing the "permissions" attribute or is there something more related to the spec? > We'll need to do a bit of wordsmithing too. For example, the current draft has "It is possible to query a Path object .." when it should be saying "It is possible to query a file in a Zip file system ...".? This is all straight-forward, I think the main things now are to get agreement on the relationship between the different sets of attributes and the name of the permissions that the zip view supports. -Alan From claes.redestad at oracle.com Tue Apr 2 10:14:53 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 2 Apr 2019 12:14:53 +0200 Subject: RFR: 8221701: Archive constant BaseLocales In-Reply-To: <621b7ca9-acbc-02df-0ed4-7689ab234726@oracle.com> References: <621b7ca9-acbc-02df-0ed4-7689ab234726@oracle.com> Message-ID: <18af8ba9-3ba2-74d0-faa7-90f6d123f673@oracle.com> On 2019-04-01 17:46, Claes Redestad wrote: > Hi, > > by archiving constant BaseLocale objects, we can simplify (and speed up) > creation of the constant Locale objects in java.util.Locale which are > unconditionally created during startup. > > Bug:??? https://bugs.openjdk.java.net/browse/JDK-8221701 > Webrev: http://cr.openjdk.java.net/~redestad/8221701/open.00/ > > Testing: tier1-3, along with patches for JDK-8221723 and > JDK-8221724 These RFEs have now been pushed, unblocking this RFE. /Claes From Alan.Bateman at oracle.com Tue Apr 2 10:22:52 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 2 Apr 2019 11:22:52 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> Message-ID: On 02/04/2019 10:12, Andrew Dinn wrote: > Could I please have reviews for the following enhancement: > > JIRA: https://bugs.openjdk.java.net/browse/JDK-8221397 > webrev: http://cr.openjdk.java.net/~adinn/8221397/webrev.00/ > This updates the description for NonReadableChannelException/NonWriteableChannelException, I assume you didn't mean to include that in the patch. A corner case to consider is whether a map mode can be the empty string, maybe IAE should be thrown for that case. Are you planning a test to go along with this? It can test that the map method throws UOE and it can test the MapMode constructor. -Alan From peter.levart at gmail.com Tue Apr 2 10:53:04 2019 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 2 Apr 2019 12:53:04 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: <865ae456-2c89-dd1b-17f9-457663584cba@oracle.com> Message-ID: Hi Claes, On 4/2/19 10:29 AM, Claes Redestad wrote: > Hi Peter, > > On 2019-04-01 23:54, Peter Levart wrote: >> >> In addition, this might not be easy from another point of view. You >> all know that there's no synchronization performed when caching the >> hash value. This works, because 32 bits are always read or written >> atomically. If there was another byte to be read or written together >> with 32 bit value, it would be tricky to get the ordering right and >> still keep the performance. > > I won't do this for the current RFE, but it's an interesting topic for > a future one. :-) Right. And after I posted this message yesterday, it occurred to me that it is possible to get away without fences if this additional boolean flag is not called "hashCalculated" but "hashIsZero". Like in the following example: ??? private int hash; ??? private boolean hashIsZero; ??? public int hashCode() { ??????? int h = hash; ??????? if (h == 0 && !hashIsZero) { ??????????? h = isLatin1() ? StringLatin1.hashCode(value) ?????????????????????????? : StringUTF16.hashCode(value); ??????????? if (h == 0) { ??????????????? hashIsZero = true; ??????????? } else { ??????????????? hash = h; ??????????? } ??????? } ??????? return h; ??? } The trick here is that the logic writes to either 'hashIsZero' or to 'hash' field but never to both, so there's no ordering to be performed... Regards, Peter > > Disclaimer: As I'm trying to be clever about concurrency I'm likely > missing something... > > ... but I think a couple of barriers would be enough to ensure > sufficient visibility/atomicity for this case, since the only > catastrophic situation would be if another thread observes hash = 0 and > hashCalculated = true when the real hash value is != 0. > > ??? private boolean hashCalculated; > ??? private static Unsafe U = Unsafe.getUnsafe(); > > ??? public int hashCode() { > ??????? int h = hash; > ??????? if (h == 0 && !hashCalculated) { > ??????????? if (!hashCalculated) { > ??????????????? hash = h = isLatin1() ? StringLatin1.hashCode(value) > ??????????????????????? : StringUTF16.hashCode(value); > ??????????????? // Ensure the store of the hashCalculated value is not > ??????????????? // reordered with the store of the hash value > ??????????????? U.storeStoreFence(); > ??????????????? hashCalculated = true; > ??????????? } else { > ??????????????? // We could have lost a race where we read hash = 0, > ??????????????? // then another thread stored hash and hashCalculated, > ??????????????? // then we read hashCalculated = true when the real hash > ??????????????? // value is not 0. > ??????????????? // A re-read behind a load fence should be sufficient > ??????????????? U.loadLoadFence(); > ??????????????? h = hash; > ??????????? } > ??????? } > ??????? return h; > ??? } > > This is performance neutral on the fast-path (hash is calculated and > non-zero), and the extra fences cost ~1.2ns/op on my machine for cases > where the calculated hash code is 0, which is more or less the same > overhead as the extra branches we have now. The benefit of course is > that for non-empty Strings with hash 0 then repeated hashCode() > invocation is now as fast as "".hashCode() > > (One performance risk is that the added calls to U.*Fence will mess up > inlining heuristics.) > > Thanks! > > /Claes From peter.levart at gmail.com Tue Apr 2 10:56:30 2019 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 2 Apr 2019 12:56:30 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: References: <865ae456-2c89-dd1b-17f9-457663584cba@oracle.com> Message-ID: <7b1a9cf8-d411-9b19-611c-4e410ea13ff9@gmail.com> Hi Claes, I also think that the variant shown below should be compatible with existing VM code that "injects" hash value. No changes necessary, right? Peter On 4/2/19 12:53 PM, Peter Levart wrote: > Hi Claes, > > On 4/2/19 10:29 AM, Claes Redestad wrote: >> Hi Peter, >> >> On 2019-04-01 23:54, Peter Levart wrote: >>> >>> In addition, this might not be easy from another point of view. You >>> all know that there's no synchronization performed when caching the >>> hash value. This works, because 32 bits are always read or written >>> atomically. If there was another byte to be read or written together >>> with 32 bit value, it would be tricky to get the ordering right and >>> still keep the performance. >> >> I won't do this for the current RFE, but it's an interesting topic for >> a future one. :-) > > Right. And after I posted this message yesterday, it occurred to me > that it is possible to get away without fences if this additional > boolean flag is not called "hashCalculated" but "hashIsZero". Like in > the following example: > > ??? private int hash; > ??? private boolean hashIsZero; > > ??? public int hashCode() { > ??????? int h = hash; > ??????? if (h == 0 && !hashIsZero) { > ??????????? h = isLatin1() ? StringLatin1.hashCode(value) > ?????????????????????????? : StringUTF16.hashCode(value); > ??????????? if (h == 0) { > ??????????????? hashIsZero = true; > ??????????? } else { > ??????????????? hash = h; > ??????????? } > ??????? } > ??????? return h; > ??? } > > The trick here is that the logic writes to either 'hashIsZero' or to > 'hash' field but never to both, so there's no ordering to be performed... > > Regards, Peter > >> >> Disclaimer: As I'm trying to be clever about concurrency I'm likely >> missing something... >> >> ... but I think a couple of barriers would be enough to ensure >> sufficient visibility/atomicity for this case, since the only >> catastrophic situation would be if another thread observes hash = 0 and >> hashCalculated = true when the real hash value is != 0. >> >> ??? private boolean hashCalculated; >> ??? private static Unsafe U = Unsafe.getUnsafe(); >> >> ??? public int hashCode() { >> ??????? int h = hash; >> ??????? if (h == 0 && !hashCalculated) { >> ??????????? if (!hashCalculated) { >> ??????????????? hash = h = isLatin1() ? StringLatin1.hashCode(value) >> ??????????????????????? : StringUTF16.hashCode(value); >> ??????????????? // Ensure the store of the hashCalculated value is not >> ??????????????? // reordered with the store of the hash value >> ??????????????? U.storeStoreFence(); >> ??????????????? hashCalculated = true; >> ??????????? } else { >> ??????????????? // We could have lost a race where we read hash = 0, >> ??????????????? // then another thread stored hash and hashCalculated, >> ??????????????? // then we read hashCalculated = true when the real hash >> ??????????????? // value is not 0. >> ??????????????? // A re-read behind a load fence should be sufficient >> ??????????????? U.loadLoadFence(); >> ??????????????? h = hash; >> ??????????? } >> ??????? } >> ??????? return h; >> ??? } >> >> This is performance neutral on the fast-path (hash is calculated and >> non-zero), and the extra fences cost ~1.2ns/op on my machine for cases >> where the calculated hash code is 0, which is more or less the same >> overhead as the extra branches we have now. The benefit of course is >> that for non-empty Strings with hash 0 then repeated hashCode() >> invocation is now as fast as "".hashCode() >> >> (One performance risk is that the added calls to U.*Fence will mess up >> inlining heuristics.) >> >> Thanks! >> >> /Claes > From claes.redestad at oracle.com Tue Apr 2 11:10:04 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 2 Apr 2019 13:10:04 +0200 Subject: RFR: 8221723: Avoid storing zero to String.hash In-Reply-To: <7b1a9cf8-d411-9b19-611c-4e410ea13ff9@gmail.com> References: <865ae456-2c89-dd1b-17f9-457663584cba@oracle.com> <7b1a9cf8-d411-9b19-611c-4e410ea13ff9@gmail.com> Message-ID: <6ac2129b-7e06-2ee7-e837-1653eeea399a@oracle.com> Hi Peter, first: neat trick! On 2019-04-02 12:56, Peter Levart wrote: > Hi Claes, > > I also think that the variant shown below should be compatible with > existing VM code that "injects" hash value. No changes necessary, right? Kind of. If an injector forgets setting the hashIsZero bit, it'd just be set the first time someone calls hashCode, which is a small performance penalty in general, but a more real problem for the archive use case since we want to avoid any stores to the String object. Regardless, I think it'd be straightforward to update the hash injectors to do the right thing, especially now that we have a protocol that don't need any fences. I'll file an RFE and probably start working on this right away. Thanks! /Claes > > Peter > > On 4/2/19 12:53 PM, Peter Levart wrote: >> Hi Claes, >> >> On 4/2/19 10:29 AM, Claes Redestad wrote: >>> Hi Peter, >>> >>> On 2019-04-01 23:54, Peter Levart wrote: >>>> >>>> In addition, this might not be easy from another point of view. You >>>> all know that there's no synchronization performed when caching the >>>> hash value. This works, because 32 bits are always read or written >>>> atomically. If there was another byte to be read or written together >>>> with 32 bit value, it would be tricky to get the ordering right and >>>> still keep the performance. >>> >>> I won't do this for the current RFE, but it's an interesting topic for >>> a future one. :-) >> >> Right. And after I posted this message yesterday, it occurred to me >> that it is possible to get away without fences if this additional >> boolean flag is not called "hashCalculated" but "hashIsZero". Like in >> the following example: >> >> ??? private int hash; >> ??? private boolean hashIsZero; >> >> ??? public int hashCode() { >> ??????? int h = hash; >> ??????? if (h == 0 && !hashIsZero) { >> ??????????? h = isLatin1() ? StringLatin1.hashCode(value) >> ?????????????????????????? : StringUTF16.hashCode(value); >> ??????????? if (h == 0) { >> ??????????????? hashIsZero = true; >> ??????????? } else { >> ??????????????? hash = h; >> ??????????? } >> ??????? } >> ??????? return h; >> ??? } >> >> The trick here is that the logic writes to either 'hashIsZero' or to >> 'hash' field but never to both, so there's no ordering to be performed... >> >> Regards, Peter From sgehwolf at redhat.com Tue Apr 2 11:48:22 2019 From: sgehwolf at redhat.com (Severin Gehwolf) Date: Tue, 02 Apr 2019 13:48:22 +0200 Subject: [PING] RFR: 8217338: [Containers] Improve systemd slice memory limit support In-Reply-To: <226CB44C-7B3A-42E8-8385-4E85168DBA4E@oracle.com> References: <4a1ae4e0e3efd68818bfe868349972aa878de60b.camel@redhat.com> <9a911da4b2a4a8eff42c7c2f1a19c06f6521da8d.camel@redhat.com> <226CB44C-7B3A-42E8-8385-4E85168DBA4E@oracle.com> Message-ID: <254f53446176175689373b346c11aabc26d9b4b0.camel@redhat.com> Could I get a second review, please? Thanks, Severin On Thu, 2019-03-28 at 11:37 -0400, Bob Vandette wrote: > Sorry for the delay. The update looks good. > > Bob. > > > > On Mar 25, 2019, at 1:30 PM, Severin Gehwolf wrote: > > > > On Fri, 2019-03-22 at 14:25 -0400, Bob Vandette wrote: > > > Could you maybe combine subsystem_file_contents with subsystem_file_line_contents > > > by adding an additional argument? > > > > Done: http://cr.openjdk.java.net/~sgehwolf/webrevs/JDK-8217338/05/webrev/ > > > > Thanks, > > Severin > > From matthias.baesken at sap.com Tue Apr 2 12:54:57 2019 From: matthias.baesken at sap.com (Baesken, Matthias) Date: Tue, 2 Apr 2019 12:54:57 +0000 Subject: RFR: 8218547: Simplify JLI_Open on Windows in native code (libjli) - was : RE: RFR : 8217093: Support extended-length paths in parse_manifest.c on windows In-Reply-To: <43304634-d902-b006-3159-3537433d9f67@oracle.com> References: <758af3c4-c59f-ea25-8491-2dcdab7bda17@oracle.com> <43304634-d902-b006-3159-3537433d9f67@oracle.com> Message-ID: Hi Alan, here is a new webrev : http://cr.openjdk.java.net/~mbaesken/webrevs/8218547.3/webrev/ re-formatted the comment in java_md.c to avoid VERY LONG lines adjusted test/jdk/tools/launcher/Arrrghs.java Best regards, Matthias > -----Original Message----- > From: Alan Bateman > Sent: Samstag, 30. M?rz 2019 10:04 > To: Baesken, Matthias > Cc: core-libs-dev at openjdk.java.net > Subject: Re: RFR: 8218547: Simplify JLI_Open on Windows in native code > (libjli) - was : RE: RFR : 8217093: Support extended-length paths in > parse_manifest.c on windows > > On 29/03/2019 12:36, Baesken, Matthias wrote: > > Thanks. Alan, are you fine with the current webrev, if yes may I add you as > reviewer ? > > > The update to java_md.c looks okay, I probably would re-format the > comment to void the line longs but it is otherwise okay. > > I think the new test needs a of bit clean-up, L490 is the main issue. > One suggest is to rename pLong to longPath and build up ots value in a > loop to avoid having a 340+ character line? The other variables names > are very strange too but I can you can eliminate some of them by > changing L491-492 to: > ???? Path jarPath = Files.createDirectories(longPah).resolve("foo.jar"); > > -Alan > From adinn at redhat.com Tue Apr 2 15:12:15 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 2 Apr 2019 16:12:15 +0100 Subject: RFR: 8221477: Inject os/cpu-specific constants into Unsafe from JVM In-Reply-To: <21b14ecd-4b24-8601-4b07-50d7ac516493@oracle.com> References: <2fc62430-2e2e-9ee5-ccf1-f1cde5cea416@redhat.com> <8b0f5b4c-0386-1440-6939-646daf36aa55@redhat.com> <24b4bb72-732e-0447-d1be-dd71507e7787@redhat.com> <945d9546-5195-ab33-0e20-57871c2f1ef9@oracle.com> <2a26715f-fa64-9de4-1071-b18d07c05511@redhat.com> <936d213e-9c75-6af4-a7f6-bab6a0f320bb@oracle.com> <21b14ecd-4b24-8601-4b07-50d7ac516493@oracle.com> Message-ID: Hi David, Thanks very much for investigating this and posting your recommendations. On 01/04/2019 08:15, David Holmes wrote: >> I did some analysis of the class loading and initialization sequence >> and added my suggestions to bug report. In summary loading seems >> somewhat immaterial so I suggest: >> >> - javaClasses.hpp: Add UnsafeConstants at the end of >> BASIC_JAVA_CLASSES_DO_PART2 >> - systemDictionary.hpp: Add UnsafeConstants immediately before Unsafe >> >> Then for init: >> - thread.cpp: initialize UnsafeConstants immediately after j.l.Module I have done all of the above. Also, in javaClasses.hpp to keep things uniform I moved the class decl for jdk_internal_misc_UnsafeConstants to follow that of class java_..._AbstractOwnableSynchronizer i.e. the class decl order matches the order of the do_klass statements. >> It would be desirable to detect if we happen to execute the >> earlier (by accident) so I suggest adding a "not initialized" >> assertion prior to your code calling initialize_class. Actually that >> might be a useful addition to the initialize_class method, as if it >> fires it means we're not initializing in the expected order ... I'll >> run a little adding that ... > > I meant to say "run a little test". Turns out you can't put the > assertion in initialize_class as the initialization can vary for some of > the exception classes (at least) depending on VM flags used (e.g. -Xrs, > and I think certain logging options). Ok, thanks. I have added the following immediately before calling initialize_class. #ifdef ASSERT InstanceKlass *k = SystemDictionary::UnsafeConstants_klass(); assert(k->is_not_initialized(), "UnsafeConstants should not already be initialized"); #endif . . . I'll wait for feedback from Coleen before sending an updated webrev. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From naoto.sato at oracle.com Tue Apr 2 15:36:57 2019 From: naoto.sato at oracle.com (Naoto Sato) Date: Tue, 2 Apr 2019 08:36:57 -0700 Subject: RFR: 8221701: Archive constant BaseLocales In-Reply-To: <18af8ba9-3ba2-74d0-faa7-90f6d123f673@oracle.com> References: <621b7ca9-acbc-02df-0ed4-7689ab234726@oracle.com> <18af8ba9-3ba2-74d0-faa7-90f6d123f673@oracle.com> Message-ID: <2fff4c88-431d-3cf8-11ae-b650b58361f4@oracle.com> Hi Claes, Thank you for looking into this. I remember we discussed this before. One comment I have is that, currently the archive map seems to have two level structure, i.e, lang, then country. There is another basic element that consists of a locale, that is script. At the moment, there is not a constant that has script in it, but if we wanted to have a constant locale, say zh-Hans, it cannot be archived. It's ok for now, but can it be extended if we want in the future, without any compatibility implications? Naoto On 4/2/19 3:14 AM, Claes Redestad wrote: > > > On 2019-04-01 17:46, Claes Redestad wrote: >> Hi, >> >> by archiving constant BaseLocale objects, we can simplify (and speed up) >> creation of the constant Locale objects in java.util.Locale which are >> unconditionally created during startup. >> >> Bug:??? https://bugs.openjdk.java.net/browse/JDK-8221701 >> Webrev: http://cr.openjdk.java.net/~redestad/8221701/open.00/ >> >> Testing: tier1-3, along with patches for JDK-8221723 and >> JDK-8221724 > > These RFEs have now been pushed, unblocking this RFE. > > /Claes From mandy.chung at oracle.com Tue Apr 2 16:02:11 2019 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 2 Apr 2019 09:02:11 -0700 Subject: [JDK 13] RFR 8178335: fake pass: jdk/internal/ref/Cleaner/ExitOnThrow.java In-Reply-To: References: Message-ID: <59ce6414-d68e-144c-175a-0666929504aa@oracle.com> On 4/1/19 11:40 PM, Amy Lu wrote: > Please review the patch to fix a fake passed test: > > jdk/internal/ref/Cleaner/ExitOnThrow.java > > It expects the target test program exists with '1', and throws an > exception. Due to the target test program be wrongly forked (missed > --add-exports ), it exists with '1' but with unexpected > java.lang.IllegalAccessError. > > bug: https://bugs.openjdk.java.net/browse/JDK-8178335 > webrev: http://cr.openjdk.java.net/~amlu/8178335/webrev.00 Looks good. Mandy From lance.andersen at oracle.com Tue Apr 2 19:35:09 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Tue, 2 Apr 2019 15:35:09 -0400 Subject: Review Request: JDK-8220282 Add MethodHandle tests on accessing final fields In-Reply-To: References: <8fb939e4-afbc-6711-1d16-b0c7f34d0a10@oracle.com> Message-ID: <460F7BB9-0EA2-42DE-AE49-2AF4C9C00698@oracle.com> Hi Mandy the updates look good. > On Mar 26, 2019, at 10:58 PM, Mandy Chung wrote: > > This is a new version of the patch: > http://cr.openjdk.java.net/~mchung/jdk13/webrevs/8220282/webrev.01 > > I made further clean up to this new test. > > It extends MethodHandlesTest.HasFields class to include the test > cases for instance final fields. HasFields is used to test > findGetter/findStaticGetter, findSetter/findStaticSetter, and > unreflectSetter/unreflectGetter. > > A new HasFields::testCasesFor(int testMode) method is added to > return the test cases where c[1] == Error.class indicates a > negative test case. > > For getters, all HasFields except bogus_xx fields are positive > test cases, i.e. no exception is expected. > > For findSetter/findStaticSetter, a final field has no write access > and setting on a final field is a negative test case. > > For unreflectSetter, non-final fields and instance final fields > whose accessible flag is true have write access and hence they > are positive test cases whereas static final fields are negative > test cases. > > thanks > Mandy > 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 vlv.spb.ru at mail.ru Tue Apr 2 20:51:49 2019 From: vlv.spb.ru at mail.ru (=?UTF-8?B?VmxhZGltaXIgWWFyb3NsYXZza2l5?=) Date: Tue, 02 Apr 2019 23:51:49 +0300 Subject: =?UTF-8?B?VGhlIGZpbmFsIHZlcnNpb24gb2YgRHVhbC1QaXZvdCBRdWlja3NvcnQ6IHYu?= =?UTF-8?B?MTc=?= Message-ID: <1554238309.700424544@f388.i.mail.ru> Hi team, Please find my improved version, v17, it was optimized for sorting small arrays. Summary of changes: 1. Mixed insertion sort is introduced: it is combination of simple insertion sort, pin insertion sort and pair insertion sort. Simple insertion sort is invoked on tiny array. In case of small part we start with pin insertion sort (small element is inserted at the beginning, large element is moved to the end). Then we continue with pair insertion sort on remain part. Optimized combination of various types of insertion sorts allows to increase threshold for Quicksort and makes whole sorting faster. 2. Heap sort is used only if execution time is becoming quadratic, not for sorting small arrays. 3. New tests are added against heap sort. 4. Minor javadoc changes: double spaces are removed. ParallelSorting class will be deleted, because Sorting test class covers both: sequential and parallel algorithms. @Doug, @Laurent Could you please look at new sources? Thank you, Vladimir From vlv.spb.ru at mail.ru Tue Apr 2 20:52:59 2019 From: vlv.spb.ru at mail.ru (=?UTF-8?B?VmxhZGltaXIgWWFyb3NsYXZza2l5?=) Date: Tue, 02 Apr 2019 23:52:59 +0300 Subject: =?UTF-8?B?VGhlIGZpbmFsIHZlcnNpb24gb2YgRHVhbC1QaXZvdCBRdWlja3NvcnQ6IHYx?= =?UTF-8?B?LjcgKEFycmF5cy5qYXZhKQ==?= Message-ID: <1554238379.59076364@f501.i.mail.ru> + Arrays class From claes.redestad at oracle.com Tue Apr 2 22:22:26 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Wed, 3 Apr 2019 00:22:26 +0200 Subject: RFR: 8221701: Archive constant BaseLocales In-Reply-To: <2fff4c88-431d-3cf8-11ae-b650b58361f4@oracle.com> References: <621b7ca9-acbc-02df-0ed4-7689ab234726@oracle.com> <18af8ba9-3ba2-74d0-faa7-90f6d123f673@oracle.com> <2fff4c88-431d-3cf8-11ae-b650b58361f4@oracle.com> Message-ID: <03aa99f5-ea7d-8f29-cda6-1057130c5d2d@oracle.com> Hi Naoto, thanks for reviewing! On 2019-04-02 17:36, Naoto Sato wrote: > Hi Claes, > > Thank you for looking into this. I remember we discussed this before. > One comment I have is that, currently the archive map seems to have two > level structure, i.e, lang, then country. There is another basic element > that consists of a locale, that is script. At the moment, there is not a > constant that has script in it, but if we wanted to have a constant > locale, say zh-Hans, it cannot be archived. It's ok for now, but can it > be extended if we want in the future, without any compatibility > implications? You're right that adding a constant with script would force a rewrite. One alternative solution is to not use nested maps, but instead archive an array of BaseLocales that we iterate over: http://cr.openjdk.java.net/~redestad/8221701/open.01/ This has more boilerplate but is simpler in structure and I believe easier to maintain. This is also significantly faster on startup than the previous iteration (also when default Locale is not in the set of predefined constants). Performance of many repeated calls to new Locale/Locale.getInstance sees a drop with either approach (from ~0.5us/op to ~0.7us/op on a new Locale("se", "SV") micro), but I believe creation of Locale objects are unlikely to be on the critical path. What do you think? Thanks! /Claes > > Naoto > > On 4/2/19 3:14 AM, Claes Redestad wrote: >> >> >> On 2019-04-01 17:46, Claes Redestad wrote: >>> Hi, >>> >>> by archiving constant BaseLocale objects, we can simplify (and speed up) >>> creation of the constant Locale objects in java.util.Locale which are >>> unconditionally created during startup. >>> >>> Bug:??? https://bugs.openjdk.java.net/browse/JDK-8221701 >>> Webrev: http://cr.openjdk.java.net/~redestad/8221701/open.00/ >>> >>> Testing: tier1-3, along with patches for JDK-8221723 and >>> JDK-8221724 >> >> These RFEs have now been pushed, unblocking this RFE. >> >> /Claes From naoto.sato at oracle.com Wed Apr 3 03:25:09 2019 From: naoto.sato at oracle.com (naoto.sato at oracle.com) Date: Tue, 2 Apr 2019 20:25:09 -0700 Subject: RFR: 8221701: Archive constant BaseLocales In-Reply-To: <03aa99f5-ea7d-8f29-cda6-1057130c5d2d@oracle.com> References: <621b7ca9-acbc-02df-0ed4-7689ab234726@oracle.com> <18af8ba9-3ba2-74d0-faa7-90f6d123f673@oracle.com> <2fff4c88-431d-3cf8-11ae-b650b58361f4@oracle.com> <03aa99f5-ea7d-8f29-cda6-1057130c5d2d@oracle.com> Message-ID: <5827ddbb-60f5-4231-d0f4-d0234c331e90@oracle.com> Hi Claes, The new version looks good, and I like this approach better. Simpler and easily maintainable IMO. Also I like the improved startup time, which I think is more important than multiple creation of Locale instances, which is not very common. Naoto On 4/2/19 3:22 PM, Claes Redestad wrote: > Hi Naoto, > > thanks for reviewing! > > On 2019-04-02 17:36, Naoto Sato wrote: >> Hi Claes, >> >> Thank you for looking into this. I remember we discussed this before. >> One comment I have is that, currently the archive map seems to have >> two level structure, i.e, lang, then country. There is another basic >> element that consists of a locale, that is script. At the moment, >> there is not a constant that has script in it, but if we wanted to >> have a constant locale, say zh-Hans, it cannot be archived. It's ok >> for now, but can it be extended if we want in the future, without any >> compatibility implications? > > You're right that adding a constant with script would force a rewrite. > One alternative solution is to not use nested maps, but instead archive > an array of BaseLocales that we iterate over: > > http://cr.openjdk.java.net/~redestad/8221701/open.01/ > > This has more boilerplate but is simpler in structure and I believe > easier to maintain. This is also significantly faster on startup than > the previous iteration (also when default Locale is not in the set of > predefined constants). > > Performance of many repeated calls to new Locale/Locale.getInstance sees > a drop with either approach (from ~0.5us/op to ~0.7us/op on a new > Locale("se", "SV") micro), but I believe creation of Locale objects are > unlikely to be on the critical path. > > What do you think? > > Thanks! > > /Claes > >> >> Naoto >> >> On 4/2/19 3:14 AM, Claes Redestad wrote: >>> >>> >>> On 2019-04-01 17:46, Claes Redestad wrote: >>>> Hi, >>>> >>>> by archiving constant BaseLocale objects, we can simplify (and speed >>>> up) >>>> creation of the constant Locale objects in java.util.Locale which are >>>> unconditionally created during startup. >>>> >>>> Bug:??? https://bugs.openjdk.java.net/browse/JDK-8221701 >>>> Webrev: http://cr.openjdk.java.net/~redestad/8221701/open.00/ >>>> >>>> Testing: tier1-3, along with patches for JDK-8221723 and >>>> JDK-8221724 >>> >>> These RFEs have now been pushed, unblocking this RFE. >>> >>> /Claes From amy.lu at oracle.com Wed Apr 3 05:31:34 2019 From: amy.lu at oracle.com (Amy Lu) Date: Wed, 3 Apr 2019 13:31:34 +0800 Subject: [JDK 13] RFR 8178335: fake pass: jdk/internal/ref/Cleaner/ExitOnThrow.java In-Reply-To: <59ce6414-d68e-144c-175a-0666929504aa@oracle.com> References: <59ce6414-d68e-144c-175a-0666929504aa@oracle.com> Message-ID: <0614d755-1666-5f86-03fd-96820359475a@oracle.com> Thank you Mandy! Pushed. Thanks, Amy On 4/3/19 12:02 AM, Mandy Chung wrote: > > > On 4/1/19 11:40 PM, Amy Lu wrote: >> Please review the patch to fix a fake passed test: >> >> jdk/internal/ref/Cleaner/ExitOnThrow.java >> >> It expects the target test program exists with '1', and throws an >> exception. Due to the target test program be wrongly forked (missed >> --add-exports ), it exists with '1' but with unexpected >> java.lang.IllegalAccessError. >> >> bug: https://bugs.openjdk.java.net/browse/JDK-8178335 >> webrev: http://cr.openjdk.java.net/~amlu/8178335/webrev.00 > > Looks good. > > Mandy From adinn at redhat.com Wed Apr 3 09:10:19 2019 From: adinn at redhat.com (Andrew Dinn) Date: Wed, 3 Apr 2019 10:10:19 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> Message-ID: Hi Alan, Thanks for reviewing this patch. On 02/04/2019 11:22, Alan Bateman wrote: > On 02/04/2019 10:12, Andrew Dinn wrote: >> Could I please have reviews for the following enhancement: >> >> JIRA:?? https://bugs.openjdk.java.net/browse/JDK-8221397 >> webrev: http://cr.openjdk.java.net/~adinn/8221397/webrev.00/ Updated webrev: http://cr.openjdk.java.net/~adinn/8221397/webrev.01 Testing: Updated test (MapTest) passes. Submit job in progress. Details of changes below: > This updates the description for > NonReadableChannelException/NonWriteableChannelException, I assume you > didn't mean to include that in the patch. Yes, that was a leftover from the full JEP change set that I have now removed. > A corner case to consider is whether a map mode can be the empty string, > maybe IAE should be thrown for that case. I have added a test for this case which throws IAE if an empty string is found. I also updated the javadoc accordingly. > Are you planning a test to go along with this? It can test that the map > method throws UOE and it can test the MapMode constructor. I added test code to existing test MapTest as it seemed closely related and was even able to reuse the check method. The new tests ensure that 1) illegal user map mode names are rejected and 2) attempts to pass a user-defined map mode in a map call for a normal file channel are rejected. In order to get this to pass I updated method FileChannelImpl.map to allow for the possibility of user-defined map modes. It no longer asserts if map mode is unrecognized but instead throws an UnsupportedOperationException. I still have two undecided points you might advise on: Does the javadoc for FileChannel.map and/or FileChannelImpl.map need updating to record the possibility that UOE might be thrown? Do I need to update any other implementations of map to cater for the possibility of user-defined map modes? regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From claes.redestad at oracle.com Wed Apr 3 14:12:16 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Wed, 3 Apr 2019 16:12:16 +0200 Subject: RFR: 8221701: Archive constant BaseLocales In-Reply-To: <5827ddbb-60f5-4231-d0f4-d0234c331e90@oracle.com> References: <621b7ca9-acbc-02df-0ed4-7689ab234726@oracle.com> <18af8ba9-3ba2-74d0-faa7-90f6d123f673@oracle.com> <2fff4c88-431d-3cf8-11ae-b650b58361f4@oracle.com> <03aa99f5-ea7d-8f29-cda6-1057130c5d2d@oracle.com> <5827ddbb-60f5-4231-d0f4-d0234c331e90@oracle.com> Message-ID: <971c61c7-dd96-5ee3-cee7-6a848bcf77a8@oracle.com> Hi Naoto, On 2019-04-03 05:25, naoto.sato at oracle.com wrote: > Hi Claes, > > The new version looks good, and I like this approach better. Simpler and > easily maintainable IMO. Also I like the improved startup time, which I > think is more important than multiple creation of Locale instances, > which is not very common. thanks! I've gotten it through tier1-3 and will push shortly. /Claes From raffaello.giulietti at gmail.com Wed Apr 3 14:43:22 2019 From: raffaello.giulietti at gmail.com (Raffaello Giulietti) Date: Wed, 3 Apr 2019 16:43:22 +0200 Subject: [PATCH] 4511638: Double.toString(double) sometimes produces incorrect results Message-ID: Hi, in this patch there are additional white-box tests against critical package private entities in the jdk.internal.math classes. In particular the class jdk.internal.math.MathUtils is thoroughly tested. Also, the tag @key randomness is now used along jdk.test.lib.RandomFactory. To run the tests make test TEST="jtreg:test/jdk/jdk/internal/math/ToDecimal" Brian Burkhalter, my sponsor, will soon publish the patch in webrev form. Of course, if anybody would like to step forward as a reviewer I'll be glad to help. Greetings Raffaello ---- # HG changeset patch # Date 1554293915 -7200 # Wed Apr 03 14:18:35 2019 +0200 # Node ID ba8f29ece3ce61c217e5c77748067bb3d4d2f5ad # Parent f9feec76a481a0f53e907c68f48253138b621d38 Patch to fix JDK-4511638 4511638: Double.toString(double) sometimes produces incorrect results Reviewed-by: TBD Contributed-by: Raffaello Giulietti diff --git a/src/java.base/share/classes/java/lang/Double.java b/src/java.base/share/classes/java/lang/Double.java --- a/src/java.base/share/classes/java/lang/Double.java +++ b/src/java.base/share/classes/java/lang/Double.java @@ -32,6 +32,7 @@ import jdk.internal.math.FloatingDecimal; import jdk.internal.math.DoubleConsts; +import jdk.internal.math.DoubleToDecimal; import jdk.internal.HotSpotIntrinsicCandidate; /** @@ -145,69 +146,120 @@ public static final Class TYPE = (Class) Class.getPrimitiveClass("double"); /** - * Returns a string representation of the {@code double} - * argument. All characters mentioned below are ASCII characters. - *
    - *
  • If the argument is NaN, the result is the string - * "{@code NaN}". - *
  • Otherwise, the result is a string that represents the sign and - * magnitude (absolute value) of the argument. If the sign is negative, - * the first character of the result is '{@code -}' - * ({@code '\u005Cu002D'}); if the sign is positive, no sign character - * appears in the result. As for the magnitude m: - *
      - *
    • If m is infinity, it is represented by the characters - * {@code "Infinity"}; thus, positive infinity produces the result - * {@code "Infinity"} and negative infinity produces the result - * {@code "-Infinity"}. - * - *
    • If m is zero, it is represented by the characters - * {@code "0.0"}; thus, negative zero produces the result - * {@code "-0.0"} and positive zero produces the result - * {@code "0.0"}. + * Returns a string rendering of the {@code double} argument. * - *
    • If m is greater than or equal to 10-3 but less - * than 107, then it is represented as the integer part of - * m, in decimal form with no leading zeroes, followed by - * '{@code .}' ({@code '\u005Cu002E'}), followed by one or - * more decimal digits representing the fractional part of m. - * - *
    • If m is less than 10-3 or greater than or - * equal to 107, then it is represented in so-called - * "computerized scientific notation." Let n be the unique - * integer such that 10nm {@literal <} - * 10n+1; then let a be the - * mathematically exact quotient of m and - * 10n so that 1 ≤ a {@literal <} 10. The - * magnitude is then represented as the integer part of a, - * as a single decimal digit, followed by '{@code .}' - * ({@code '\u005Cu002E'}), followed by decimal digits - * representing the fractional part of a, followed by the - * letter '{@code E}' ({@code '\u005Cu0045'}), followed - * by a representation of n as a decimal integer, as - * produced by the method {@link Integer#toString(int)}. + *

      The characters of the result are all drawn from the ASCII set. + *

        + *
      • Any NaN, whether quiet or signaling, is rendered as + * {@code "NaN"}, regardless of the sign bit. + *
      • The infinities +∞ and -∞ are rendered as + * {@code "Infinity"} and {@code "-Infinity"}, respectively. + *
      • The positive and negative zeroes are rendered as + * {@code "0.0"} and {@code "-0.0"}, respectively. + *
      • A finite negative {@code v} is rendered as the sign + * '{@code -}' followed by the rendering of the magnitude -{@code v}. + *
      • A finite positive {@code v} is rendered in two stages: + *
          + *
        • Selection of a decimal: A well-defined + * decimal dv is selected + * to represent {@code v}. + *
        • Formatting as a string: The decimal + * dv is formatted as a string, + * either in plain or in computerized scientific notation, + * depending on its value. *
        *
      - * How many digits must be printed for the fractional part of - * m or a? There must be at least one digit to represent - * the fractional part, and beyond that as many, but only as many, more - * digits as are needed to uniquely distinguish the argument value from - * adjacent values of type {@code double}. That is, suppose that - * x is the exact mathematical value represented by the decimal - * representation produced by this method for a finite nonzero argument - * d. Then d must be the {@code double} value nearest - * to x; or if two {@code double} values are equally close - * to x, then d must be one of them and the least - * significant bit of the significand of d must be {@code 0}. + * + *

      A decimal is a number of the form + * d×10i + * for some (unique) integers d > 0 and i such that + * d is not a multiple of 10. + * These integers are the significand and + * the exponent, respectively, of the decimal. + * The length of the decimal is the (unique) + * integer n meeting + * 10n-1d < 10n. + * + *

      The decimal dv + * for a finite positive {@code v} is defined as follows: + *

        + *
      • Let R be the set of all decimals that round to {@code v} + * according to the usual round-to-closest rule of + * IEEE 754 floating-point arithmetic. + *
      • Let m be the minimal length over all decimals in R. + *
      • When m ≥ 2, let T be the set of all decimals + * in R with length m. + * Otherwise, let T be the set of all decimals + * in R with length 1 or 2. + *
      • Define dv as + * the decimal in T that is closest to {@code v}. + * Or if there are two such decimals in T, + * select the one with the even significand (there is exactly one). + *
      + * + *

      The (uniquely) selected decimal dv + * is then formatted. * - *

      To create localized string representations of a floating-point - * value, use subclasses of {@link java.text.NumberFormat}. + *

      Let d, i and n be the significand, exponent and + * length of dv, respectively. + * Further, let e = n + i - 1 and let + * d1dn + * be the usual decimal expansion of the significand. + * Note that d1 ≠ 0 ≠ dn. + *

        + *
      • Case -3 ≤ e < 0: + * dv is formatted as + * 0.00d1dn, + * where there are exactly -(n + i) zeroes between + * the decimal point and d1. + * For example, 123 × 10-4 is formatted as + * {@code 0.0123}. + *
      • Case 0 ≤ e < 7: + *
          + *
        • Subcase i ≥ 0: + * dv is formatted as + * d1dn00.0, + * where there are exactly i zeroes + * between dn and the decimal point. + * For example, 123 × 102 is formatted as + * {@code 12300.0}. + *
        • Subcase i < 0: + * dv is formatted as + * d1dn+i.dn+i+1dn. + * There are exactly -i digits to the right of + * the decimal point. + * For example, 123 × 10-1 is formatted as + * {@code 12.3}. + *
        + *
      • Case e < -3 or e ≥ 7: + * computerized scientific notation is used to format + * dv. + * Here e is formatted as by {@link Integer#toString(int)}. + *
          + *
        • Subcase n = 1: + * dv is formatted as + * d1.0Ee. + * For example, 1 × 1023 is formatted as + * {@code 1.0E23}. + *
        • Subcase n > 1: + * dv is formatted as + * d1.d2dnEe. + * For example, 123 × 10-21 is formatted as + * {@code 1.23E-19}. + *
        + *
      * - * @param d the {@code double} to be converted. - * @return a string representation of the argument. + * @param v the {@code double} to be rendered. + * @return a string rendering of the argument. */ - public static String toString(double d) { - return FloatingDecimal.toJavaFormatString(d); + public static String toString(double v) { + return DoubleToDecimal.toString(v); } /** diff --git a/src/java.base/share/classes/java/lang/Float.java b/src/java.base/share/classes/java/lang/Float.java --- a/src/java.base/share/classes/java/lang/Float.java +++ b/src/java.base/share/classes/java/lang/Float.java @@ -31,6 +31,7 @@ import java.util.Optional; import jdk.internal.math.FloatingDecimal; +import jdk.internal.math.FloatToDecimal; import jdk.internal.HotSpotIntrinsicCandidate; /** @@ -142,73 +143,120 @@ public static final Class TYPE = (Class) Class.getPrimitiveClass("float"); /** - * Returns a string representation of the {@code float} - * argument. All characters mentioned below are ASCII characters. - *
        - *
      • If the argument is NaN, the result is the string - * "{@code NaN}". - *
      • Otherwise, the result is a string that represents the sign and - * magnitude (absolute value) of the argument. If the sign is - * negative, the first character of the result is - * '{@code -}' ({@code '\u005Cu002D'}); if the sign is - * positive, no sign character appears in the result. As for - * the magnitude m: + * Returns a string rendering of the {@code float} argument. + * + *

        The characters of the result are all drawn from the ASCII set. *

          - *
        • If m is infinity, it is represented by the characters - * {@code "Infinity"}; thus, positive infinity produces - * the result {@code "Infinity"} and negative infinity - * produces the result {@code "-Infinity"}. - *
        • If m is zero, it is represented by the characters - * {@code "0.0"}; thus, negative zero produces the result - * {@code "-0.0"} and positive zero produces the result - * {@code "0.0"}. - *
        • If m is greater than or equal to 10-3 but - * less than 107, then it is represented as the - * integer part of m, in decimal form with no leading - * zeroes, followed by '{@code .}' - * ({@code '\u005Cu002E'}), followed by one or more - * decimal digits representing the fractional part of - * m. - *
        • If m is less than 10-3 or greater than or - * equal to 107, then it is represented in - * so-called "computerized scientific notation." Let n - * be the unique integer such that 10n ≤ - * m {@literal <} 10n+1; then let a - * be the mathematically exact quotient of m and - * 10n so that 1 ≤ a {@literal <} 10. - * The magnitude is then represented as the integer part of - * a, as a single decimal digit, followed by - * '{@code .}' ({@code '\u005Cu002E'}), followed by - * decimal digits representing the fractional part of - * a, followed by the letter '{@code E}' - * ({@code '\u005Cu0045'}), followed by a representation - * of n as a decimal integer, as produced by the - * method {@link java.lang.Integer#toString(int)}. - * + *
        • Any NaN, whether quiet or signaling, is rendered as + * {@code "NaN"}, regardless of the sign bit. + *
        • The infinities +∞ and -∞ are rendered as + * {@code "Infinity"} and {@code "-Infinity"}, respectively. + *
        • The positive and negative zeroes are rendered as + * {@code "0.0"} and {@code "-0.0"}, respectively. + *
        • A finite negative {@code v} is rendered as the sign + * '{@code -}' followed by the rendering of the magnitude -{@code v}. + *
        • A finite positive {@code v} is rendered in two stages: + *
            + *
          • Selection of a decimal: A well-defined + * decimal dv is selected + * to represent {@code v}. + *
          • Formatting as a string: The decimal + * dv is formatted as a string, + * either in plain or in computerized scientific notation, + * depending on its value. *
          *
        - * How many digits must be printed for the fractional part of - * m or a? There must be at least one digit - * to represent the fractional part, and beyond that as many, but - * only as many, more digits as are needed to uniquely distinguish - * the argument value from adjacent values of type - * {@code float}. That is, suppose that x is the - * exact mathematical value represented by the decimal - * representation produced by this method for a finite nonzero - * argument f. Then f must be the {@code float} - * value nearest to x; or, if two {@code float} values are - * equally close to x, then f must be one of - * them and the least significant bit of the significand of - * f must be {@code 0}. + * + *

        A decimal is a number of the form + * d×10i + * for some (unique) integers d > 0 and i such that + * d is not a multiple of 10. + * These integers are the significand and + * the exponent, respectively, of the decimal. + * The length of the decimal is the (unique) + * integer n meeting + * 10n-1d < 10n. + * + *

        The decimal dv + * for a finite positive {@code v} is defined as follows: + *

          + *
        • Let R be the set of all decimals that round to {@code v} + * according to the usual round-to-closest rule of + * IEEE 754 floating-point arithmetic. + *
        • Let m be the minimal length over all decimals in R. + *
        • When m ≥ 2, let T be the set of all decimals + * in R with length m. + * Otherwise, let T be the set of all decimals + * in R with length 1 or 2. + *
        • Define dv as + * the decimal in T that is closest to {@code v}. + * Or if there are two such decimals in T, + * select the one with the even significand (there is exactly one). + *
        + * + *

        The (uniquely) selected decimal dv + * is then formatted. * - *

        To create localized string representations of a floating-point - * value, use subclasses of {@link java.text.NumberFormat}. + *

        Let d, i and n be the significand, exponent and + * length of dv, respectively. + * Further, let e = n + i - 1 and let + * d1dn + * be the usual decimal expansion of the significand. + * Note that d1 ≠ 0 ≠ dn. + *

          + *
        • Case -3 ≤ e < 0: + * dv is formatted as + * 0.00d1dn, + * where there are exactly -(n + i) zeroes between + * the decimal point and d1. + * For example, 123 × 10-4 is formatted as + * {@code 0.0123}. + *
        • Case 0 ≤ e < 7: + *
            + *
          • Subcase i ≥ 0: + * dv is formatted as + * d1dn00.0, + * where there are exactly i zeroes + * between dn and the decimal point. + * For example, 123 × 102 is formatted as + * {@code 12300.0}. + *
          • Subcase i < 0: + * dv is formatted as + * d1dn+i.dn+i+1dn. + * There are exactly -i digits to the right of + * the decimal point. + * For example, 123 × 10-1 is formatted as + * {@code 12.3}. + *
          + *
        • Case e < -3 or e ≥ 7: + * computerized scientific notation is used to format + * dv. + * Here e is formatted as by {@link Integer#toString(int)}. + *
            + *
          • Subcase n = 1: + * dv is formatted as + * d1.0Ee. + * For example, 1 × 1023 is formatted as + * {@code 1.0E23}. + *
          • Subcase n > 1: + * dv is formatted as + * d1.d2dnEe. + * For example, 123 × 10-21 is formatted as + * {@code 1.23E-19}. + *
          + *
        * - * @param f the float to be converted. - * @return a string representation of the argument. + * @param v the {@code float} to be rendered. + * @return a string rendering of the argument. */ - public static String toString(float f) { - return FloatingDecimal.toJavaFormatString(f); + public static String toString(float v) { + return FloatToDecimal.toString(v); } /** diff --git a/src/java.base/share/classes/jdk/internal/math/DoubleToDecimal.java b/src/java.base/share/classes/jdk/internal/math/DoubleToDecimal.java new file mode 100644 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/math/DoubleToDecimal.java @@ -0,0 +1,573 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +import static java.lang.Double.*; +import static java.lang.Long.*; +import static java.lang.Math.multiplyHigh; +import static jdk.internal.math.MathUtils.*; + +/** + * This class exposes a method to render a {@code double} as a string. + * + * @author Raffaello Giulietti + */ +final public class DoubleToDecimal { + /* + For full details about this code see the following references: + + [1] Giulietti, "The Schubfach way to render doubles", + https://drive.google.com/open?id=1KLtG_LaIbK9ETXI290zqCxvBW94dj058 + + [2] IEEE Computer Society, "IEEE Standard for Floating-Point Arithmetic" + + [3] Bouvier & Zimmermann, "Division-Free Binary-to-Decimal Conversion" + + Divisions are avoided for the benefit of those architectures that do not + provide specific machine instructions or where they are slow. + This is discussed in section 10 of [1]. + */ + + // The precision in bits. + static final int P = 53; + + // H is as in section 8 of [1]. + static final int H = 17; + + // 10^(MIN_EXP - 1) <= MIN_VALUE < 10^MIN_EXP + static final int MIN_EXP = -323; + + // 10^(MAX_EXP - 1) <= MAX_VALUE < 10^MAX_EXP + static final int MAX_EXP = 309; + + // Exponent width in bits. + private static final int W = (Double.SIZE - 1) - (P - 1); + + // Minimum value of the exponent: -(2^(W-1)) - P + 3. + private static final int Q_MIN = (-1 << W - 1) - P + 3; + + // Minimum value of the significand of a normal value: 2^(P-1). + private static final long C_MIN = 1L << P - 1; + + // Mask to extract the biased exponent. + private static final int BQ_MASK = (1 << W) - 1; + + // Mask to extract the fraction bits. + private static final long T_MASK = (1L << P - 1) - 1; + + // Used in rop(). + private static final long MASK_63 = (1L << 63) - 1; + + // Used for left-to-tight digit extraction. + private static final int MASK_28 = (1 << 28) - 1; + + // For thread-safety, each thread gets its own instance of this class. + private static final ThreadLocal threadLocal = + ThreadLocal.withInitial(DoubleToDecimal::new); + + /* + Room for the longer of the forms + -ddddd.dddddddddddd H + 2 characters + -0.00ddddddddddddddddd H + 5 characters + -d.ddddddddddddddddE-eee H + 7 characters + where there are H digits d + */ + private final byte[] buf = new byte[H + 7]; + + // Index into buf of rightmost valid character. + private int index; + + private DoubleToDecimal() { + } + + /** + * Returns a string rendering of the {@code double} argument. + * + *

        The characters of the result are all drawn from the ASCII set. + *

          + *
        • Any NaN, whether quiet or signaling, is rendered as + * {@code "NaN"}, regardless of the sign bit. + *
        • The infinities +∞ and -∞ are rendered as + * {@code "Infinity"} and {@code "-Infinity"}, respectively. + *
        • The positive and negative zeroes are rendered as + * {@code "0.0"} and {@code "-0.0"}, respectively. + *
        • A finite negative {@code v} is rendered as the sign + * '{@code -}' followed by the rendering of the magnitude -{@code v}. + *
        • A finite positive {@code v} is rendered in two stages: + *
            + *
          • Selection of a decimal: A well-defined + * decimal dv is selected + * to represent {@code v}. + *
          • Formatting as a string: The decimal + * dv is formatted as a string, + * either in plain or in computerized scientific notation, + * depending on its value. + *
          + *
        + * + *

        A decimal is a number of the form + * d×10i + * for some (unique) integers d > 0 and i such that + * d is not a multiple of 10. + * These integers are the significand and + * the exponent, respectively, of the decimal. + * The length of the decimal is the (unique) + * integer n meeting + * 10n-1d < 10n. + * + *

        The decimal dv + * for a finite positive {@code v} is defined as follows: + *

          + *
        • Let R be the set of all decimals that round to {@code v} + * according to the usual round-to-closest rule of + * IEEE 754 floating-point arithmetic. + *
        • Let m be the minimal length over all decimals in R. + *
        • When m ≥ 2, let T be the set of all decimals + * in R with length m. + * Otherwise, let T be the set of all decimals + * in R with length 1 or 2. + *
        • Define dv as + * the decimal in T that is closest to {@code v}. + * Or if there are two such decimals in T, + * select the one with the even significand (there is exactly one). + *
        + * + *

        The (uniquely) selected decimal dv + * is then formatted. + * + *

        Let d, i and n be the significand, exponent and + * length of dv, respectively. + * Further, let e = n + i - 1 and let + * d1dn + * be the usual decimal expansion of the significand. + * Note that d1 ≠ 0 ≠ dn. + *

          + *
        • Case -3 ≤ e < 0: + * dv is formatted as + * 0.00d1dn, + * where there are exactly -(n + i) zeroes between + * the decimal point and d1. + * For example, 123 × 10-4 is formatted as + * {@code 0.0123}. + *
        • Case 0 ≤ e < 7: + *
            + *
          • Subcase i ≥ 0: + * dv is formatted as + * d1dn00.0, + * where there are exactly i zeroes + * between dn and the decimal point. + * For example, 123 × 102 is formatted as + * {@code 12300.0}. + *
          • Subcase i < 0: + * dv is formatted as + * d1dn+i.dn+i+1dn. + * There are exactly -i digits to the right of + * the decimal point. + * For example, 123 × 10-1 is formatted as + * {@code 12.3}. + *
          + *
        • Case e < -3 or e ≥ 7: + * computerized scientific notation is used to format + * dv. + * Here e is formatted as by {@link Integer#toString(int)}. + *
            + *
          • Subcase n = 1: + * dv is formatted as + * d1.0Ee. + * For example, 1 × 1023 is formatted as + * {@code 1.0E23}. + *
          • Subcase n > 1: + * dv is formatted as + * d1.d2dnEe. + * For example, 123 × 10-21 is formatted as + * {@code 1.23E-19}. + *
          + *
        + * + * @param v the {@code double} to be rendered. + * @return a string rendering of the argument. + */ + public static String toString(double v) { + return threadLocalInstance().toDecimal(v); + } + + private static DoubleToDecimal threadLocalInstance() { + return threadLocal.get(); + } + + private String toDecimal(double v) { + /* + For full details see references [2] and [1]. + + Let + Q_MAX = 2^(W-1) - P + For finite v != 0, determine integers c and q such that + |v| = c 2^q and + Q_MIN <= q <= Q_MAX and + either 2^(P-1) <= c < 2^P (normal) + or 0 < c < 2^(P-1) and q = Q_MIN (subnormal) + */ + long bits = doubleToRawLongBits(v); + long t = bits & T_MASK; + int bq = (int) (bits >>> P - 1) & BQ_MASK; + if (bq < BQ_MASK) { + index = -1; + if (bits < 0) { + append('-'); + } + if (bq != 0) { + // normal value. Here mq = -q + int mq = -Q_MIN + 1 - bq; + long c = C_MIN | t; + // The fast path discussed in section 8.3 of [1]. + if (0 < mq & mq < P) { + long f = c >> mq; + if (f << mq == c) { + return toChars(f, 0); + } + } + return toDecimal(-mq, c); + } + if (t != 0) { + // subnormal value + return toDecimal(Q_MIN, t); + } + return bits == 0 ? "0.0" : "-0.0"; + } + if (t != 0) { + return "NaN"; + } + return bits > 0 ? "Infinity" : "-Infinity"; + } + + private String toDecimal(int q, long c) { + /* + The skeleton corresponds to figure 4 of [1]. + The efficient computations are those summarized in figure 7. + + Here's a correspondence between Java names and names in [1], + expressed as approximate LaTeX source code and informally. + Other names are identical. + cb: \bar{c} "c-bar" + cbr: \bar{c}_r "c-bar-r" + cbl: \bar{c}_l "c-bar-l" + + vb: \bar{v} "v-bar" + vbr: \bar{v}_r "v-bar-r" + vbl: \bar{v}_l "v-bar-l" + + rop: r_o' "r-o-prime" + */ + int out = (int) c & 0x1; + long cb; + long cbr; + long cbl; + int k; + int h; + /* + flog10pow2(e) = floor(log_10(2^e)) + flog10threeQuartersPow2(e) = floor(log_10(3/4 2^e)) + flog2pow10(e) = floor(log_2(10^e)) + */ + if (c != C_MIN | q == Q_MIN) { + // regular spacing + cb = c << 1; + cbr = cb + 1; + k = flog10pow2(q); + h = q + flog2pow10(-k) + 3; + } else { + // irregular spacing + cb = c << 2; + cbr = cb + 2; + k = flog10threeQuartersPow2(q); + h = q + flog2pow10(-k) + 2; + } + cbl = cb - 1; + + // g1 and g0 are as in section 9.8.3, so g = g1 2^63 + g0 + long g1 = g1(-k); + long g0 = g0(-k); + + long vb = rop(g1, g0, cb << h); + long vbl = rop(g1, g0, cbl << h); + long vbr = rop(g1, g0, cbr << h); + + long s = vb >> 2; + if (s >= 100) { + /* + For n = 17, m = 1 the table in section 10 of [1] shows + s' = + floor(s / 10) = floor(s 115'292'150'460'684'698 / 2^60) = + floor(s 115'292'150'460'684'698 2^4 / 2^64) + + sp10 = 10 s', tp10 = 10 t' = sp10 + 10 + upin iff u' = sp10 10^k in Rv + wpin iff w' = tp10 10^k in Rv + See section 9.3. + */ + long sp10 = 10 * multiplyHigh(s, 115_292_150_460_684_698L << 4); + long tp10 = sp10 + 10; + boolean upin = vbl + out <= sp10 << 2; + boolean wpin = (tp10 << 2) + out <= vbr; + if (upin != wpin) { + return toChars(upin ? sp10 : tp10, k); + } + } else if (s < 10) { + switch ((int) s) { + case 4: + return toChars(49, -325); // 4.9 10^(-324) + case 9: + return toChars(99, -325); // 9.9 10^(-324) + } + } + + /* + 10 <= s < 100 or s >= 100 and u', w' not in Rv + uin iff u = s 10^k in Rv + win iff w = t 10^k in Rv + See section 9.3. + */ + long t = s + 1; + boolean uin = vbl + out <= s << 2; + boolean win = (t << 2) + out <= vbr; + if (uin != win) { + // Exactly one of u or w lies in Rv. + return toChars(uin ? s : t, k); + } + /* + Both u and w lie in Rv: determine the one closest to v. + See section 9.3. + */ + long cmp = vb - (s + t << 1); + return toChars(cmp < 0 || cmp == 0 && (s & 0x1) == 0 ? s : t, k); + } + + /* + Computes rop(cp g 2^(-127)), where g = g1 2^63 + g0 + See section 9.9 and figure 6 of [1]. + */ + private static long rop(long g1, long g0, long cp) { + long x1 = multiplyHigh(g0, cp); + long y0 = g1 * cp; + long y1 = multiplyHigh(g1, cp); + long z = (y0 >>> 1) + x1; + long vbp = y1 + (z >>> 63); + return vbp | (z & MASK_63) + MASK_63 >>> 63; + } + + /* + Formats the decimal f 10^e. + */ + private String toChars(long f, int e) { + /* + For details not discussed here see section 10 of [1]. + + Determine len such that + 10^(len-1) <= f < 10^len + */ + int len = flog10pow2(Long.SIZE - numberOfLeadingZeros(f)); + if (f >= pow10(len)) { + len += 1; + } + + /* + Let fp and ep be the original f and e, respectively. + Transform f and e to ensure + 10^(H-1) <= f < 10^H + fp 10^ep = f 10^(e-H) = 0.f 10^e + */ + f *= pow10(H - len); + e += len; + + /* + The toChars?() methods perform left-to-right digits extraction + using ints, provided that the arguments are limited to 8 digits. + Therefore, split the H = 17 digits of f into: + h = the most significant digit of f + m = the next 8 most significant digits of f + l = the last 8, least significant digits of f + + For n = 17, m = 8 the table in section 10 of [1] shows + floor(f / 10^8) = floor(193'428'131'138'340'668 f / 2^84) = + floor(floor(193'428'131'138'340'668 f / 2^64) / 2^20) + and for n = 9, m = 8 + floor(hm / 10^8) = floor(1'441'151'881 hm / 2^57) + */ + long hm = multiplyHigh(f, 193_428_131_138_340_668L) >>> 20; + int l = (int) (f - 100_000_000L * hm); + int h = (int) (hm * 1_441_151_881L >>> 57); + int m = (int) (hm - 100_000_000 * h); + + if (0 < e && e <= 7) { + return toChars1(h, m, l, e); + } + if (-3 < e && e <= 0) { + return toChars2(h, m, l, e); + } + return toChars3(h, m, l, e); + } + + private String toChars1(int h, int m, int l, int e) { + /* + 0 < e <= 7: plain format without leading zeroes. + Left-to-right digits extraction: + algorithm 1 in [3], with b = 10, k = 8, n = 28. + */ + appendDigit(h); + int y = y(m); + int t; + int i = 1; + for (; i < e; ++i) { + t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + append('.'); + for (; i <= 8; ++i) { + t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + lowDigits(l); + return charsToString(); + } + + private String toChars2(int h, int m, int l, int e) { + // -3 < e <= 0: plain format with leading zeroes. + appendDigit(0); + append('.'); + for (; e < 0; ++e) { + appendDigit(0); + } + appendDigit(h); + append8Digits(m); + lowDigits(l); + return charsToString(); + } + + private String toChars3(int h, int m, int l, int e) { + // -3 >= e | e > 7: computerized scientific notation + appendDigit(h); + append('.'); + append8Digits(m); + lowDigits(l); + exponent(e - 1); + return charsToString(); + } + + private void lowDigits(int l) { + if (l != 0) { + append8Digits(l); + } + removeTrailingZeroes(); + } + + private void append8Digits(int m) { + /* + Left-to-right digits extraction: + algorithm 1 in [3], with b = 10, k = 8, n = 28. + */ + int y = y(m); + for (int i = 0; i < 8; ++i) { + int t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + } + + private void removeTrailingZeroes() { + while (buf[index] == '0') { + --index; + } + // ... but do not remove the one directly to the right of '.' + if (buf[index] == '.') { + ++index; + } + } + + private int y(int a) { + /* + Algorithm 1 in [3] needs computation of + floor((a + 1) 2^n / b^k) - 1 + with a < 10^8, b = 10, k = 8, n = 28. + Noting that + (a + 1) 2^n <= 10^8 2^28 < 10^17 + For n = 17, m = 8 the table in section 10 of [1] leads to: + */ + return (int) (multiplyHigh( + (long) (a + 1) << 28, + 193_428_131_138_340_668L) >>> 20) - 1; + } + + private void exponent(int e) { + append('E'); + if (e < 0) { + append('-'); + e = -e; + } + if (e < 10) { + appendDigit(e); + return; + } + int d; + if (e >= 100) { + /* + For n = 3, m = 2 the table in section 10 of [1] shows + floor(e / 100) = floor(1'311 e / 2^17) + */ + d = e * 1_311 >>> 17; + appendDigit(d); + e -= 100 * d; + } + /* + For n = 2, m = 1 the table in section 10 of [1] shows + floor(e / 10) = floor(103 e / 2^10) + */ + d = e * 103 >>> 10; + appendDigit(d); + appendDigit(e - 10 * d); + } + + private void append(int c) { + buf[++index] = (byte) c; + } + + private void appendDigit(int d) { + buf[++index] = (byte) ('0' + d); + } + + /* + Using the deprecated constructor enhances performance. + */ + @SuppressWarnings("deprecation") + private String charsToString() { + return new String(buf, 0, 0, index + 1); + } + +} diff --git a/src/java.base/share/classes/jdk/internal/math/FloatToDecimal.java b/src/java.base/share/classes/jdk/internal/math/FloatToDecimal.java new file mode 100644 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/math/FloatToDecimal.java @@ -0,0 +1,549 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +import static java.lang.Float.*; +import static java.lang.Integer.*; +import static java.lang.Math.multiplyHigh; +import static jdk.internal.math.MathUtils.*; + +/** + * This class exposes a method to render a {@code float} as a string. + * + * @author Raffaello Giulietti + */ +final public class FloatToDecimal { + /* + For full details about this code see the following references: + + [1] Giulietti, "The Schubfach way to render doubles", + https://drive.google.com/open?id=1KLtG_LaIbK9ETXI290zqCxvBW94dj058 + + [2] IEEE Computer Society, "IEEE Standard for Floating-Point Arithmetic" + + [3] Bouvier & Zimmermann, "Division-Free Binary-to-Decimal Conversion" + + Divisions are avoided for the benefit of those architectures that do not + provide specific machine instructions or where they are slow. + This is discussed in section 10 of [1]. + */ + + // The precision in bits. + static final int P = 24; + + // H is as in section 8 of [1]. + static final int H = 9; + + // 10^(MIN_EXP - 1) <= MIN_VALUE < 10^MIN_EXP + static final int MIN_EXP = -44; + + // 10^(MAX_EXP - 1) <= MAX_VALUE < 10^MAX_EXP + static final int MAX_EXP = 39; + + // Exponent width in bits. + private static final int W = (Float.SIZE - 1) - (P - 1); + + // Minimum value of the exponent: -(2^(W-1)) - P + 3. + private static final int Q_MIN = (-1 << W - 1) - P + 3; + + // Minimum value of the significand of a normal value: 2^(P-1). + private static final int C_MIN = 1 << P - 1; + + // Mask to extract the biased exponent. + private static final int BQ_MASK = (1 << W) - 1; + + // Mask to extract the fraction bits. + private static final int T_MASK = (1 << P - 1) - 1; + + // Used in rop(). + private static final long MASK_32 = (1L << 32) - 1; + + // Used for left-to-tight digit extraction. + private static final int MASK_28 = (1 << 28) - 1; + + // For thread-safety, each thread gets its own instance of this class. + private static final ThreadLocal threadLocal = + ThreadLocal.withInitial(FloatToDecimal::new); + + /* + Room for the longer of the forms + -ddddd.dddd H + 2 characters + -0.00ddddddddd H + 5 characters + -d.ddddddddE-ee H + 6 characters + where there are H digits d + */ + private final byte[] buf = new byte[H + 6]; + + // Index into buf of rightmost valid character. + private int index; + + private FloatToDecimal() { + } + + /** + * Returns a string rendering of the {@code float} argument. + * + *

        The characters of the result are all drawn from the ASCII set. + *

          + *
        • Any NaN, whether quiet or signaling, is rendered as + * {@code "NaN"}, regardless of the sign bit. + *
        • The infinities +∞ and -∞ are rendered as + * {@code "Infinity"} and {@code "-Infinity"}, respectively. + *
        • The positive and negative zeroes are rendered as + * {@code "0.0"} and {@code "-0.0"}, respectively. + *
        • A finite negative {@code v} is rendered as the sign + * '{@code -}' followed by the rendering of the magnitude -{@code v}. + *
        • A finite positive {@code v} is rendered in two stages: + *
            + *
          • Selection of a decimal: A well-defined + * decimal dv is selected + * to represent {@code v}. + *
          • Formatting as a string: The decimal + * dv is formatted as a string, + * either in plain or in computerized scientific notation, + * depending on its value. + *
          + *
        + * + *

        A decimal is a number of the form + * d×10i + * for some (unique) integers d > 0 and i such that + * d is not a multiple of 10. + * These integers are the significand and + * the exponent, respectively, of the decimal. + * The length of the decimal is the (unique) + * integer n meeting + * 10n-1d < 10n. + * + *

        The decimal dv + * for a finite positive {@code v} is defined as follows: + *

          + *
        • Let R be the set of all decimals that round to {@code v} + * according to the usual round-to-closest rule of + * IEEE 754 floating-point arithmetic. + *
        • Let m be the minimal length over all decimals in R. + *
        • When m ≥ 2, let T be the set of all decimals + * in R with length m. + * Otherwise, let T be the set of all decimals + * in R with length 1 or 2. + *
        • Define dv as + * the decimal in T that is closest to {@code v}. + * Or if there are two such decimals in T, + * select the one with the even significand (there is exactly one). + *
        + * + *

        The (uniquely) selected decimal dv + * is then formatted. + * + *

        Let d, i and n be the significand, exponent and + * length of dv, respectively. + * Further, let e = n + i - 1 and let + * d1dn + * be the usual decimal expansion of the significand. + * Note that d1 ≠ 0 ≠ dn. + *

          + *
        • Case -3 ≤ e < 0: + * dv is formatted as + * 0.00d1dn, + * where there are exactly -(n + i) zeroes between + * the decimal point and d1. + * For example, 123 × 10-4 is formatted as + * {@code 0.0123}. + *
        • Case 0 ≤ e < 7: + *
            + *
          • Subcase i ≥ 0: + * dv is formatted as + * d1dn00.0, + * where there are exactly i zeroes + * between dn and the decimal point. + * For example, 123 × 102 is formatted as + * {@code 12300.0}. + *
          • Subcase i < 0: + * dv is formatted as + * d1dn+i.dn+i+1dn. + * There are exactly -i digits to the right of + * the decimal point. + * For example, 123 × 10-1 is formatted as + * {@code 12.3}. + *
          + *
        • Case e < -3 or e ≥ 7: + * computerized scientific notation is used to format + * dv. + * Here e is formatted as by {@link Integer#toString(int)}. + *
            + *
          • Subcase n = 1: + * dv is formatted as + * d1.0Ee. + * For example, 1 × 1023 is formatted as + * {@code 1.0E23}. + *
          • Subcase n > 1: + * dv is formatted as + * d1.d2dnEe. + * For example, 123 × 10-21 is formatted as + * {@code 1.23E-19}. + *
          + *
        + * + * @param v the {@code float} to be rendered. + * @return a string rendering of the argument. + */ + public static String toString(float v) { + return threadLocalInstance().toDecimal(v); + } + + private static FloatToDecimal threadLocalInstance() { + return threadLocal.get(); + } + + private String toDecimal(float v) { + /* + For full details see references [2] and [1]. + + Let + Q_MAX = 2^(W-1) - P + For finite v != 0, determine integers c and q such that + |v| = c 2^q and + Q_MIN <= q <= Q_MAX and + either 2^(P-1) <= c < 2^P (normal) + or 0 < c < 2^(P-1) and q = Q_MIN (subnormal) + */ + int bits = floatToRawIntBits(v); + int t = bits & T_MASK; + int bq = (bits >>> P - 1) & BQ_MASK; + if (bq < BQ_MASK) { + index = -1; + if (bits < 0) { + append('-'); + } + if (bq != 0) { + // normal value. Here mq = -q + int mq = -Q_MIN + 1 - bq; + int c = C_MIN | t; + // The fast path discussed in section 8.3 of [1]. + if (0 < mq & mq < P) { + int f = c >> mq; + if (f << mq == c) { + return toChars(f, 0); + } + } + return toDecimal(-mq, c); + } + if (t != 0) { + // subnormal value + return toDecimal(Q_MIN, t); + } + return bits == 0 ? "0.0" : "-0.0"; + } + if (t != 0) { + return "NaN"; + } + return bits > 0 ? "Infinity" : "-Infinity"; + } + + private String toDecimal(int q, int c) { + /* + The skeleton corresponds to figure 4 of [1]. + The efficient computations are those summarized in figure 7. + Also check the appendix. + + Here's a correspondence between Java names and names in [1], + expressed as approximate LaTeX source code and informally. + Other names are identical. + cb: \bar{c} "c-bar" + cbr: \bar{c}_r "c-bar-r" + cbl: \bar{c}_l "c-bar-l" + + vb: \bar{v} "v-bar" + vbr: \bar{v}_r "v-bar-r" + vbl: \bar{v}_l "v-bar-l" + + rop: r_o' "r-o-prime" + */ + int out = c & 0x1; + long cb; + long cbr; + long cbl; + int k; + int h; + /* + flog10pow2(e) = floor(log_10(2^e)) + flog10threeQuartersPow2(e) = floor(log_10(3/4 2^e)) + flog2pow10(e) = floor(log_2(10^e)) + */ + if (c != C_MIN | q == Q_MIN) { + // regular spacing + cb = c << 1; + cbr = cb + 1; + k = flog10pow2(q); + h = q + flog2pow10(-k) + 34; + } else { + // irregular spacing + cb = c << 2; + cbr = cb + 2; + k = flog10threeQuartersPow2(q); + h = q + flog2pow10(-k) + 33; + } + cbl = cb - 1; + + // g is as in the appendix + long g = g1(-k) + 1; + + int vb = rop(g, cb << h); + int vbl = rop(g, cbl << h); + int vbr = rop(g, cbr << h); + + int s = vb >> 2; + if (s >= 100) { + /* + For n = 9, m = 1 the table in section 10 of [1] shows + s' = + floor(s / 10) = floor(s 1'717'986'919 / 2^34) + + sp10 = 10 s', tp10 = 10 t' = sp10 + 10 + upin iff u' = sp10 10^k in Rv + wpin iff w' = tp10 10^k in Rv + See section 9.3. + */ + int sp10 = 10 * (int) (s * 1_717_986_919L >>> 34); + int tp10 = sp10 + 10; + boolean upin = vbl + out <= sp10 << 2; + boolean wpin = (tp10 << 2) + out <= vbr; + if (upin != wpin) { + return toChars(upin ? sp10 : tp10, k); + } + } else if (s < 10) { + switch (s) { + case 1: return toChars(14, -46); // 1.4 * 10^-45 + case 2: return toChars(28, -46); // 2.8 * 10^-45 + case 4: return toChars(42, -46); // 4.2 * 10^-45 + case 5: return toChars(56, -46); // 5.6 * 10^-45 + case 7: return toChars(70, -46); // 7.0 * 10^-45 + case 8: return toChars(84, -46); // 8.4 * 10^-45 + case 9: return toChars(98, -46); // 9.8 * 10^-45 + } + } + + /* + 10 <= s < 100 or s >= 100 and u', w' not in Rv + uin iff u = s 10^k in Rv + win iff w = t 10^k in Rv + See section 9.3. + */ + int t = s + 1; + boolean uin = vbl + out <= s << 2; + boolean win = (t << 2) + out <= vbr; + if (uin != win) { + // Exactly one of u or w lies in Rv. + return toChars(uin ? s : t, k); + } + /* + Both u and w lie in Rv: determine the one closest to v. + See section 9.3. + */ + int cmp = vb - (s + t << 1); + return toChars(cmp < 0 || cmp == 0 && (s & 0x1) == 0 ? s : t, k); + } + + /* + Computes rop(cp g 2^(-95)) + See appendix and figure 9 of [1]. + */ + private static int rop(long g, long cp) { + long x1 = multiplyHigh(g, cp); + long vbp = x1 >>> 31; + return (int) (vbp | (x1 & MASK_32) + MASK_32 >>> 32); + } + + /* + Formats the decimal f 10^e. + */ + private String toChars(int f, int e) { + /* + For details not discussed here see section 10 of [1]. + + Determine len such that + 10^(len-1) <= f < 10^len + */ + int len = flog10pow2(Integer.SIZE - numberOfLeadingZeros(f)); + if (f >= pow10(len)) { + len += 1; + } + + /* + Let fp and ep be the original f and e, respectively. + Transform f and e to ensure + 10^(H-1) <= f < 10^H + fp 10^ep = f 10^(e-H) = 0.f 10^e + */ + f *= pow10(H - len); + e += len; + + /* + The toChars?() methods perform left-to-right digits extraction + using ints, provided that the arguments are limited to 8 digits. + Therefore, split the H = 9 digits of f into: + h = the most significant digit of f + l = the last 8, least significant digits of f + + For n = 9, m = 8 the table in section 10 of [1] shows + floor(f / 10^8) = floor(1'441'151'881 f / 2^57) + */ + int h = (int) (f * 1_441_151_881L >>> 57); + int l = f - 100_000_000 * h; + + if (0 < e && e <= 7) { + return toChars1(h, l, e); + } + if (-3 < e && e <= 0) { + return toChars2(h, l, e); + } + return toChars3(h, l, e); + } + + private String toChars1(int h, int l, int e) { + /* + 0 < e <= 7: plain format without leading zeroes. + Left-to-right digits extraction: + algorithm 1 in [3], with b = 10, k = 8, n = 28. + */ + appendDigit(h); + int y = y(l); + int t; + int i = 1; + for (; i < e; ++i) { + t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + append('.'); + for (; i <= 8; ++i) { + t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + removeTrailingZeroes(); + return charsToString(); + } + + private String toChars2(int h, int l, int e) { + // -3 < e <= 0: plain format with leading zeroes. + appendDigit(0); + append('.'); + for (; e < 0; ++e) { + appendDigit(0); + } + appendDigit(h); + append8Digits(l); + removeTrailingZeroes(); + return charsToString(); + } + + private String toChars3(int h, int l, int e) { + // -3 >= e | e > 7: computerized scientific notation + appendDigit(h); + append('.'); + append8Digits(l); + removeTrailingZeroes(); + exponent(e - 1); + return charsToString(); + } + + private void append8Digits(int m) { + /* + Left-to-right digits extraction: + algorithm 1 in [3], with b = 10, k = 8, n = 28. + */ + int y = y(m); + for (int i = 0; i < 8; ++i) { + int t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + } + + private void removeTrailingZeroes() { + while (buf[index] == '0') { + --index; + } + // ... but do not remove the one directly to the right of '.' + if (buf[index] == '.') { + ++index; + } + } + + private int y(int a) { + /* + Algorithm 1 in [3] needs computation of + floor((a + 1) 2^n / b^k) - 1 + with a < 10^8, b = 10, k = 8, n = 28. + Noting that + (a + 1) 2^n <= 10^8 2^28 < 10^17 + For n = 17, m = 8 the table in section 10 of [1] leads to: + */ + return (int) (multiplyHigh( + (long) (a + 1) << 28, + 193_428_131_138_340_668L) >>> 20) - 1; + } + + private void exponent(int e) { + append('E'); + if (e < 0) { + append('-'); + e = -e; + } + if (e < 10) { + appendDigit(e); + return; + } + /* + For n = 2, m = 1 the table in section 10 of [1] shows + floor(e / 10) = floor(103 e / 2^10) + */ + int d = e * 103 >>> 10; + appendDigit(d); + appendDigit(e - 10 * d); + } + + private void append(int c) { + buf[++index] = (byte) c; + } + + private void appendDigit(int d) { + buf[++index] = (byte) ('0' + d); + } + + /* + Using the deprecated constructor enhances performance. + */ + @SuppressWarnings("deprecation") + private String charsToString() { + return new String(buf, 0, 0, index + 1); + } + +} diff --git a/src/java.base/share/classes/jdk/internal/math/MathUtils.java b/src/java.base/share/classes/jdk/internal/math/MathUtils.java new file mode 100644 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/math/MathUtils.java @@ -0,0 +1,799 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +/** + * This class exposes package private utilities for other classes. Thus, + * all methods are assumed to be invoked with correct arguments, so they are + * not checked at all. + * + * @author Raffaello Giulietti + */ +final class MathUtils { + /* + For full details about this code see the following reference: + + Giulietti, "The Schubfach way to render doubles", + https://drive.google.com/open?id=1KLtG_LaIbK9ETXI290zqCxvBW94dj058 + */ + + // The minimum and maximum k + static final int MIN_K = -324; + static final int MAX_K = 292; + + // C_10 = floor(log10(2) * 2^Q_10), A_10 = floor(log10(3/4) * 2^Q_10) + private static final int Q_10 = 41; + private static final long C_10 = 661_971_961_083L; + private static final long A_10 = -274_743_187_321L; + + // C_2 = floor(log2(10) * 2^Q_2) + private static final int Q_2 = 38; + private static final long C_2 = 913_124_641_741L; + + private MathUtils() { + } + + private static final long[] pow10 = { + 1L, + 10L, + 100L, + 1_000L, + 10_000L, + 100_000L, + 1_000_000L, + 10_000_000L, + 100_000_000L, + 1_000_000_000L, + 10_000_000_000L, + 100_000_000_000L, + 1_000_000_000_000L, + 10_000_000_000_000L, + 100_000_000_000_000L, + 1_000_000_000_000_000L, + 10_000_000_000_000_000L, + 100_000_000_000_000_000L, + }; + + /** + * Returns 10{@code e}. + * + * @param e The exponent which must meet + * 0 ≤ {@code e} ≤ {@link DoubleToDecimal#H}. + * @return 10{@code e}. + */ + static long pow10(int e) { + return pow10[e]; + } + + /** + * Returns the unique integer k such that + * 10k ≤ 2{@code e} + * < 10k+1. + *

        + * The result is correct when |{@code e}| ≤ 5_456_721. + * Otherwise the result is undefined. + * + * @param e The exponent of 2, which should meet + * |{@code e}| ≤ 5_456_721 for safe results. + * @return ⌊log102{@code e}⌋. + */ + static int flog10pow2(int e) { + return (int) (e * C_10 >> Q_10); + } + + /** + * Returns the unique integer k such that + * 10k ≤ 3/4 · 2{@code e} + * < 10k+1. + *

        + * The result is correct when + * -2_956_395 ≤ {@code e} ≤ 2_500_325. + * Otherwise the result is undefined. + * + * @param e The exponent of 2, which should meet + * -2_956_395 ≤ {@code e} ≤ 2_500_325 for safe results. + * @return ⌊log10(3/4 · + * 2{@code e})⌋. + */ + static int flog10threeQuartersPow2(int e) { + return (int) (e * C_10 + A_10 >> Q_10); + } + + /** + * Returns the unique integer k such that + * 2k ≤ 10{@code e} + * < 2k+1. + *

        + * The result is correct when |{@code e}| ≤ 1_838_394. + * Otherwise the result is undefined. + * + * @param e The exponent of 10, which should meet + * |{@code e}| ≤ 1_838_394 for safe results. + * @return ⌊log210{@code e}⌋. + */ + static int flog2pow10(int e) { + return (int) (e * C_2 >> Q_2); + } + + /** + * Let 10{@code e} = β 2r, + * for the unique pair of integer r and real β meeting + * 2125β < 2126. + * Further, let g = ⌊β⌋ + 1. + * Split g into the higher 63 bits g1 and + * the lower 63 bits g0. Thus, + * g1 = + * ⌊g 2-63⌋ + * and + * g0 = + * g - g1 263. + *

        + * This method returns g1 while + * {@link #g0(int)} returns g0. + *

        + * If needed, the exponent r can be computed as + * r = {@code flog2pow10(e)} - 125 (see {@link #flog2pow10(int)}). + * + * @param e The exponent of 10. + * @return g1 as described above. + */ + static long g1(int e) { + return g[e + MAX_K << 1]; + } + + /** + * Returns g0 as described in + * {@link #g1(int)}. + * + * @param e The exponent of 10. + * @return g0 as described in + * {@link #g1(int)}. + */ + static long g0(int e) { + return g[e + MAX_K << 1 | 1]; + } + + /** + * The precomputed values for {@link #g1(int)} and {@link #g0(int)}. + */ + private static final long[] g = { + /* -292 */ 0x7FBB_D8FE_5F5E_6E27L, 0x497A_3A27_04EE_C3DFL, + /* -291 */ 0x4FD5_679E_FB9B_04D8L, 0x5DEC_6458_6315_3A6CL, + /* -290 */ 0x63CA_C186_BA81_C60EL, 0x7567_7D6E_7BDA_8906L, + /* -289 */ 0x7CBD_71E8_6922_3792L, 0x52C1_5CCA_1AD1_2B48L, + /* -288 */ 0x4DF6_6731_41B5_62BBL, 0x53B8_D9FE_50C2_BB0DL, + /* -287 */ 0x6174_00FD_9222_BB6AL, 0x48A7_107D_E4F3_69D0L, + /* -286 */ 0x79D1_013C_F6AB_6A45L, 0x1AD0_D49D_5E30_4444L, + /* -285 */ 0x4C22_A0C6_1A2B_226BL, 0x20C2_84E2_5ADE_2AABL, + /* -284 */ 0x5F2B_48F7_A0B5_EB06L, 0x08F3_261A_F195_B555L, + /* -283 */ 0x76F6_1B35_88E3_65C7L, 0x4B2F_EFA1_ADFB_22ABL, + /* -282 */ 0x4A59_D101_758E_1F9CL, 0x5EFD_F5C5_0CBC_F5ABL, + /* -281 */ 0x5CF0_4541_D2F1_A783L, 0x76BD_7336_4FEC_3315L, + /* -280 */ 0x742C_5692_47AE_1164L, 0x746C_D003_E3E7_3FDBL, + /* -279 */ 0x489B_B61B_6CCC_CADFL, 0x08C4_0202_6E70_87E9L, + /* -278 */ 0x5AC2_A3A2_47FF_FD96L, 0x6AF5_0283_0A0C_A9E3L, + /* -277 */ 0x7173_4C8A_D9FF_FCFCL, 0x45B2_4323_CC8F_D45CL, + /* -276 */ 0x46E8_0FD6_C83F_FE1DL, 0x6B8F_69F6_5FD9_E4B9L, + /* -275 */ 0x58A2_13CC_7A4F_FDA5L, 0x2673_4473_F7D0_5DE8L, + /* -274 */ 0x6ECA_98BF_98E3_FD0EL, 0x5010_1590_F5C4_7561L, + /* -273 */ 0x453E_9F77_BF8E_7E29L, 0x120A_0D7A_999A_C95DL, + /* -272 */ 0x568E_4755_AF72_1DB3L, 0x368C_90D9_4001_7BB4L, + /* -271 */ 0x6C31_D92B_1B4E_A520L, 0x242F_B50F_9001_DAA1L, + /* -270 */ 0x439F_27BA_F111_2734L, 0x169D_D129_BA01_28A5L, + /* -269 */ 0x5486_F1A9_AD55_7101L, 0x1C45_4574_2881_72CEL, + /* -268 */ 0x69A8_AE14_18AA_CD41L, 0x4356_96D1_32A1_CF81L, + /* -267 */ 0x4209_6CCC_8F6A_C048L, 0x7A16_1E42_BFA5_21B1L, + /* -266 */ 0x528B_C7FF_B345_705BL, 0x189B_A5D3_6F8E_6A1DL, + /* -265 */ 0x672E_B9FF_A016_CC71L, 0x7EC2_8F48_4B72_04A4L, + /* -264 */ 0x407D_343F_C40E_3FC7L, 0x1F39_998D_2F27_42E7L, + /* -263 */ 0x509C_814F_B511_CFB9L, 0x0707_FFF0_7AF1_13A1L, + /* -262 */ 0x64C3_A1A3_A256_43A7L, 0x28C9_FFEC_99AD_5889L, + /* -261 */ 0x7DF4_8A0C_8AEB_D491L, 0x12FC_7FE7_C018_AEABL, + /* -260 */ 0x4EB8_D647_D6D3_64DAL, 0x5BDD_CFF0_D80F_6D2BL, + /* -259 */ 0x6267_0BD9_CC88_3E11L, 0x32D5_43ED_0E13_4875L, + /* -258 */ 0x7B00_CED0_3FAA_4D95L, 0x5F8A_94E8_5198_1A93L, + /* -257 */ 0x4CE0_8142_27CA_707DL, 0x4BB6_9D11_32FF_109CL, + /* -256 */ 0x6018_A192_B1BD_0C9CL, 0x7EA4_4455_7FBE_D4C3L, + /* -255 */ 0x781E_C9F7_5E2C_4FC4L, 0x1E4D_556A_DFAE_89F3L, + /* -254 */ 0x4B13_3E3A_9ADB_B1DAL, 0x52F0_5562_CBCD_1638L, + /* -253 */ 0x5DD8_0DC9_4192_9E51L, 0x27AC_6ABB_7EC0_5BC6L, + /* -252 */ 0x754E_113B_91F7_45E5L, 0x5197_856A_5E70_72B8L, + /* -251 */ 0x4950_CAC5_3B3A_8BAFL, 0x42FE_B362_7B06_47B3L, + /* -250 */ 0x5BA4_FD76_8A09_2E9BL, 0x33BE_603B_19C7_D99FL, + /* -249 */ 0x728E_3CD4_2C8B_7A42L, 0x20AD_F849_E039_D007L, + /* -248 */ 0x4798_E604_9BD7_2C69L, 0x346C_BB2E_2C24_2205L, + /* -247 */ 0x597F_1F85_C2CC_F783L, 0x6187_E9F9_B72D_2A86L, + /* -246 */ 0x6FDE_E767_3380_3564L, 0x59E9_E478_24F8_7527L, + /* -245 */ 0x45EB_50A0_8030_215EL, 0x7832_2ECB_171B_4939L, + /* -244 */ 0x5766_24C8_A03C_29B6L, 0x563E_BA7D_DCE2_1B87L, + /* -243 */ 0x6D3F_ADFA_C84B_3424L, 0x2BCE_691D_541A_A268L, + /* -242 */ 0x4447_CCBC_BD2F_0096L, 0x5B61_01B2_5490_A581L, + /* -241 */ 0x5559_BFEB_EC7A_C0BCL, 0x3239_421E_E9B4_CEE1L, + /* -240 */ 0x6AB0_2FE6_E799_70EBL, 0x3EC7_92A6_A422_029AL, + /* -239 */ 0x42AE_1DF0_50BF_E693L, 0x173C_BBA8_2695_41A0L, + /* -238 */ 0x5359_A56C_64EF_E037L, 0x7D0B_EA92_303A_9208L, + /* -237 */ 0x6830_0EC7_7E2B_D845L, 0x7C4E_E536_BC49_368AL, + /* -236 */ 0x411E_093C_AEDB_672BL, 0x5DB1_4F42_35AD_C217L, + /* -235 */ 0x5165_8B8B_DA92_40F6L, 0x551D_A312_C319_329CL, + /* -234 */ 0x65BE_EE6E_D136_D134L, 0x2A65_0BD7_73DF_7F43L, + /* -233 */ 0x7F2E_AA0A_8584_8581L, 0x34FE_4ECD_50D7_5F14L, + /* -232 */ 0x4F7D_2A46_9372_D370L, 0x711E_F140_5286_9B6CL, + /* -231 */ 0x635C_74D8_384F_884DL, 0x0D66_AD90_6728_4247L, + /* -230 */ 0x7C33_920E_4663_6A60L, 0x30C0_58F4_80F2_52D9L, + /* -229 */ 0x4DA0_3B48_EBFE_227CL, 0x1E78_3798_D097_73C8L, + /* -228 */ 0x6108_4A1B_26FD_AB1BL, 0x2616_457F_04BD_50BAL, + /* -227 */ 0x794A_5CA1_F0BD_15E2L, 0x0F9B_D6DE_C5EC_A4E8L, + /* -226 */ 0x4BCE_79E5_3676_2DADL, 0x29C1_664B_3BB3_E711L, + /* -225 */ 0x5EC2_185E_8413_B918L, 0x5431_BFDE_0AA0_E0D5L, + /* -224 */ 0x7672_9E76_2518_A75EL, 0x693E_2FD5_8D49_190BL, + /* -223 */ 0x4A07_A309_D72F_689BL, 0x21C6_DDE5_784D_AFA7L, + /* -222 */ 0x5C89_8BCC_4CFB_42C2L, 0x0A38_955E_D661_1B90L, + /* -221 */ 0x73AB_EEBF_603A_1372L, 0x4CC6_BAB6_8BF9_6274L, + /* -220 */ 0x484B_7537_9C24_4C27L, 0x4FFC_34B2_177B_DD89L, + /* -219 */ 0x5A5E_5285_832D_5F31L, 0x43FB_41DE_9D5A_D4EBL, + /* -218 */ 0x70F5_E726_E3F8_B6FDL, 0x74FA_1256_44B1_8A26L, + /* -217 */ 0x4699_B078_4E7B_725EL, 0x591C_4B75_EAEE_F658L, + /* -216 */ 0x5840_1C96_621A_4EF6L, 0x2F63_5E53_65AA_B3EDL, + /* -215 */ 0x6E50_23BB_FAA0_E2B3L, 0x7B3C_35E8_3F15_60E9L, + /* -214 */ 0x44F2_1655_7CA4_8DB0L, 0x3D05_A1B1_276D_5C92L, + /* -213 */ 0x562E_9BEA_DBCD_B11CL, 0x4C47_0A1D_7148_B3B6L, + /* -212 */ 0x6BBA_42E5_92C1_1D63L, 0x5F58_CCA4_CD9A_E0A3L, + /* -211 */ 0x4354_69CF_7BB8_B25EL, 0x2B97_7FE7_0080_CC66L, + /* -210 */ 0x5429_8443_5AA6_DEF5L, 0x767D_5FE0_C0A0_FF80L, + /* -209 */ 0x6933_E554_3150_96B3L, 0x341C_B7D8_F0C9_3F5FL, + /* -208 */ 0x41C0_6F54_9ED2_5E30L, 0x1091_F2E7_967D_C79CL, + /* -207 */ 0x5230_8B29_C686_F5BCL, 0x14B6_6FA1_7C1D_3983L, + /* -206 */ 0x66BC_ADF4_3828_B32BL, 0x19E4_0B89_DB24_87E3L, + /* -205 */ 0x4035_ECB8_A319_6FFBL, 0x002E_8736_28F6_D4EEL, + /* -204 */ 0x5043_67E6_CBDF_CBF9L, 0x603A_2903_B334_8A2AL, + /* -203 */ 0x6454_41E0_7ED7_BEF8L, 0x1848_B344_A001_ACB4L, + /* -202 */ 0x7D69_5258_9E8D_AEB6L, 0x1E5A_E015_C802_17E1L, + /* -201 */ 0x4E61_D377_6318_8D31L, 0x72F8_CC0D_9D01_4EEDL, + /* -200 */ 0x61FA_4855_3BDE_B07EL, 0x2FB6_FF11_0441_A2A8L, + /* -199 */ 0x7A78_DA6A_8AD6_5C9DL, 0x7BA4_BED5_4552_0B52L, + /* -198 */ 0x4C8B_8882_96C5_F9E2L, 0x5D46_F745_4B53_4713L, + /* -197 */ 0x5FAE_6AA3_3C77_785BL, 0x3498_B516_9E28_18D8L, + /* -196 */ 0x779A_054C_0B95_5672L, 0x21BE_E25C_45B2_1F0EL, + /* -195 */ 0x4AC0_434F_873D_5607L, 0x3517_4D79_AB8F_5369L, + /* -194 */ 0x5D70_5423_690C_AB89L, 0x225D_20D8_1673_2843L, + /* -193 */ 0x74CC_692C_434F_D66BL, 0x4AF4_690E_1C0F_F253L, + /* -192 */ 0x48FF_C1BB_AA11_E603L, 0x1ED8_C1A8_D189_F774L, + /* -191 */ 0x5B3F_B22A_9496_5F84L, 0x068E_F213_05EC_7551L, + /* -190 */ 0x720F_9EB5_39BB_F765L, 0x0832_AE97_C767_92A5L, + /* -189 */ 0x4749_C331_4415_7A9FL, 0x151F_AD1E_DCA0_BBA8L, + /* -188 */ 0x591C_33FD_951A_D946L, 0x7A67_9866_93C8_EA91L, + /* -187 */ 0x6F63_40FC_FA61_8F98L, 0x5901_7E80_38BB_2536L, + /* -186 */ 0x459E_089E_1C7C_F9BFL, 0x37A0_EF10_2374_F742L, + /* -185 */ 0x5705_8AC5_A39C_382FL, 0x2589_2AD4_2C52_3512L, + /* -184 */ 0x6CC6_ED77_0C83_463BL, 0x0EEB_7589_3766_C256L, + /* -183 */ 0x43FC_546A_67D2_0BE4L, 0x7953_2975_C2A0_3976L, + /* -182 */ 0x54FB_6985_01C6_8EDEL, 0x17A7_F3D3_3348_47D4L, + /* -181 */ 0x6A3A_43E6_4238_3295L, 0x5D91_F0C8_001A_59C8L, + /* -180 */ 0x4264_6A6F_E963_1F9DL, 0x4A7B_367D_0010_781DL, + /* -179 */ 0x52FD_850B_E3BB_E784L, 0x7D1A_041C_4014_9625L, + /* -178 */ 0x67BC_E64E_DCAA_E166L, 0x1C60_8523_5019_BBAEL, + /* -177 */ 0x40D6_0FF1_49EA_CCDFL, 0x71BC_5336_1210_154DL, + /* -176 */ 0x510B_93ED_9C65_8017L, 0x6E2B_6803_9694_1AA0L, + /* -175 */ 0x654E_78E9_037E_E01DL, 0x69B6_4204_7C39_2148L, + /* -174 */ 0x7EA2_1723_445E_9825L, 0x2423_D285_9B47_6999L, + /* -173 */ 0x4F25_4E76_0ABB_1F17L, 0x2696_6393_810C_A200L, + /* -172 */ 0x62EE_A213_8D69_E6DDL, 0x103B_FC78_614F_CA80L, + /* -171 */ 0x7BAA_4A98_70C4_6094L, 0x344A_FB96_79A3_BD20L, + /* -170 */ 0x4D4A_6E9F_467A_BC5CL, 0x60AE_DD3E_0C06_5634L, + /* -169 */ 0x609D_0A47_1819_6B73L, 0x78DA_948D_8F07_EBC1L, + /* -168 */ 0x78C4_4CD8_DE1F_C650L, 0x7711_39B0_F2C9_E6B1L, + /* -167 */ 0x4B7A_B007_8AD3_DBF2L, 0x4A6A_C40E_97BE_302FL, + /* -166 */ 0x5E59_5C09_6D88_D2EFL, 0x1D05_7512_3DAD_BC3AL, + /* -165 */ 0x75EF_B30B_C8EB_07ABL, 0x0446_D256_CD19_2B49L, + /* -164 */ 0x49B5_CFE7_5D92_E4CAL, 0x72AC_4376_402F_BB0EL, + /* -163 */ 0x5C23_43E1_34F7_9DFDL, 0x4F57_5453_D03B_A9D1L, + /* -162 */ 0x732C_14D9_8235_857DL, 0x032D_2968_C44A_9445L, + /* -161 */ 0x47FB_8D07_F161_736EL, 0x11FC_39E1_7AAE_9CABL, + /* -160 */ 0x59FA_7049_EDB9_D049L, 0x567B_4859_D95A_43D6L, + /* -159 */ 0x7079_0C5C_6928_445CL, 0x0C1A_1A70_4FB0_D4CCL, + /* -158 */ 0x464B_A7B9_C1B9_2AB9L, 0x4790_5086_31CE_84FFL, + /* -157 */ 0x57DE_91A8_3227_7567L, 0x7974_64A7_BE42_263FL, + /* -156 */ 0x6DD6_3612_3EB1_52C1L, 0x77D1_7DD1_ADD2_AFCFL, + /* -155 */ 0x44A5_E1CB_672E_D3B9L, 0x1AE2_EEA3_0CA3_ADE1L, + /* -154 */ 0x55CF_5A3E_40FA_88A7L, 0x419B_AA4B_CFCC_995AL, + /* -153 */ 0x6B43_30CD_D139_2AD1L, 0x3202_94DE_C3BF_BFB0L, + /* -152 */ 0x4309_FE80_A2C3_BAC2L, 0x6F41_9D0B_3A57_D7CEL, + /* -151 */ 0x53CC_7E20_CB74_A973L, 0x4B12_044E_08ED_CDC2L, + /* -150 */ 0x68BF_9DA8_FE51_D3D0L, 0x3DD6_8561_8B29_4132L, + /* -149 */ 0x4177_C289_9EF3_2462L, 0x26A6_135C_F6F9_C8BFL, + /* -148 */ 0x51D5_B32C_06AF_ED7AL, 0x704F_9834_34B8_3AEFL, + /* -147 */ 0x664B_1FF7_085B_E8D9L, 0x4C63_7E41_41E6_49ABL, + /* -146 */ 0x7FDD_E7F4_CA72_E30FL, 0x7F7C_5DD1_925F_DC15L, + /* -145 */ 0x4FEA_B0F8_FE87_CDE9L, 0x7FAD_BAA2_FB7B_E98DL, + /* -144 */ 0x63E5_5D37_3E29_C164L, 0x3F99_294B_BA5A_E3F1L, + /* -143 */ 0x7CDE_B485_0DB4_31BDL, 0x4F7F_739E_A8F1_9CEDL, + /* -142 */ 0x4E0B_30D3_2890_9F16L, 0x41AF_A843_2997_0214L, + /* -141 */ 0x618D_FD07_F2B4_C6DCL, 0x121B_9253_F3FC_C299L, + /* -140 */ 0x79F1_7C49_EF61_F893L, 0x16A2_76E8_F0FB_F33FL, + /* -139 */ 0x4C36_EDAE_359D_3B5BL, 0x7E25_8A51_969D_7808L, + /* -138 */ 0x5F44_A919_C304_8A32L, 0x7DAE_ECE5_FC44_D609L, + /* -137 */ 0x7715_D360_33C5_ACBFL, 0x5D1A_A81F_7B56_0B8CL, + /* -136 */ 0x4A6D_A41C_205B_8BF7L, 0x6A30_A913_AD15_C738L, + /* -135 */ 0x5D09_0D23_2872_6EF5L, 0x64BC_D358_985B_3905L, + /* -134 */ 0x744B_506B_F28F_0AB3L, 0x1DEC_082E_BE72_0746L, + /* -133 */ 0x48AF_1243_7799_66B0L, 0x02B3_851D_3707_448CL, + /* -132 */ 0x5ADA_D6D4_557F_C05CL, 0x0360_6664_84C9_15AFL, + /* -131 */ 0x7191_8C89_6ADF_B073L, 0x0438_7FFD_A5FB_5B1BL, + /* -130 */ 0x46FA_F7D5_E2CB_CE47L, 0x72A3_4FFE_87BD_18F1L, + /* -129 */ 0x58B9_B5CB_5B7E_C1D9L, 0x6F4C_23FE_29AC_5F2DL, + /* -128 */ 0x6EE8_233E_325E_7250L, 0x2B1F_2CFD_B417_76F8L, + /* -127 */ 0x4551_1606_DF7B_0772L, 0x1AF3_7C1E_908E_AA5BL, + /* -126 */ 0x56A5_5B88_9759_C94EL, 0x61B0_5B26_34B2_54F2L, + /* -125 */ 0x6C4E_B26A_BD30_3BA2L, 0x3A1C_71EF_C1DE_EA2EL, + /* -124 */ 0x43B1_2F82_B63E_2545L, 0x4451_C735_D92B_525DL, + /* -123 */ 0x549D_7B63_63CD_AE96L, 0x7566_3903_4F76_26F4L, + /* -122 */ 0x69C4_DA3C_3CC1_1A3CL, 0x52BF_C744_2353_B0B1L, + /* -121 */ 0x421B_0865_A5F8_B065L, 0x73B7_DC8A_9614_4E6FL, + /* -120 */ 0x52A1_CA7F_0F76_DC7FL, 0x30A5_D3AD_3B99_620BL, + /* -119 */ 0x674A_3D1E_D354_939FL, 0x1CCF_4898_8A7F_BA8DL, + /* -118 */ 0x408E_6633_4414_DC43L, 0x4201_8D5F_568F_D498L, + /* -117 */ 0x50B1_FFC0_151A_1354L, 0x3281_F0B7_2C33_C9BEL, + /* -116 */ 0x64DE_7FB0_1A60_9829L, 0x3F22_6CE4_F740_BC2EL, + /* -115 */ 0x7E16_1F9C_20F8_BE33L, 0x6EEB_081E_3510_EB39L, + /* -114 */ 0x4ECD_D3C1_949B_76E0L, 0x3552_E512_E12A_9304L, + /* -113 */ 0x6281_48B1_F9C2_5498L, 0x42A7_9E57_9975_37C5L, + /* -112 */ 0x7B21_9ADE_7832_E9BEL, 0x5351_85ED_7FD2_85B6L, + /* -111 */ 0x4CF5_00CB_0B1F_D217L, 0x1412_F3B4_6FE3_9392L, + /* -110 */ 0x6032_40FD_CDE7_C69CL, 0x7917_B0A1_8BDC_7876L, + /* -109 */ 0x783E_D13D_4161_B844L, 0x175D_9CC9_EED3_9694L, + /* -108 */ 0x4B27_42C6_48DD_132AL, 0x4E9A_81FE_3544_3E1CL, + /* -107 */ 0x5DF1_1377_DB14_57F5L, 0x2241_227D_C295_4DA3L, + /* -106 */ 0x756D_5855_D1D9_6DF2L, 0x4AD1_6B1D_333A_A10CL, + /* -105 */ 0x4964_5735_A327_E4B7L, 0x4EC2_E2F2_4004_A4A8L, + /* -104 */ 0x5BBD_6D03_0BF1_DDE5L, 0x4273_9BAE_D005_CDD2L, + /* -103 */ 0x72AC_C843_CEEE_555EL, 0x7310_829A_8407_4146L, + /* -102 */ 0x47AB_FD2A_6154_F55BL, 0x27EA_51A0_9284_88CCL, + /* -101 */ 0x5996_FC74_F9AA_32B2L, 0x11E4_E608_B725_AAFFL, + /* -100 */ 0x6FFC_BB92_3814_BF5EL, 0x565E_1F8A_E4EF_15BEL, + /* -99 */ 0x45FD_F53B_630C_F79BL, 0x15FA_D3B6_CF15_6D97L, + /* -98 */ 0x577D_728A_3BD0_3581L, 0x7B79_88A4_82DA_C8FDL, + /* -97 */ 0x6D5C_CF2C_CAC4_42E2L, 0x3A57_EACD_A391_7B3CL, + /* -96 */ 0x445A_017B_FEBA_A9CDL, 0x4476_F2C0_863A_ED06L, + /* -95 */ 0x5570_81DA_FE69_5440L, 0x7594_AF70_A7C9_A847L, + /* -94 */ 0x6ACC_A251_BE03_A951L, 0x12F9_DB4C_D1BC_1258L, + /* -93 */ 0x42BF_E573_16C2_49D2L, 0x5BDC_2910_0315_8B77L, + /* -92 */ 0x536F_DECF_DC72_DC47L, 0x32D3_3354_03DA_EE55L, + /* -91 */ 0x684B_D683_D38F_9359L, 0x1F88_0029_04D1_A9EAL, + /* -90 */ 0x412F_6612_6439_BC17L, 0x63B5_0019_A303_0A33L, + /* -89 */ 0x517B_3F96_FD48_2B1DL, 0x5CA2_4020_0BC3_CCBFL, + /* -88 */ 0x65DA_0F7C_BC9A_35E5L, 0x13CA_D028_0EB4_BFEFL, + /* -87 */ 0x7F50_935B_EBC0_C35EL, 0x38BD_8432_1261_EFEBL, + /* -86 */ 0x4F92_5C19_7358_7A1BL, 0x0376_729F_4B7D_35F3L, + /* -85 */ 0x6376_F31F_D02E_98A1L, 0x6454_0F47_1E5C_836FL, + /* -84 */ 0x7C54_AFE7_C43A_3ECAL, 0x1D69_1318_E5F3_A44BL, + /* -83 */ 0x4DB4_EDF0_DAA4_673EL, 0x3261_ABEF_8FB8_46AFL, + /* -82 */ 0x6122_296D_114D_810DL, 0x7EFA_16EB_73A6_585BL, + /* -81 */ 0x796A_B3C8_55A0_E151L, 0x3EB8_9CA6_508F_EE71L, + /* -80 */ 0x4BE2_B05D_3584_8CD2L, 0x7733_61E7_F259_F507L, + /* -79 */ 0x5EDB_5C74_82E5_B007L, 0x5500_3A61_EEF0_7249L, + /* -78 */ 0x7692_3391_A39F_1C09L, 0x4A40_48FA_6AAC_8EDBL, + /* -77 */ 0x4A1B_603B_0643_7185L, 0x7E68_2D9C_82AB_D949L, + /* -76 */ 0x5CA2_3849_C7D4_4DE7L, 0x3E02_3903_A356_CF9BL, + /* -75 */ 0x73CA_C65C_39C9_6161L, 0x2D82_C744_8C2C_8382L, + /* -74 */ 0x485E_BBF9_A41D_DCDCL, 0x6C71_BC8A_D79B_D231L, + /* -73 */ 0x5A76_6AF8_0D25_5414L, 0x078E_2BAD_8D82_C6BDL, + /* -72 */ 0x7114_05B6_106E_A919L, 0x0971_B698_F0E3_786DL, + /* -71 */ 0x46AC_8391_CA45_29AFL, 0x55E7_121F_968E_2B44L, + /* -70 */ 0x5857_A476_3CD6_741BL, 0x4B60_D6A7_7C31_B615L, + /* -69 */ 0x6E6D_8D93_CC0C_1122L, 0x3E39_0C51_5B3E_239AL, + /* -68 */ 0x4504_787C_5F87_8AB5L, 0x46E3_A7B2_D906_D640L, + /* -67 */ 0x5645_969B_7769_6D62L, 0x789C_919F_8F48_8BD0L, + /* -66 */ 0x6BD6_FC42_5543_C8BBL, 0x56C3_B607_731A_AEC4L, + /* -65 */ 0x4366_5DA9_754A_5D75L, 0x263A_51C4_A7F0_AD3BL, + /* -64 */ 0x543F_F513_D29C_F4D2L, 0x4FC8_E635_D1EC_D88AL, + /* -63 */ 0x694F_F258_C744_3207L, 0x23BB_1FC3_4668_0EACL, + /* -62 */ 0x41D1_F777_7C8A_9F44L, 0x4654_F3DA_0C01_092CL, + /* -61 */ 0x5246_7555_5BAD_4715L, 0x57EA_30D0_8F01_4B76L, + /* -60 */ 0x66D8_12AA_B298_98DBL, 0x0DE4_BD04_B2C1_9E54L, + /* -59 */ 0x4047_0BAA_AF9F_5F88L, 0x78AE_F622_EFB9_02F5L, + /* -58 */ 0x5058_CE95_5B87_376BL, 0x16DA_B3AB_ABA7_43B2L, + /* -57 */ 0x646F_023A_B269_0545L, 0x7C91_6096_9691_149EL, + /* -56 */ 0x7D8A_C2C9_5F03_4697L, 0x3BB5_B8BC_3C35_59C5L, + /* -55 */ 0x4E76_B9BD_DB62_0C1EL, 0x5551_9375_A5A1_581BL, + /* -54 */ 0x6214_682D_523A_8F26L, 0x2AA5_F853_0F09_AE22L, + /* -53 */ 0x7A99_8238_A6C9_32EFL, 0x754F_7667_D2CC_19ABL, + /* -52 */ 0x4C9F_F163_683D_BFD5L, 0x7951_AA00_E3BF_900BL, + /* -51 */ 0x5FC7_EDBC_424D_2FCBL, 0x37A6_1481_1CAF_740DL, + /* -50 */ 0x77B9_E92B_52E0_7BBEL, 0x258F_99A1_63DB_5111L, + /* -49 */ 0x4AD4_31BB_13CC_4D56L, 0x7779_C004_DE69_12ABL, + /* -48 */ 0x5D89_3E29_D8BF_60ACL, 0x5558_3006_1603_5755L, + /* -47 */ 0x74EB_8DB4_4EEF_38D7L, 0x6AAE_3C07_9B84_2D2AL, + /* -46 */ 0x4913_3890_B155_8386L, 0x72AC_E584_C132_9C3BL, + /* -45 */ 0x5B58_06B4_DDAA_E468L, 0x4F58_1EE5_F17F_4349L, + /* -44 */ 0x722E_0862_1515_9D82L, 0x632E_269F_6DDF_141BL, + /* -43 */ 0x475C_C53D_4D2D_8271L, 0x5DFC_D823_A4AB_6C91L, + /* -42 */ 0x5933_F68C_A078_E30EL, 0x157C_0E2C_8DD6_47B5L, + /* -41 */ 0x6F80_F42F_C897_1BD1L, 0x5ADB_11B7_B14B_D9A3L, + /* -40 */ 0x45B0_989D_DD5E_7163L, 0x08C8_EB12_CECF_6806L, + /* -39 */ 0x571C_BEC5_54B6_0DBBL, 0x6AFB_25D7_8283_4207L, + /* -38 */ 0x6CE3_EE76_A9E3_912AL, 0x65B9_EF4D_6324_1289L, + /* -37 */ 0x440E_750A_2A2E_3ABAL, 0x5F94_3590_5DF6_8B96L, + /* -36 */ 0x5512_124C_B4B9_C969L, 0x3779_42F4_7574_2E7BL, + /* -35 */ 0x6A56_96DF_E1E8_3BC3L, 0x6557_93B1_92D1_3A1AL, + /* -34 */ 0x4276_1E4B_ED31_255AL, 0x2F56_BC4E_FBC2_C450L, + /* -33 */ 0x5313_A5DE_E87D_6EB0L, 0x7B2C_6B62_BAB3_7564L, + /* -32 */ 0x67D8_8F56_A29C_CA5DL, 0x19F7_863B_6960_52BDL, + /* -31 */ 0x40E7_5996_25A1_FE7AL, 0x203A_B3E5_21DC_33B6L, + /* -30 */ 0x5121_2FFB_AF0A_7E18L, 0x6849_60DE_6A53_40A4L, + /* -29 */ 0x6569_7BFA_9ACD_1D9FL, 0x025B_B916_04E8_10CDL, + /* -28 */ 0x7EC3_DAF9_4180_6506L, 0x62F2_A75B_8622_1500L, + /* -27 */ 0x4F3A_68DB_C8F0_3F24L, 0x1DD7_A899_33D5_4D20L, + /* -26 */ 0x6309_0312_BB2C_4EEDL, 0x254D_92BF_80CA_A068L, + /* -25 */ 0x7BCB_43D7_69F7_62A8L, 0x4EA0_F76F_60FD_4882L, + /* -24 */ 0x4D5F_0A66_A23A_9DA9L, 0x3124_9AA5_9C9E_4D51L, + /* -23 */ 0x60B6_CD00_4AC9_4513L, 0x5D6D_C14F_03C5_E0A5L, + /* -22 */ 0x78E4_8040_5D7B_9658L, 0x54C9_31A2_C4B7_58CFL, + /* -21 */ 0x4B8E_D028_3A6D_3DF7L, 0x34FD_BF05_BAF2_9781L, + /* -20 */ 0x5E72_8432_4908_8D75L, 0x223D_2EC7_29AF_3D62L, + /* -19 */ 0x760F_253E_DB4A_B0D2L, 0x4ACC_7A78_F41B_0CBAL, + /* -18 */ 0x49C9_7747_490E_AE83L, 0x4EBF_CC8B_9890_E7F4L, + /* -17 */ 0x5C3B_D519_1B52_5A24L, 0x426F_BFAE_7EB5_21F1L, + /* -16 */ 0x734A_CA5F_6226_F0ADL, 0x530B_AF9A_1E62_6A6DL, + /* -15 */ 0x480E_BE7B_9D58_566CL, 0x43E7_4DC0_52FD_8285L, + /* -14 */ 0x5A12_6E1A_84AE_6C07L, 0x54E1_2130_67BC_E326L, + /* -13 */ 0x7097_09A1_25DA_0709L, 0x4A19_697C_81AC_1BEFL, + /* -12 */ 0x465E_6604_B7A8_4465L, 0x7E4F_E1ED_D10B_9175L, + /* -11 */ 0x57F5_FF85_E592_557FL, 0x3DE3_DA69_454E_75D3L, + /* -10 */ 0x6DF3_7F67_5EF6_EADFL, 0x2D5C_D103_96A2_1347L, + /* -9 */ 0x44B8_2FA0_9B5A_52CBL, 0x4C5A_02A2_3E25_4C0DL, + /* -8 */ 0x55E6_3B88_C230_E77EL, 0x3F70_834A_CDAE_9F10L, + /* -7 */ 0x6B5F_CA6A_F2BD_215EL, 0x0F4C_A41D_811A_46D4L, + /* -6 */ 0x431B_DE82_D7B6_34DAL, 0x698F_E692_70B0_6C44L, + /* -5 */ 0x53E2_D623_8DA3_C211L, 0x43F3_E037_0CDC_8755L, + /* -4 */ 0x68DB_8BAC_710C_B295L, 0x74F0_D844_D013_A92BL, + /* -3 */ 0x4189_374B_C6A7_EF9DL, 0x5916_872B_020C_49BBL, + /* -2 */ 0x51EB_851E_B851_EB85L, 0x0F5C_28F5_C28F_5C29L, + /* -1 */ 0x6666_6666_6666_6666L, 0x3333_3333_3333_3334L, + /* 0 */ 0x4000_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 1 */ 0x5000_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 2 */ 0x6400_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 3 */ 0x7D00_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 4 */ 0x4E20_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 5 */ 0x61A8_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 6 */ 0x7A12_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 7 */ 0x4C4B_4000_0000_0000L, 0x0000_0000_0000_0001L, + /* 8 */ 0x5F5E_1000_0000_0000L, 0x0000_0000_0000_0001L, + /* 9 */ 0x7735_9400_0000_0000L, 0x0000_0000_0000_0001L, + /* 10 */ 0x4A81_7C80_0000_0000L, 0x0000_0000_0000_0001L, + /* 11 */ 0x5D21_DBA0_0000_0000L, 0x0000_0000_0000_0001L, + /* 12 */ 0x746A_5288_0000_0000L, 0x0000_0000_0000_0001L, + /* 13 */ 0x48C2_7395_0000_0000L, 0x0000_0000_0000_0001L, + /* 14 */ 0x5AF3_107A_4000_0000L, 0x0000_0000_0000_0001L, + /* 15 */ 0x71AF_D498_D000_0000L, 0x0000_0000_0000_0001L, + /* 16 */ 0x470D_E4DF_8200_0000L, 0x0000_0000_0000_0001L, + /* 17 */ 0x58D1_5E17_6280_0000L, 0x0000_0000_0000_0001L, + /* 18 */ 0x6F05_B59D_3B20_0000L, 0x0000_0000_0000_0001L, + /* 19 */ 0x4563_9182_44F4_0000L, 0x0000_0000_0000_0001L, + /* 20 */ 0x56BC_75E2_D631_0000L, 0x0000_0000_0000_0001L, + /* 21 */ 0x6C6B_935B_8BBD_4000L, 0x0000_0000_0000_0001L, + /* 22 */ 0x43C3_3C19_3756_4800L, 0x0000_0000_0000_0001L, + /* 23 */ 0x54B4_0B1F_852B_DA00L, 0x0000_0000_0000_0001L, + /* 24 */ 0x69E1_0DE7_6676_D080L, 0x0000_0000_0000_0001L, + /* 25 */ 0x422C_A8B0_A00A_4250L, 0x0000_0000_0000_0001L, + /* 26 */ 0x52B7_D2DC_C80C_D2E4L, 0x0000_0000_0000_0001L, + /* 27 */ 0x6765_C793_FA10_079DL, 0x0000_0000_0000_0001L, + /* 28 */ 0x409F_9CBC_7C4A_04C2L, 0x1000_0000_0000_0001L, + /* 29 */ 0x50C7_83EB_9B5C_85F2L, 0x5400_0000_0000_0001L, + /* 30 */ 0x64F9_64E6_8233_A76FL, 0x2900_0000_0000_0001L, + /* 31 */ 0x7E37_BE20_22C0_914BL, 0x1340_0000_0000_0001L, + /* 32 */ 0x4EE2_D6D4_15B8_5ACEL, 0x7C08_0000_0000_0001L, + /* 33 */ 0x629B_8C89_1B26_7182L, 0x5B0A_0000_0000_0001L, + /* 34 */ 0x7B42_6FAB_61F0_0DE3L, 0x31CC_8000_0000_0001L, + /* 35 */ 0x4D09_85CB_1D36_08AEL, 0x0F1F_D000_0000_0001L, + /* 36 */ 0x604B_E73D_E483_8AD9L, 0x52E7_C400_0000_0001L, + /* 37 */ 0x785E_E10D_5DA4_6D90L, 0x07A1_B500_0000_0001L, + /* 38 */ 0x4B3B_4CA8_5A86_C47AL, 0x04C5_1120_0000_0001L, + /* 39 */ 0x5E0A_1FD2_7128_7598L, 0x45F6_5568_0000_0001L, + /* 40 */ 0x758C_A7C7_0D72_92FEL, 0x5773_EAC2_0000_0001L, + /* 41 */ 0x4977_E8DC_6867_9BDFL, 0x16A8_72B9_4000_0001L, + /* 42 */ 0x5BD5_E313_8281_82D6L, 0x7C52_8F67_9000_0001L, + /* 43 */ 0x72CB_5BD8_6321_E38CL, 0x5B67_3341_7400_0001L, + /* 44 */ 0x47BF_1967_3DF5_2E37L, 0x7920_8008_E880_0001L, + /* 45 */ 0x59AE_DFC1_0D72_79C5L, 0x7768_A00B_22A0_0001L, + /* 46 */ 0x701A_97B1_50CF_1837L, 0x3542_C80D_EB48_0001L, + /* 47 */ 0x4610_9ECE_D281_6F22L, 0x5149_BD08_B30D_0001L, + /* 48 */ 0x5794_C682_8721_CAEBL, 0x259C_2C4A_DFD0_4001L, + /* 49 */ 0x6D79_F823_28EA_3DA6L, 0x0F03_375D_97C4_5001L, + /* 50 */ 0x446C_3B15_F992_6687L, 0x6962_029A_7EDA_B201L, + /* 51 */ 0x5587_49DB_77F7_0029L, 0x63BA_8341_1E91_5E81L, + /* 52 */ 0x6AE9_1C52_55F4_C034L, 0x1CA9_2411_6635_B621L, + /* 53 */ 0x42D1_B1B3_75B8_F820L, 0x51E9_B68A_DFE1_91D5L, + /* 54 */ 0x5386_1E20_5327_3628L, 0x6664_242D_97D9_F64AL, + /* 55 */ 0x6867_A5A8_67F1_03B2L, 0x7FFD_2D38_FDD0_73DCL, + /* 56 */ 0x4140_C789_40F6_A24FL, 0x6FFE_3C43_9EA2_486AL, + /* 57 */ 0x5190_F96B_9134_4AE3L, 0x6BFD_CB54_864A_DA84L, + /* 58 */ 0x65F5_37C6_7581_5D9CL, 0x66FD_3E29_A7DD_9125L, + /* 59 */ 0x7F72_85B8_12E1_B504L, 0x00BC_8DB4_11D4_F56EL, + /* 60 */ 0x4FA7_9393_0BCD_1122L, 0x4075_D890_8B25_1965L, + /* 61 */ 0x6391_7877_CEC0_556BL, 0x1093_4EB4_ADEE_5FBEL, + /* 62 */ 0x7C75_D695_C270_6AC5L, 0x74B8_2261_D969_F7ADL, + /* 63 */ 0x4DC9_A61D_9986_42BBL, 0x58F3_157D_27E2_3ACCL, + /* 64 */ 0x613C_0FA4_FFE7_D36AL, 0x4F2F_DADC_71DA_C97FL, + /* 65 */ 0x798B_138E_3FE1_C845L, 0x22FB_D193_8E51_7BDFL, + /* 66 */ 0x4BF6_EC38_E7ED_1D2BL, 0x25DD_62FC_38F2_ED6CL, + /* 67 */ 0x5EF4_A747_21E8_6476L, 0x0F54_BBBB_472F_A8C6L, + /* 68 */ 0x76B1_D118_EA62_7D93L, 0x5329_EAAA_18FB_92F8L, + /* 69 */ 0x4A2F_22AF_927D_8E7CL, 0x23FA_32AA_4F9D_3BDBL, + /* 70 */ 0x5CBA_EB5B_771C_F21BL, 0x2CF8_BF54_E384_8AD2L, + /* 71 */ 0x73E9_A632_54E4_2EA2L, 0x1836_EF2A_1C65_AD86L, + /* 72 */ 0x4872_07DF_750E_9D25L, 0x2F22_557A_51BF_8C74L, + /* 73 */ 0x5A8E_89D7_5252_446EL, 0x5AEA_EAD8_E62F_6F91L, + /* 74 */ 0x7132_2C4D_26E6_D58AL, 0x31A5_A58F_1FBB_4B75L, + /* 75 */ 0x46BF_5BB0_3850_4576L, 0x3F07_8779_73D5_0F29L, + /* 76 */ 0x586F_329C_4664_56D4L, 0x0EC9_6957_D0CA_52F3L, + /* 77 */ 0x6E8A_FF43_57FD_6C89L, 0x127B_C3AD_C4FC_E7B0L, + /* 78 */ 0x4516_DF8A_16FE_63D5L, 0x5B8D_5A4C_9B1E_10CEL, + /* 79 */ 0x565C_976C_9CBD_FCCBL, 0x1270_B0DF_C1E5_9502L, + /* 80 */ 0x6BF3_BD47_C3ED_7BFDL, 0x770C_DD17_B25E_FA42L, + /* 81 */ 0x4378_564C_DA74_6D7EL, 0x5A68_0A2E_CF7B_5C69L, + /* 82 */ 0x5456_6BE0_1111_88DEL, 0x3102_0CBA_835A_3384L, + /* 83 */ 0x696C_06D8_1555_EB15L, 0x7D42_8FE9_2430_C065L, + /* 84 */ 0x41E3_8447_0D55_B2EDL, 0x5E49_99F1_B69E_783FL, + /* 85 */ 0x525C_6558_D0AB_1FA9L, 0x15DC_006E_2446_164FL, + /* 86 */ 0x66F3_7EAF_04D5_E793L, 0x3B53_0089_AD57_9BE2L, + /* 87 */ 0x4058_2F2D_6305_B0BCL, 0x1513_E056_0C56_C16EL, + /* 88 */ 0x506E_3AF8_BBC7_1CEBL, 0x1A58_D86B_8F6C_71C9L, + /* 89 */ 0x6489_C9B6_EAB8_E426L, 0x00EF_0E86_7347_8E3BL, + /* 90 */ 0x7DAC_3C24_A567_1D2FL, 0x412A_D228_1019_71C9L, + /* 91 */ 0x4E8B_A596_E760_723DL, 0x58BA_C359_0A0F_E71EL, + /* 92 */ 0x622E_8EFC_A138_8ECDL, 0x0EE9_742F_4C93_E0E6L, + /* 93 */ 0x7ABA_32BB_C986_B280L, 0x32A3_D13B_1FB8_D91FL, + /* 94 */ 0x4CB4_5FB5_5DF4_2F90L, 0x1FA6_62C4_F3D3_87B3L, + /* 95 */ 0x5FE1_77A2_B571_3B74L, 0x278F_FB76_30C8_69A0L, + /* 96 */ 0x77D9_D58B_62CD_8A51L, 0x3173_FA53_BCFA_8408L, + /* 97 */ 0x4AE8_2577_1DC0_7672L, 0x6EE8_7C74_561C_9285L, + /* 98 */ 0x5DA2_2ED4_E530_940FL, 0x4AA2_9B91_6BA3_B726L, + /* 99 */ 0x750A_BA8A_1E7C_B913L, 0x3D4B_4275_C68C_A4F0L, + /* 100 */ 0x4926_B496_530D_F3ACL, 0x164F_0989_9C17_E716L, + /* 101 */ 0x5B70_61BB_E7D1_7097L, 0x1BE2_CBEC_031D_E0DCL, + /* 102 */ 0x724C_7A2A_E1C5_CCBDL, 0x02DB_7EE7_03E5_5912L, + /* 103 */ 0x476F_CC5A_CD1B_9FF6L, 0x11C9_2F50_626F_57ACL, + /* 104 */ 0x594B_BF71_8062_87F3L, 0x563B_7B24_7B0B_2D96L, + /* 105 */ 0x6F9E_AF4D_E07B_29F0L, 0x4BCA_59ED_99CD_F8FCL, + /* 106 */ 0x45C3_2D90_AC4C_FA36L, 0x2F5E_7834_8020_BB9EL, + /* 107 */ 0x5733_F8F4_D760_38C3L, 0x7B36_1641_A028_EA85L, + /* 108 */ 0x6D00_F732_0D38_46F4L, 0x7A03_9BD2_0833_2526L, + /* 109 */ 0x4420_9A7F_4843_2C59L, 0x0C42_4163_451F_F738L, + /* 110 */ 0x5528_C11F_1A53_F76FL, 0x2F52_D1BC_1667_F506L, + /* 111 */ 0x6A72_F166_E0E8_F54BL, 0x1B27_862B_1C01_F247L, + /* 112 */ 0x4287_D6E0_4C91_994FL, 0x00F8_B3DA_F181_376DL, + /* 113 */ 0x5329_CC98_5FB5_FFA2L, 0x6136_E0D1_ADE1_8548L, + /* 114 */ 0x67F4_3FBE_77A3_7F8BL, 0x3984_9906_1959_E699L, + /* 115 */ 0x40F8_A7D7_0AC6_2FB7L, 0x13F2_DFA3_CFD8_3020L, + /* 116 */ 0x5136_D1CC_CD77_BBA4L, 0x78EF_978C_C3CE_3C28L, + /* 117 */ 0x6584_8640_00D5_AA8EL, 0x172B_7D6F_F4C1_CB32L, + /* 118 */ 0x7EE5_A7D0_010B_1531L, 0x5CF6_5CCB_F1F2_3DFEL, + /* 119 */ 0x4F4F_88E2_00A6_ED3FL, 0x0A19_F9FF_7737_66BFL, + /* 120 */ 0x6323_6B1A_80D0_A88EL, 0x6CA0_787F_5505_406FL, + /* 121 */ 0x7BEC_45E1_2104_D2B2L, 0x47C8_969F_2A46_908AL, + /* 122 */ 0x4D73_ABAC_B4A3_03AFL, 0x4CDD_5E23_7A6C_1A57L, + /* 123 */ 0x60D0_9697_E1CB_C49BL, 0x4014_B5AC_5907_20ECL, + /* 124 */ 0x7904_BC3D_DA3E_B5C2L, 0x3019_E317_6F48_E927L, + /* 125 */ 0x4BA2_F5A6_A867_3199L, 0x3E10_2DEE_A58D_91B9L, + /* 126 */ 0x5E8B_B310_5280_FDFFL, 0x6D94_396A_4EF0_F627L, + /* 127 */ 0x762E_9FD4_6721_3D7FL, 0x68F9_47C4_E2AD_33B0L, + /* 128 */ 0x49DD_23E4_C074_C66FL, 0x719B_CCDB_0DAC_404EL, + /* 129 */ 0x5C54_6CDD_F091_F80BL, 0x6E02_C011_D117_5062L, + /* 130 */ 0x7369_8815_6CB6_760EL, 0x6983_7016_455D_247AL, + /* 131 */ 0x4821_F50D_63F2_09C9L, 0x21F2_260D_EB5A_36CCL, + /* 132 */ 0x5A2A_7250_BCEE_8C3BL, 0x4A6E_AF91_6630_C47FL, + /* 133 */ 0x70B5_0EE4_EC2A_2F4AL, 0x3D0A_5B75_BFBC_F59FL, + /* 134 */ 0x4671_294F_139A_5D8EL, 0x4626_7929_97D6_1984L, + /* 135 */ 0x580D_73A2_D880_F4F2L, 0x17B0_1773_FDCB_9FE4L, + /* 136 */ 0x6E10_D08B_8EA1_322EL, 0x5D9C_1D50_FD3E_87DDL, + /* 137 */ 0x44CA_8257_3924_BF5DL, 0x1A81_9252_9E47_14EBL, + /* 138 */ 0x55FD_22ED_076D_EF34L, 0x4121_F6E7_45D8_DA25L, + /* 139 */ 0x6B7C_6BA8_4949_6B01L, 0x516A_74A1_174F_10AEL, + /* 140 */ 0x432D_C349_2DCD_E2E1L, 0x02E2_88E4_AE91_6A6DL, + /* 141 */ 0x53F9_341B_7941_5B99L, 0x239B_2B1D_DA35_C508L, + /* 142 */ 0x68F7_8122_5791_B27FL, 0x4C81_F5E5_50C3_364AL, + /* 143 */ 0x419A_B0B5_76BB_0F8FL, 0x5FD1_39AF_527A_01EFL, + /* 144 */ 0x5201_5CE2_D469_D373L, 0x57C5_881B_2718_826AL, + /* 145 */ 0x6681_B41B_8984_4850L, 0x4DB6_EA21_F0DE_A304L, + /* 146 */ 0x4011_1091_35F2_AD32L, 0x3092_5255_368B_25E3L, + /* 147 */ 0x5015_54B5_836F_587EL, 0x7CB6_E6EA_842D_EF5CL, + /* 148 */ 0x641A_A9E2_E44B_2E9EL, 0x5BE4_A0A5_2539_6B32L, + /* 149 */ 0x7D21_545B_9D5D_FA46L, 0x32DD_C8CE_6E87_C5FFL, + /* 150 */ 0x4E34_D4B9_425A_BC6BL, 0x7FCA_9D81_0514_DBBFL, + /* 151 */ 0x61C2_09E7_92F1_6B86L, 0x7FBD_44E1_465A_12AFL, + /* 152 */ 0x7A32_8C61_77AD_C668L, 0x5FAC_9619_97F0_975BL, + /* 153 */ 0x4C5F_97BC_EACC_9C01L, 0x3BCB_DDCF_FEF6_5E99L, + /* 154 */ 0x5F77_7DAC_257F_C301L, 0x6ABE_D543_FEB3_F63FL, + /* 155 */ 0x7755_5D17_2EDF_B3C2L, 0x256E_8A94_FE60_F3CFL, + /* 156 */ 0x4A95_5A2E_7D4B_D059L, 0x3765_169D_1EFC_9861L, + /* 157 */ 0x5D3A_B0BA_1C9E_C46FL, 0x653E_5C44_66BB_BE7AL, + /* 158 */ 0x7489_5CE8_A3C6_758BL, 0x5E8D_F355_806A_AE18L, + /* 159 */ 0x48D5_DA11_665C_0977L, 0x2B18_B815_7042_ACCFL, + /* 160 */ 0x5B0B_5095_BFF3_0BD5L, 0x15DE_E61A_CC53_5803L, + /* 161 */ 0x71CE_24BB_2FEF_CECAL, 0x3B56_9FA1_7F68_2E03L, + /* 162 */ 0x4720_D6F4_FDF5_E13EL, 0x4516_23C4_EFA1_1CC2L, + /* 163 */ 0x58E9_0CB2_3D73_598EL, 0x165B_ACB6_2B89_63F3L, + /* 164 */ 0x6F23_4FDE_CCD0_2FF1L, 0x5BF2_97E3_B66B_BCEFL, + /* 165 */ 0x4576_11EB_4002_1DF7L, 0x0977_9EEE_5203_5616L, + /* 166 */ 0x56D3_9666_1002_A574L, 0x6BD5_86A9_E684_2B9BL, + /* 167 */ 0x6C88_7BFF_9403_4ED2L, 0x06CA_E854_6025_3682L, + /* 168 */ 0x43D5_4D7F_BC82_1143L, 0x243E_D134_BC17_4211L, + /* 169 */ 0x54CA_A0DF_ABA2_9594L, 0x0D4E_8581_EB1D_1295L, + /* 170 */ 0x69FD_4917_968B_3AF9L, 0x10A2_26E2_65E4_573BL, + /* 171 */ 0x423E_4DAE_BE17_04DBL, 0x5A65_584D_7FAE_B685L, + /* 172 */ 0x52CD_E11A_6D9C_C612L, 0x50FE_AE60_DF9A_6426L, + /* 173 */ 0x6781_5961_0903_F797L, 0x253E_59F9_1780_FD2FL, + /* 174 */ 0x40B0_D7DC_A5A2_7ABEL, 0x4746_F83B_AEB0_9E3EL, + /* 175 */ 0x50DD_0DD3_CF0B_196EL, 0x1918_B64A_9A5C_C5CDL, + /* 176 */ 0x6514_5148_C2CD_DFC9L, 0x5F5E_E3DD_40F3_F740L, + /* 177 */ 0x7E59_659A_F381_57BCL, 0x1736_9CD4_9130_F510L, + /* 178 */ 0x4EF7_DF80_D830_D6D5L, 0x4E82_2204_DABE_992AL, + /* 179 */ 0x62B5_D761_0E3D_0C8BL, 0x0222_AA86_116E_3F75L, + /* 180 */ 0x7B63_4D39_51CC_4FADL, 0x62AB_5527_95C9_CF52L, + /* 181 */ 0x4D1E_1043_D31F_B1CCL, 0x4DAB_1538_BD9E_2193L, + /* 182 */ 0x6065_9454_C7E7_9E3FL, 0x6115_DA86_ED05_A9F8L, + /* 183 */ 0x787E_F969_F9E1_85CFL, 0x595B_5128_A847_1476L, + /* 184 */ 0x4B4F_5BE2_3C2C_F3A1L, 0x67D9_12B9_692C_6CCAL, + /* 185 */ 0x5E23_32DA_CB38_308AL, 0x21CF_5767_C377_87FCL, + /* 186 */ 0x75AB_FF91_7E06_3CACL, 0x6A43_2D41_B455_69FBL, + /* 187 */ 0x498B_7FBA_EEC3_E5ECL, 0x0269_FC49_10B5_623DL, + /* 188 */ 0x5BEE_5FA9_AA74_DF67L, 0x0304_7B5B_54E2_BACCL, + /* 189 */ 0x72E9_F794_1512_1740L, 0x63C5_9A32_2A1B_697FL, + /* 190 */ 0x47D2_3ABC_8D2B_4E88L, 0x3E5B_805F_5A51_21F0L, + /* 191 */ 0x59C6_C96B_B076_222AL, 0x4DF2_6077_30E5_6A6CL, + /* 192 */ 0x7038_7BC6_9C93_AAB5L, 0x216E_F894_FD1E_C506L, + /* 193 */ 0x4623_4D5C_21DC_4AB1L, 0x24E5_5B5D_1E33_3B24L, + /* 194 */ 0x57AC_20B3_2A53_5D5DL, 0x4E1E_B234_65C0_09EDL, + /* 195 */ 0x6D97_28DF_F4E8_34B5L, 0x01A6_5EC1_7F30_0C68L, + /* 196 */ 0x447E_798B_F911_20F1L, 0x1107_FB38_EF7E_07C1L, + /* 197 */ 0x559E_17EE_F755_692DL, 0x3549_FA07_2B5D_89B1L, + /* 198 */ 0x6B05_9DEA_B52A_C378L, 0x629C_7888_F634_EC1EL, + /* 199 */ 0x42E3_82B2_B13A_BA2BL, 0x3DA1_CB55_99E1_1393L, + /* 200 */ 0x539C_635F_5D89_68B6L, 0x2D0A_3E2B_0059_5877L, + /* 201 */ 0x6883_7C37_34EB_C2E3L, 0x784C_CDB5_C06F_AE95L, + /* 202 */ 0x4152_2DA2_8113_59CEL, 0x3B30_0091_9845_CD1DL, + /* 203 */ 0x51A6_B90B_2158_3042L, 0x09FC_00B5_FE57_4065L, + /* 204 */ 0x6610_674D_E9AE_3C52L, 0x4C7B_00E3_7DED_107EL, + /* 205 */ 0x7F94_8121_6419_CB67L, 0x1F99_C11C_5D68_549DL, + /* 206 */ 0x4FBC_D0B4_DE90_1F20L, 0x43C0_18B1_BA61_34E2L, + /* 207 */ 0x63AC_04E2_1634_26E8L, 0x54B0_1EDE_28F9_821BL, + /* 208 */ 0x7C97_061A_9BC1_30A2L, 0x69DC_2695_B337_E2A1L, + /* 209 */ 0x4DDE_63D0_A158_BE65L, 0x6229_981D_9002_EDA5L, + /* 210 */ 0x6155_FCC4_C9AE_EDFFL, 0x1AB3_FE24_F403_A90EL, + /* 211 */ 0x79AB_7BF5_FC1A_A97FL, 0x0160_FDAE_3104_9351L, + /* 212 */ 0x4C0B_2D79_BD90_A9EFL, 0x30DC_9E8C_DEA2_DC13L, + /* 213 */ 0x5F0D_F8D8_2CF4_D46BL, 0x1D13_C630_164B_9318L, + /* 214 */ 0x76D1_770E_3832_0986L, 0x0458_B7BC_1BDE_77DDL, + /* 215 */ 0x4A42_EA68_E31F_45F3L, 0x62B7_72D5_916B_0AEBL, + /* 216 */ 0x5CD3_A503_1BE7_1770L, 0x5B65_4F8A_F5C5_CDA5L, + /* 217 */ 0x7408_8E43_E2E0_DD4CL, 0x723E_A36D_B337_410EL, + /* 218 */ 0x4885_58EA_6DCC_8A50L, 0x0767_2624_9002_88A9L, + /* 219 */ 0x5AA6_AF25_093F_ACE4L, 0x0940_EFAD_B403_2AD3L, + /* 220 */ 0x7150_5AEE_4B8F_981DL, 0x0B91_2B99_2103_F588L, + /* 221 */ 0x46D2_38D4_EF39_BF12L, 0x173A_BB3F_B4A2_7975L, + /* 222 */ 0x5886_C70A_2B08_2ED6L, 0x5D09_6A0F_A1CB_17D2L, + /* 223 */ 0x6EA8_78CC_B5CA_3A8CL, 0x344B_C493_8A3D_DDC7L, + /* 224 */ 0x4529_4B7F_F19E_6497L, 0x60AF_5ADC_3666_AA9CL, + /* 225 */ 0x5673_9E5F_EE05_FDBDL, 0x58DB_3193_4400_5543L, + /* 226 */ 0x6C10_85F7_E987_7D2DL, 0x0F11_FDF8_1500_6A94L, + /* 227 */ 0x438A_53BA_F1F4_AE3CL, 0x196B_3EBB_0D20_429DL, + /* 228 */ 0x546C_E8A9_AE71_D9CBL, 0x1FC6_0E69_D068_5344L, + /* 229 */ 0x6988_22D4_1A0E_503EL, 0x07B7_9204_4482_6815L, + /* 230 */ 0x41F5_15C4_9048_F226L, 0x64D2_BB42_AAD1_810DL, + /* 231 */ 0x5272_5B35_B45B_2EB0L, 0x3E07_6A13_5585_E150L, + /* 232 */ 0x670E_F203_2171_FA5CL, 0x4D89_4498_2AE7_59A4L, + /* 233 */ 0x4069_5741_F4E7_3C79L, 0x7075_CADF_1AD0_9807L, + /* 234 */ 0x5083_AD12_7221_0B98L, 0x2C93_3D96_E184_BE08L, + /* 235 */ 0x64A4_9857_0EA9_4E7EL, 0x37B8_0CFC_99E5_ED8AL, + /* 236 */ 0x7DCD_BE6C_D253_A21EL, 0x05A6_103B_C05F_68EDL, + /* 237 */ 0x4EA0_9704_0374_4552L, 0x6387_CA25_583B_A194L, + /* 238 */ 0x6248_BCC5_0451_56A7L, 0x3C69_BCAE_AE4A_89F9L, + /* 239 */ 0x7ADA_EBF6_4565_AC51L, 0x2B84_2BDA_59DD_2C77L, + /* 240 */ 0x4CC8_D379_EB5F_8BB2L, 0x6B32_9B68_782A_3BCBL, + /* 241 */ 0x5FFB_0858_6637_6E9FL, 0x45FF_4242_9634_CABDL, + /* 242 */ 0x77F9_CA6E_7FC5_4A47L, 0x377F_12D3_3BC1_FD6DL, + /* 243 */ 0x4AFC_1E85_0FDB_4E6CL, 0x52AF_6BC4_0559_3E64L, + /* 244 */ 0x5DBB_2626_53D2_2207L, 0x675B_46B5_06AF_8DFDL, + /* 245 */ 0x7529_EFAF_E8C6_AA89L, 0x6132_1862_485B_717CL, + /* 246 */ 0x493A_35CD_F17C_2A96L, 0x0CBF_4F3D_6D39_26EEL, + /* 247 */ 0x5B88_C341_6DDB_353BL, 0x4FEF_230C_C887_70A9L, + /* 248 */ 0x726A_F411_C952_028AL, 0x43EA_EBCF_FAA9_4CD3L, + /* 249 */ 0x4782_D88B_1DD3_4196L, 0x4A72_D361_FCA9_D004L, + /* 250 */ 0x5963_8EAD_E548_11FCL, 0x1D0F_883A_7BD4_4405L, + /* 251 */ 0x6FBC_7259_5E9A_167BL, 0x2453_6A49_1AC9_5506L, + /* 252 */ 0x45D5_C777_DB20_4E0DL, 0x06B4_226D_B0BD_D524L, + /* 253 */ 0x574B_3955_D1E8_6190L, 0x2861_2B09_1CED_4A6DL, + /* 254 */ 0x6D1E_07AB_4662_79F4L, 0x3279_75CB_6428_9D08L, + /* 255 */ 0x4432_C4CB_0BFD_8C38L, 0x5F8B_E99F_1E99_6225L, + /* 256 */ 0x553F_75FD_CEFC_EF46L, 0x776E_E406_E63F_BAAEL, + /* 257 */ 0x6A8F_537D_42BC_2B18L, 0x554A_9D08_9FCF_A95AL, + /* 258 */ 0x4299_942E_49B5_9AEFL, 0x354E_A225_63E1_C9D8L, + /* 259 */ 0x533F_F939_DC23_01ABL, 0x22A2_4AAE_BCDA_3C4EL, + /* 260 */ 0x680F_F788_532B_C216L, 0x0B4A_DD5A_6C10_CB62L, + /* 261 */ 0x4109_FAB5_33FB_594DL, 0x670E_CA58_838A_7F1DL, + /* 262 */ 0x514C_7962_80FA_2FA1L, 0x20D2_7CEE_A46D_1EE4L, + /* 263 */ 0x659F_97BB_2138_BB89L, 0x4907_1C2A_4D88_669DL, + /* 264 */ 0x7F07_7DA9_E986_EA6BL, 0x7B48_E334_E0EA_8045L, + /* 265 */ 0x4F64_AE8A_31F4_5283L, 0x3D0D_8E01_0C92_902BL, + /* 266 */ 0x633D_DA2C_BE71_6724L, 0x2C50_F181_4FB7_3436L, + /* 267 */ 0x7C0D_50B7_EE0D_C0EDL, 0x3765_2DE1_A3A5_0143L, + /* 268 */ 0x4D88_5272_F4C8_9894L, 0x329F_3CAD_0647_20CAL, + /* 269 */ 0x60EA_670F_B1FA_BEB9L, 0x3F47_0BD8_47D8_E8FDL, + /* 270 */ 0x7925_00D3_9E79_6E67L, 0x6F18_CECE_59CF_233CL, + /* 271 */ 0x4BB7_2084_430B_E500L, 0x756F_8140_F821_7605L, + /* 272 */ 0x5EA4_E8A5_53CE_DE41L, 0x12CB_6191_3629_D387L, + /* 273 */ 0x764E_22CE_A8C2_95D1L, 0x377E_39F5_83B4_4868L, + /* 274 */ 0x49F0_D5C1_2979_9DA2L, 0x72AE_E439_7250_AD41L, + /* 275 */ 0x5C6D_0B31_73D8_050BL, 0x4F5A_9D47_CEE4_D891L, + /* 276 */ 0x7388_4DFD_D0CE_064EL, 0x4331_4499_C29E_0EB6L, + /* 277 */ 0x4835_30BE_A280_C3F1L, 0x09FE_CAE0_19A2_C932L, + /* 278 */ 0x5A42_7CEE_4B20_F4EDL, 0x2C7E_7D98_200B_7B7EL, + /* 279 */ 0x70D3_1C29_DDE9_3228L, 0x579E_1CFE_280E_5A5DL, + /* 280 */ 0x4683_F19A_2AB1_BF59L, 0x36C2_D21E_D908_F87BL, + /* 281 */ 0x5824_EE00_B55E_2F2FL, 0x6473_86A6_8F4B_3699L, + /* 282 */ 0x6E2E_2980_E2B5_BAFBL, 0x5D90_6850_331E_043FL, + /* 283 */ 0x44DC_D9F0_8DB1_94DDL, 0x2A7A_4132_1FF2_C2A8L, + /* 284 */ 0x5614_106C_B11D_FA14L, 0x5518_D17E_A7EF_7352L, + /* 285 */ 0x6B99_1487_DD65_7899L, 0x6A5F_05DE_51EB_5026L, + /* 286 */ 0x433F_ACD4_EA5F_6B60L, 0x127B_63AA_F333_1218L, + /* 287 */ 0x540F_980A_24F7_4638L, 0x171A_3C95_AFFF_D69EL, + /* 288 */ 0x6913_7E0C_AE35_17C6L, 0x1CE0_CBBB_1BFF_CC45L, + /* 289 */ 0x41AC_2EC7_ECE1_2EDBL, 0x720C_7F54_F17F_DFABL, + /* 290 */ 0x5217_3A79_E819_7A92L, 0x6E8F_9F2A_2DDF_D796L, + /* 291 */ 0x669D_0918_621F_D937L, 0x4A33_86F4_B957_CD7BL, + /* 292 */ 0x4022_25AF_3D53_E7C2L, 0x5E60_3458_F3D6_E06DL, + /* 293 */ 0x502A_AF1B_0CA8_E1B3L, 0x35F8_416F_30CC_9888L, + /* 294 */ 0x6435_5AE1_CFD3_1A20L, 0x2376_51CA_FCFF_BEAAL, + /* 295 */ 0x7D42_B19A_43C7_E0A8L, 0x2C53_E63D_BC3F_AE55L, + /* 296 */ 0x4E49_AF00_6A5C_EC69L, 0x1BB4_6FE6_95A7_CCF5L, + /* 297 */ 0x61DC_1AC0_84F4_2783L, 0x42A1_8BE0_3B11_C033L, + /* 298 */ 0x7A53_2170_A631_3164L, 0x3349_EED8_49D6_303FL, + /* 299 */ 0x4C73_F4E6_67DE_BEDEL, 0x600E_3547_2E25_DE28L, + /* 300 */ 0x5F90_F220_01D6_6E96L, 0x3811_C298_F9AF_55B1L, + /* 301 */ 0x7775_2EA8_024C_0A3CL, 0x0616_333F_381B_2B1EL, + /* 302 */ 0x4AA9_3D29_016F_8665L, 0x43CD_E007_8310_FAF3L, + /* 303 */ 0x5D53_8C73_41CB_67FEL, 0x74C1_5809_63D5_39AFL, + /* 304 */ 0x74A8_6F90_123E_41FEL, 0x51F1_AE0B_BCCA_881BL, + /* 305 */ 0x48E9_45BA_0B66_E93FL, 0x1337_0CC7_55FE_9511L, + /* 306 */ 0x5B23_9728_8E40_A38EL, 0x7804_CFF9_2B7E_3A55L, + /* 307 */ 0x71EC_7CF2_B1D0_CC72L, 0x5606_03F7_765D_C8EAL, + /* 308 */ 0x4733_CE17_AF22_7FC7L, 0x55C3_C27A_A9FA_9D93L, + /* 309 */ 0x5900_C19D_9AEB_1FB9L, 0x4B34_B319_5479_44F7L, + /* 310 */ 0x6F40_F205_01A5_E7A7L, 0x7E01_DFDF_A997_9635L, + /* 311 */ 0x4588_9743_2107_B0C8L, 0x7EC1_2BEB_C9FE_BDE1L, + /* 312 */ 0x56EA_BD13_E949_9CFBL, 0x1E71_76E6_BC7E_6D59L, + /* 313 */ 0x6CA5_6C58_E39C_043AL, 0x060D_D4A0_6B9E_08B0L, + /* 314 */ 0x43E7_63B7_8E41_82A4L, 0x23C8_A4E4_4342_C56EL, + /* 315 */ 0x54E1_3CA5_71D1_E34DL, 0x2CBA_CE1D_5413_76C9L, + /* 316 */ 0x6A19_8BCE_CE46_5C20L, 0x57E9_81A4_A918_547BL, + /* 317 */ 0x424F_F761_40EB_F994L, 0x36F1_F106_E9AF_34CDL, + /* 318 */ 0x52E3_F539_9126_F7F9L, 0x44AE_6D48_A41B_0201L, + /* 319 */ 0x679C_F287_F570_B5F7L, 0x75DA_089A_CD21_C281L, + /* 320 */ 0x40C2_1794_F966_71BAL, 0x79A8_4560_C035_1991L, + /* 321 */ 0x50F2_9D7A_37C0_0E29L, 0x5812_56B8_F042_5FF5L, + /* 322 */ 0x652F_44D8_C5B0_11B4L, 0x0E16_EC67_2C52_F7F2L, + /* 323 */ 0x7E7B_160E_F71C_1621L, 0x119C_A780_F767_B5EEL, + /* 324 */ 0x4F0C_EDC9_5A71_8DD4L, 0x5B01_E8B0_9AA0_D1B5L, + }; + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/DoubleToDecimalTest.java b/test/jdk/jdk/internal/math/ToDecimal/DoubleToDecimalTest.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/DoubleToDecimalTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import jdk.internal.math.DoubleToDecimalChecker; +import jdk.test.lib.RandomFactory; + +/* + * @test + * @bug 8202555 + * @author Raffaello Giulietti + * @key randomness + * + * @modules java.base/jdk.internal.math + * @library /test/lib + * @library java.base + * @build jdk.test.lib.RandomFactory + * @build java.base/jdk.internal.math.* + * @run main DoubleToDecimalTest 1_000_000 + */ +public class DoubleToDecimalTest { + + private static final int RANDOM_COUNT = 100_000; + + public static void main(String[] args) { + int count = RANDOM_COUNT; + if (args.length == 0) { + DoubleToDecimalChecker.test(count, RandomFactory.getRandom()); + return; + } + try { + count = Integer.parseInt(args[0].replace("_", "")); + } catch (NumberFormatException ignored) { + } + DoubleToDecimalChecker.test(count, RandomFactory.getRandom()); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/FloatToDecimalTest.java b/test/jdk/jdk/internal/math/ToDecimal/FloatToDecimalTest.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/FloatToDecimalTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import jdk.internal.math.FloatToDecimalChecker; +import jdk.test.lib.RandomFactory; + +/* + * @test + * @author Raffaello Giulietti + * @key randomness + * + * @modules java.base/jdk.internal.math + * @library /test/lib + * @library java.base + * @build jdk.test.lib.RandomFactory + * @build java.base/jdk.internal.math.* + * @run main FloatToDecimalTest 1_000_000 + */ +public class FloatToDecimalTest { + + private static final int RANDOM_COUNT = 100_000; + + public static void main(String[] args) { + int count = RANDOM_COUNT; + if (args.length == 0) { + FloatToDecimalChecker.test(count, RandomFactory.getRandom()); + return; + } + if (args[0].equals("all")) { + FloatToDecimalChecker.testAll(); + return; + } + if (args[0].equals("positive")) { + FloatToDecimalChecker.testPositive(); + return; + } + try { + count = Integer.parseInt(args[0].replace("_", "")); + } catch (NumberFormatException ignored) { + } + FloatToDecimalChecker.test(count, RandomFactory.getRandom()); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/MathUtilsTest.java b/test/jdk/jdk/internal/math/ToDecimal/MathUtilsTest.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/MathUtilsTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import jdk.internal.math.MathUtilsChecker; + +/* + * @test + * @author Raffaello Giulietti + * + * @modules java.base/jdk.internal.math + * @library java.base + * @build java.base/jdk.internal.math.* + * @run main MathUtilsTest + */ +public class MathUtilsTest { + + public static void main(String[] args) { + MathUtilsChecker.test(); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/BasicChecker.java b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/BasicChecker.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/BasicChecker.java @@ -0,0 +1,18 @@ +package jdk.internal.math; + +class BasicChecker { + + static final boolean FAILURE_THROWS_EXCEPTION = true; + + static void assertTrue(boolean ok, String valueName) { + if (ok) { + return; + } + String msg = valueName + " is not correct"; + if (FAILURE_THROWS_EXCEPTION) { + throw new RuntimeException(msg); + } + System.err.println(msg); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/DoubleToDecimalChecker.java b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/DoubleToDecimalChecker.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/DoubleToDecimalChecker.java @@ -0,0 +1,391 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +import java.math.BigDecimal; +import java.util.Random; + +import static java.lang.Double.*; +import static java.lang.Long.numberOfTrailingZeros; +import static java.lang.Math.scalb; +import static jdk.internal.math.DoubleToDecimal.*; +import static jdk.internal.math.MathUtils.flog10pow2; + +public class DoubleToDecimalChecker extends ToDecimalChecker { + + private double v; + private final long originalBits; + + private DoubleToDecimalChecker(double v, String s) { + super(s); + this.v = v; + originalBits = doubleToRawLongBits(v); + } + + @Override + BigDecimal toBigDecimal() { + return new BigDecimal(v); + } + + @Override + boolean recovers(BigDecimal b) { + return b.doubleValue() == v; + } + + @Override + boolean recovers(String s) { + return parseDouble(s) == v; + } + + @Override + String hexBits() { + return String.format("0x%01X__%03X__%01X_%04X_%04X_%04X", + (int) (originalBits >>> 63) & 0x1, + (int) (originalBits >>> 52) & 0x7FF, + (int) (originalBits >>> 48) & 0xF, + (int) (originalBits >>> 32) & 0xFFFF, + (int) (originalBits >>> 16) & 0xFFFF, + (int) originalBits & 0xFFFF); + } + + @Override + int minExp() { + return MIN_EXP; + } + + @Override + int maxExp() { + return MAX_EXP; + } + + @Override + int maxLen10() { + return H; + } + + @Override + boolean isZero() { + return v == 0; + } + + @Override + boolean isInfinity() { + return v == POSITIVE_INFINITY; + } + + @Override + void negate() { + v = -v; + } + + @Override + boolean isNegative() { + return originalBits < 0; + } + + @Override + boolean isNaN() { + return Double.isNaN(v); + } + + private static void toDec(double v) { +// String s = Double.toString(v); + String s = DoubleToDecimal.toString(v); + new DoubleToDecimalChecker(v, s).assertTrue(); + } + + private static void testExtremeValues() { + toDec(NEGATIVE_INFINITY); + toDec(-MAX_VALUE); + toDec(-MIN_NORMAL); + toDec(-MIN_VALUE); + toDec(-0.0); + toDec(0.0); + toDec(MIN_VALUE); + toDec(MIN_NORMAL); + toDec(MAX_VALUE); + toDec(POSITIVE_INFINITY); + toDec(NaN); + + /* + Quiet NaNs have the most significant bit of the mantissa as 1, + while signaling NaNs have it as 0. + Exercise 4 combinations of quiet/signaling NaNs and + "positive/negative" NaNs + */ + toDec(longBitsToDouble(0x7FF8_0000_0000_0001L)); + toDec(longBitsToDouble(0x7FF0_0000_0000_0001L)); + toDec(longBitsToDouble(0xFFF8_0000_0000_0001L)); + toDec(longBitsToDouble(0xFFF0_0000_0000_0001L)); + + /* + All values treated specially by Schubfach + */ + toDec(4.9E-324); + toDec(9.9E-324); + } + + /* + A few "powers of 10" are incorrectly rendered by the JDK. + The rendering is either too long or it is not the closest decimal. + */ + private static void testPowersOf10() { + for (int e = MIN_EXP; e <= MAX_EXP; ++e) { + toDec(parseDouble("1e" + e)); + } + } + + /* + Many powers of 2 are incorrectly rendered by the JDK. + The rendering is either too long or it is not the closest decimal. + */ + private static void testPowersOf2() { + for (double v = MIN_VALUE; v <= MAX_VALUE; v *= 2) { + toDec(v); + } + } + + /* + There are many doubles that are rendered incorrectly by the JDK. + While the renderings correctly round back to the original value, + they are longer than needed or are not the closest decimal to the double. + Here are just a very few examples. + */ + private static final String[] Anomalies = { + // JDK renders these, and others, with 18 digits! + "2.82879384806159E17", "1.387364135037754E18", + "1.45800632428665E17", + + // JDK renders these longer than needed. + "1.6E-322", "6.3E-322", + "7.3879E20", "2.0E23", "7.0E22", "9.2E22", + "9.5E21", "3.1E22", "5.63E21", "8.41E21", + + // JDK does not render these, and many others, as the closest. + "9.9E-324", "9.9E-323", + "1.9400994884341945E25", "3.6131332396758635E25", + "2.5138990223946153E25", + }; + + private static void testSomeAnomalies() { + for (String dec : Anomalies) { + toDec(parseDouble(dec)); + } + } + + /* + Values are from + Paxson V, "A Program for Testing IEEE Decimal-Binary Conversion" + tables 3 and 4 + */ + private static final double[] PaxsonSignificands = { + 8_511_030_020_275_656L, + 5_201_988_407_066_741L, + 6_406_892_948_269_899L, + 8_431_154_198_732_492L, + 6_475_049_196_144_587L, + 8_274_307_542_972_842L, + 5_381_065_484_265_332L, + 6_761_728_585_499_734L, + 7_976_538_478_610_756L, + 5_982_403_858_958_067L, + 5_536_995_190_630_837L, + 7_225_450_889_282_194L, + 7_225_450_889_282_194L, + 8_703_372_741_147_379L, + 8_944_262_675_275_217L, + 7_459_803_696_087_692L, + 6_080_469_016_670_379L, + 8_385_515_147_034_757L, + 7_514_216_811_389_786L, + 8_397_297_803_260_511L, + 6_733_459_239_310_543L, + 8_091_450_587_292_794L, + + 6_567_258_882_077_402L, + 6_712_731_423_444_934L, + 6_712_731_423_444_934L, + 5_298_405_411_573_037L, + 5_137_311_167_659_507L, + 6_722_280_709_661_868L, + 5_344_436_398_034_927L, + 8_369_123_604_277_281L, + 8_995_822_108_487_663L, + 8_942_832_835_564_782L, + 8_942_832_835_564_782L, + 8_942_832_835_564_782L, + 6_965_949_469_487_146L, + 6_965_949_469_487_146L, + 6_965_949_469_487_146L, + 7_487_252_720_986_826L, + 5_592_117_679_628_511L, + 8_887_055_249_355_788L, + 6_994_187_472_632_449L, + 8_797_576_579_012_143L, + 7_363_326_733_505_337L, + 8_549_497_411_294_502L, + }; + + private static final int[] PaxsonExponents = { + -342, + -824, + 237, + 72, + 99, + 726, + -456, + -57, + 376, + 377, + 93, + 710, + 709, + 117, + -1, + -707, + -381, + 721, + -828, + -345, + 202, + -473, + + 952, + 535, + 534, + -957, + -144, + 363, + -169, + -853, + -780, + -383, + -384, + -385, + -249, + -250, + -251, + 548, + 164, + 665, + 690, + 588, + 272, + -448, + }; + + private static void testPaxson() { + for (int i = 0; i < PaxsonSignificands.length; ++i) { + toDec(scalb(PaxsonSignificands[i], PaxsonExponents[i])); + } + } + + /* + Tests all integers of the form yx_xxx_000_000_000_000_000, y != 0. + These are all exact doubles. + */ + private static void testLongs() { + for (int i = 10_000; i < 100_000; ++i) { + toDec(i * 1e15); + } + } + + /* + Tests all integers up to 1_000_000. + These are all exact doubles and exercise a fast path. + */ + private static void testInts() { + for (int i = 0; i <= 1_000_000; ++i) { + toDec(i); + } + } + + /* + Random doubles over the whole range + */ + private static void testRandom(int randomCount, Random r) { + for (int i = 0; i < randomCount; ++i) { + toDec(longBitsToDouble(r.nextLong())); + } + } + + /* + Random doubles over the integer range [0, 2^52). + These are all exact doubles and exercise the fast path (except 0). + */ + private static void testRandomUnit(int randomCount, Random r) { + for (int i = 0; i < randomCount; ++i) { + toDec(r.nextLong() & (1L << P - 1)); + } + } + + /* + Random doubles over the range [0, 10^15) as "multiples" of 1e-3 + */ + private static void testRandomMilli(int randomCount, Random r) { + for (int i = 0; i < randomCount; ++i) { + toDec(r.nextLong() % 1_000_000_000_000_000_000L / 1e3); + } + } + + /* + Random doubles over the range [0, 10^15) as "multiples" of 1e-6 + */ + private static void testRandomMicro(int randomCount, Random r) { + for (int i = 0; i < randomCount; ++i) { + toDec((r.nextLong() & 0x7FFF_FFFF_FFFF_FFFFL) / 1e6); + } + } + + private static void testConstants() { + assertTrue(precision() == P, "P"); + assertTrue(flog10pow2(P) + 2 == H, "H"); + assertTrue(e(MIN_VALUE) == MIN_EXP, "MIN_EXP"); + assertTrue(e(MAX_VALUE) == MAX_EXP, "MAX_EXP"); + } + + private static int precision() { + /* + Given precision P, the floating point value 3 has the bits + 0e...e10...0 + where there are exactly P - 2 trailing zeroes. + */ + return numberOfTrailingZeros(doubleToRawLongBits(3)) + 2; + } + + public static void test(int randomCount, Random r) { + testConstants(); + testExtremeValues(); + testSomeAnomalies(); + testPowersOf2(); + testPowersOf10(); + testPaxson(); + testInts(); + testLongs(); + testRandom(randomCount, r); + testRandomUnit(randomCount, r); + testRandomMilli(randomCount, r); + testRandomMicro(randomCount, r); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/FloatToDecimalChecker.java b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/FloatToDecimalChecker.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/FloatToDecimalChecker.java @@ -0,0 +1,327 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +import java.math.BigDecimal; +import java.util.Random; + +import static java.lang.Float.*; +import static java.lang.Integer.numberOfTrailingZeros; +import static java.lang.Math.scalb; +import static jdk.internal.math.FloatToDecimal.*; +import static jdk.internal.math.MathUtils.flog10pow2; + +public class FloatToDecimalChecker extends ToDecimalChecker { + + private float v; + private final int originalBits; + + private FloatToDecimalChecker(float v, String s) { + super(s); + this.v = v; + originalBits = floatToRawIntBits(v); + } + + @Override + BigDecimal toBigDecimal() { + return new BigDecimal(v); + } + + @Override + boolean recovers(BigDecimal b) { + return b.floatValue() == v; + } + + @Override + String hexBits() { + return String.format("0x%01X__%02X__%02X_%04X", + (originalBits >>> 31) & 0x1, + (originalBits >>> 23) & 0xFF, + (originalBits >>> 16) & 0x7F, + originalBits & 0xFFFF); + } + + @Override + boolean recovers(String s) { + return parseFloat(s) == v; + } + + @Override + int minExp() { + return MIN_EXP; + } + + @Override + int maxExp() { + return MAX_EXP; + } + + @Override + int maxLen10() { + return H; + } + + @Override + boolean isZero() { + return v == 0; + } + + @Override + boolean isInfinity() { + return v == POSITIVE_INFINITY; + } + + @Override + void negate() { + v = -v; + } + + @Override + boolean isNegative() { + return originalBits < 0; + } + + @Override + boolean isNaN() { + return Float.isNaN(v); + } + + private static void toDec(float v) { +// String s = Float.toString(v); + String s = FloatToDecimal.toString(v); + new FloatToDecimalChecker(v, s).assertTrue(); + } + + /* + MIN_NORMAL is incorrectly rendered by the JDK. + */ + private static void testExtremeValues() { + toDec(NEGATIVE_INFINITY); + toDec(-MAX_VALUE); + toDec(-MIN_NORMAL); + toDec(-MIN_VALUE); + toDec(-0.0f); + toDec(0.0f); + toDec(MIN_VALUE); + toDec(MIN_NORMAL); + toDec(MAX_VALUE); + toDec(POSITIVE_INFINITY); + toDec(NaN); + + /* + Quiet NaNs have the most significant bit of the mantissa as 1, + while signaling NaNs have it as 0. + Exercise 4 combinations of quiet/signaling NaNs and + "positive/negative" NaNs. + */ + toDec(intBitsToFloat(0x7FC0_0001)); + toDec(intBitsToFloat(0x7F80_0001)); + toDec(intBitsToFloat(0xFFC0_0001)); + toDec(intBitsToFloat(0xFF80_0001)); + + /* + All values treated specially by Schubfach + */ + toDec(1.4E-45F); + toDec(2.8E-45F); + toDec(4.2E-45F); + toDec(5.6E-45F); + toDec(7.0E-45F); + toDec(8.4E-45F); + toDec(9.8E-45F); + } + + /* + A few "powers of 10" are incorrectly rendered by the JDK. + The rendering is either too long or it is not the closest decimal. + */ + private static void testPowersOf10() { + for (int e = MIN_EXP; e <= MAX_EXP; ++e) { + toDec(parseFloat("1e" + e)); + } + } + + /* + Many powers of 2 are incorrectly rendered by the JDK. + The rendering is either too long or it is not the closest decimal. + */ + private static void testPowersOf2() { + for (float v = MIN_VALUE; v <= MAX_VALUE; v *= 2) { + toDec(v); + } + } + + /* + There are many floats that are rendered incorrectly by the JDK. + While the renderings correctly round back to the original value, + they are longer than needed or are not the closest decimal to the float. + Here are just a very few examples. + */ + private static final String[] Anomalies = { + // JDK renders these longer than needed. + "1.1754944E-38", "2.2E-44", + "1.0E16", "2.0E16", "3.0E16", "5.0E16", "3.0E17", + "3.2E18", "3.7E18", "3.7E16", "3.72E17", + + // JDK does not render this as the closest. + "9.9E-44", + }; + + private static void testSomeAnomalies() { + for (String dec : Anomalies) { + toDec(parseFloat(dec)); + } + } + + /* + Values are from + Paxson V, "A Program for Testing IEEE Decimal-Binary Conversion" + tables 16 and 17 + */ + private static final float[] PaxsonSignificands = { + 12_676_506, + 15_445_013, + 13_734_123, + 12_428_269, + 12_676_506, + 15_334_037, + 11_518_287, + 12_584_953, + 15_961_084, + 14_915_817, + 10_845_484, + 16_431_059, + + 16_093_626, + 9_983_778, + 12_745_034, + 12_706_553, + 11_005_028, + 15_059_547, + 16_015_691, + 8_667_859, + 14_855_922, + 14_855_922, + 10_144_164, + 13_248_074, + }; + + private static final int[] PaxsonExponents = { + -102, + -103, + 86, + -138, + -130, + -146, + -41, + -145, + -125, + -146, + -102, + -61, + + 69, + 25, + 104, + 72, + 45, + 71, + -99, + 56, + -82, + -83, + -110, + 95, + }; + + private static void testPaxson() { + for (int i = 0; i < PaxsonSignificands.length; ++i) { + toDec(scalb(PaxsonSignificands[i], PaxsonExponents[i])); + } + } + + /* + Tests all positive integers below 2^23. + These are all exact floats and exercise the fast path. + */ + private static void testInts() { + for (int i = 1; i < 1 << P - 1; ++i) { + toDec(i); + } + } + + /* + Random floats over the whole range. + */ + private static void testRandom(int randomCount, Random r) { + for (int i = 0; i < randomCount; ++i) { + toDec(intBitsToFloat(r.nextInt())); + } + } + + private static void testConstants() { + assertTrue(precision() == P, "P"); + assertTrue(flog10pow2(P) + 2 == H, "H"); + assertTrue(e(MIN_VALUE) == MIN_EXP, "MIN_EXP"); + assertTrue(e(MAX_VALUE) == MAX_EXP, "MAX_EXP"); + } + + private static int precision() { + /* + Given precision P, the floating point value 3 has the bits + 0e...e10...0 + where there are exactly P - 2 trailing zeroes. + */ + return numberOfTrailingZeros(floatToRawIntBits(3)) + 2; + } + + /* + All, really all, 2^32 possible floats. Takes between 90 and 120 minutes. + */ + public static void testAll() { + for (long bits = Integer.MIN_VALUE; bits <= Integer.MAX_VALUE; ++bits) { + toDec(intBitsToFloat((int) bits)); + } + } + + /* + All 2^31 positive floats. + */ + public static void testPositive() { + for (long bits = 0; bits <= Integer.MAX_VALUE; ++bits) { + toDec(intBitsToFloat((int) bits)); + } + } + + public static void test(int randomCount, Random r) { + testConstants(); + testExtremeValues(); + testSomeAnomalies(); + testPowersOf2(); + testPowersOf10(); + testPaxson(); + testInts(); + testRandom(randomCount, r); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/MathUtilsChecker.java b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/MathUtilsChecker.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/MathUtilsChecker.java @@ -0,0 +1,448 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +import java.math.BigInteger; + +import static java.math.BigInteger.*; +import static jdk.internal.math.DoubleToDecimal.*; +import static jdk.internal.math.MathUtils.*; + +public class MathUtilsChecker extends BasicChecker { + + private static final BigInteger THREE = BigInteger.valueOf(3); + + /* + Let + 10^e = beta 2^r + for the unique integer r and real beta meeting + 2^125 <= beta < 2^126 + Further, let g = g1 2^63 + g0. + Checks that: + 2^62 <= g1 < 2^63, + 0 <= g0 < 2^63, + g - 1 <= beta < g, (that is, g = floor(beta) + 1) + The last predicate, after multiplying by 2^r, is equivalent to + (g - 1) 2^r <= 10^e < g 2^r + This is the predicate that will be checked in various forms. + */ + private static void testG(int e, long g1, long g0) { + // 2^62 <= g1 < 2^63, 0 <= g0 < 2^63 + assertTrue(g1 << 1 < 0 && g1 >= 0 && g0 >= 0, "g"); + + BigInteger g = valueOf(g1).shiftLeft(63).or(valueOf(g0)); + // double check that 2^125 <= g < 2^126 + assertTrue(g.signum() > 0 && g.bitLength() == 126, "g"); + + // see javadoc of MathUtils.g1(int) + int r = flog2pow10(e) - 125; + + /* + The predicate + (g - 1) 2^r <= 10^e < g 2^r + is equivalent to + g - 1 <= 10^e 2^(-r) < g + When + e >= 0 & r < 0 + all numerical subexpressions are integer-valued. This is the same as + g - 1 = 10^e 2^(-r) + */ + if (e >= 0 && r < 0) { + assertTrue( + g.subtract(ONE).compareTo(TEN.pow(e).shiftLeft(-r)) == 0, + "g"); + return; + } + + /* + The predicate + (g - 1) 2^r <= 10^e < g 2^r + is equivalent to + g 10^(-e) - 10^(-e) <= 2^(-r) < g 10^(-e) + When + e < 0 & r < 0 + all numerical subexpressions are integer-valued. + */ + if (e < 0 && r < 0) { + BigInteger pow5 = TEN.pow(-e); + BigInteger mhs = ONE.shiftLeft(-r); + BigInteger rhs = g.multiply(pow5); + assertTrue(rhs.subtract(pow5).compareTo(mhs) <= 0 && + mhs.compareTo(rhs) < 0, "g"); + return; + } + + /* + Finally, when + e >= 0 & r >= 0 + the predicate + (g - 1) 2^r <= 10^e < g 2^r + can be used straightforwardly as all numerical subexpressions are + already integer-valued. + */ + if (e >= 0) { + BigInteger mhs = TEN.pow(e); + assertTrue(g.subtract(ONE).shiftLeft(r).compareTo(mhs) <= 0 && + mhs.compareTo(g.shiftLeft(r)) < 0, "g"); + return; + } + + /* + For combinatorial reasons, the only remaining case is + e < 0 & r >= 0 + which, however, cannot arise. Indeed, the predicate + (g - 1) 2^r <= 10^e < g 2^r + implies + (g - 1) 10 <= (g - 1) 2^r 10^(-e) <= 1 + which cannot hold. + */ + assertTrue(false, "g"); + } + + /* + Verifies the soundness of the values returned by g1() and g0(). + */ + private static void testG() { + for (int e = -MAX_K; e <= -MIN_K; ++e) { + testG(e, g1(e), g0(e)); + } + } + + /* + Let + k = floor(log10(3/4 2^e)) + The method verifies that + k = flog10threeQuartersPow2(e), |e| <= 2_000 + This range amply covers all binary exponents of doubles and floats. + + The first equation above is equivalent to + 10^k <= 3 2^(e-2) < 10^(k+1) + Equality never holds. Henceforth, the predicate to check is + 10^k < 3 2^(e-2) < 10^(k+1) + This will be transformed in various ways for checking purposes. + + For integer n > 0, let further + b = len2(n) + denote its length in bits. This means exactly the same as + 2^(b-1) <= n < 2^b + */ + private static void testFlog10threeQuartersPow2() { + /* + First check the case e = 1 + */ + assertTrue(flog10threeQuartersPow2(1) == 0, + "flog10threeQuartersPow2"); + + /* + Now check the range -2_000 <= e <= 0. + By rewriting, the predicate to check is equivalent to + 3 10^(-k-1) < 2^(2-e) < 3 10^(-k) + As e <= 0, it follows that 2^(2-e) >= 4 and the right inequality + implies k < 0, so the powers of 10 are integers. + + The left inequality is equivalent to + len2(3 10^(-k-1)) <= 2 - e + and the right inequality to + 2 - e < len2(3 10^(-k)) + The original predicate is therefore equivalent to + len2(3 10^(-k-1)) <= 2 - e < len2(3 10^(-k)) + + Starting with e = 0 and decrementing until the lower bound, the code + keeps track of the two powers of 10 to avoid recomputing them. + This is easy because at each iteration k changes at most by 1. A simple + multiplication by 10 computes the next power of 10 when needed. + */ + int e = 0; + int k0 = flog10threeQuartersPow2(e); + assertTrue(k0 < 0, "flog10threeQuartersPow2"); + BigInteger l = THREE.multiply(TEN.pow(-k0 - 1)); + BigInteger u = l.multiply(TEN); + for (;;) { + assertTrue(l.bitLength() <= 2 - e && 2 - e < u.bitLength(), + "flog10threeQuartersPow2"); + if (e == -2_000) { + break; + } + --e; + int kp = flog10threeQuartersPow2(e); + assertTrue(kp <= k0, "flog10threeQuartersPow2"); + if (kp < k0) { + // k changes at most by 1 at each iteration, hence: + assertTrue(k0 - kp == 1, "flog10threeQuartersPow2"); + k0 = kp; + l = u; + u = u.multiply(TEN); + } + } + + /* + Finally, check the range 2 <= e <= 2_000. + In predicate + 10^k < 3 2^(e-2) < 10^(k+1) + the right inequality shows that k >= 0 as soon as e >= 2. + It is equivalent to + 10^k / 3 < 2^(e-2) < 10^(k+1) / 3 + Both the powers of 10 and the powers of 2 are integer-valued. + The left inequality is therefore equivalent to + floor(10^k / 3) < 2^(e-2) + and thus to + len2(floor(10^k / 3)) <= e - 2 + while the right inequality is equivalent to + 2^(e-2) <= floor(10^(k+1) / 3) + and hence to + e - 2 < len2(floor(10^(k+1) / 3)) + These are summarized as + len2(floor(10^k / 3)) <= e - 2 < len2(floor(10^(k+1) / 3)) + */ + e = 2; + k0 = flog10threeQuartersPow2(e); + assertTrue(k0 >= 0, "flog10threeQuartersPow2"); + BigInteger l10 = TEN.pow(k0); + BigInteger u10 = l10.multiply(TEN); + l = l10.divide(THREE); + u = u10.divide(THREE); + for (;;) { + assertTrue(l.bitLength() <= e - 2 && e - 2 < u.bitLength(), + "flog10threeQuartersPow2"); + if (e == 2_000) { + break; + } + ++e; + int kp = flog10threeQuartersPow2(e); + assertTrue(kp >= k0, "flog10threeQuartersPow2"); + if (kp > k0) { + // k changes at most by 1 at each iteration, hence: + assertTrue(kp - k0 == 1, "flog10threeQuartersPow2"); + k0 = kp; + u10 = u10.multiply(TEN); + l = u; + u = u10.divide(THREE); + } + } + } + + /* + Let + k = floor(log10(2^e)) + The method verifies that + k = flog10pow2(e), |e| <= 2_000 + This range amply covers all binary exponents of doubles and floats. + + The first equation above is equivalent to + 10^k <= 2^e < 10^(k+1) + Equality holds iff e = 0, implying k = 0. + Henceforth, the predicates to check are equivalent to + k = 0, if e = 0 + 10^k < 2^e < 10^(k+1), otherwise + The latter will be transformed in various ways for checking purposes. + + For integer n > 0, let further + b = len2(n) + denote its length in bits. This means exactly the same as + 2^(b-1) <= n < 2^b + */ + private static void testFlog10pow2() { + /* + First check the case e = 0 + */ + assertTrue(flog10pow2(0) == 0, "flog10pow2"); + + /* + Now check the range -2_000 <= e < 0. + By inverting all quantities, the predicate to check is equivalent to + 10^(-k-1) < 2^(-e) < 10^(-k) + As e < 0, it follows that 2^(-e) >= 2 and the right inequality + implies k < 0. + The left inequality means exactly the same as + len2(10^(-k-1)) <= -e + Similarly, the right inequality is equivalent to + -e < len2(10^(-k)) + The original predicate is therefore equivalent to + len2(10^(-k-1)) <= -e < len2(10^(-k)) + The powers of 10 are integer-valued because k < 0. + + Starting with e = -1 and decrementing towards the lower bound, the code + keeps track of the two powers of 10 so as to avoid recomputing them. + This is easy because at each iteration k changes at most by 1. A simple + multiplication by 10 computes the next power of 10 when needed. + */ + int e = -1; + int k = flog10pow2(e); + assertTrue(k < 0, "flog10pow2"); + BigInteger l = TEN.pow(-k - 1); + BigInteger u = l.multiply(TEN); + for (;;) { + assertTrue(l.bitLength() <= -e && -e < u.bitLength(), + "flog10pow2"); + if (e == -2_000) { + break; + } + --e; + int kp = flog10pow2(e); + assertTrue(kp <= k, "flog10pow2"); + if (kp < k) { + // k changes at most by 1 at each iteration, hence: + assertTrue(k - kp == 1, "flog10pow2"); + k = kp; + l = u; + u = u.multiply(TEN); + } + } + + /* + Finally, in a similar vein, check the range 0 <= e <= 2_000. + In predicate + 10^k < 2^e < 10^(k+1) + the right inequality shows that k >= 0. + The left inequality means the same as + len2(10^k) <= e + and the right inequality holds iff + e < len2(10^(k+1)) + The original predicate is thus equivalent to + len2(10^k) <= e < len2(10^(k+1)) + As k >= 0, the powers of 10 are integer-valued. + */ + e = 1; + k = flog10pow2(e); + assertTrue(k >= 0, "flog10pow2"); + l = TEN.pow(k); + u = l.multiply(TEN); + for (;;) { + assertTrue(l.bitLength() <= e && e < u.bitLength(), + "flog10pow2"); + if (e == 2_000) { + break; + } + ++e; + int kp = flog10pow2(e); + assertTrue(kp >= k, "flog10pow2"); + if (kp > k) { + // k changes at most by 1 at each iteration, hence: + assertTrue(kp - k == 1, "flog10pow2"); + k = kp; + l = u; + u = u.multiply(TEN); + } + } + } + + /* + Let + k = floor(log2(10^e)) + The method verifies that + k = flog2pow10(e), |e| <= 500 + This range amply covers all decimal exponents of doubles and floats. + + The first equation above is equivalent to + 2^k <= 10^e < 2^(k+1) + Equality holds iff e = 0, implying k = 0. + Henceforth, the equivalent predicates to check are + k = 0, if e = 0 + 2^k < 10^e < 2^(k+1), otherwise + The latter will be transformed in various ways for checking purposes. + + For integer n > 0, let further + b = len2(n) + denote its length in bits. This means exactly the same as + 2^(b-1) <= n < 2^b + */ + private static void testFlog2pow10() { + /* + First check the case e = 0 + */ + assertTrue(flog2pow10(0) == 0, "flog2pow10"); + + /* + Now check the range -500 <= e < 0. + By inverting all quantities, the predicate to check is equivalent to + 2^(-k-1) < 10^(-e) < 2^(-k) + As e < 0, this leads to 10^(-e) >= 10 and the right inequality implies + k <= -4. + The above means the same as + len2(10^(-e)) = -k + The powers of 10 are integer values since e < 0. + */ + int e = -1; + int k0 = flog2pow10(e); + assertTrue(k0 <= -4, "flog2pow10"); + BigInteger l = TEN; + for (;;) { + assertTrue(l.bitLength() == -k0, "flog2pow10"); + if (e == -500) { + break; + } + --e; + k0 = flog2pow10(e); + l = l.multiply(TEN); + } + + /* + Finally check the range 0 < e <= 500. + From the predicate + 2^k < 10^e < 2^(k+1) + as e > 0, it follows that 10^e >= 10 and the right inequality implies + k >= 3. + The above means the same as + len2(10^e) = k + 1 + The powers of 10 are all integer valued, as e > 0. + */ + e = 1; + k0 = flog2pow10(e); + assertTrue(k0 >= 3, "flog2pow10"); + l = TEN; + for (;;) { + assertTrue(l.bitLength() == k0 + 1, "flog2pow10"); + if (e == 500) { + break; + } + ++e; + k0 = flog2pow10(e); + l = l.multiply(TEN); + } + } + + private static void testConstants() { + int qMin = (-1 << Double.SIZE - P - 1) - P + 3; + assertTrue(flog10pow2(qMin) == MIN_K, "MIN_K"); + int qMax = (1 << Double.SIZE - P - 1) - P; + assertTrue(flog10pow2(qMax) == MAX_K, "MAX_K"); + } + + private static void testPow10() { + int e = 0; + long pow = 1; + for (; e <= H; e += 1, pow *= 10) { + assertTrue(pow == pow10(e), "pow10"); + } + } + + public static void test() { + testFlog10pow2(); + testFlog10threeQuartersPow2(); + testFlog2pow10(); + testPow10(); + testConstants(); + testG(); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/ToDecimalChecker.java b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/ToDecimalChecker.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/ToDecimalChecker.java @@ -0,0 +1,399 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +import java.io.IOException; +import java.io.StringReader; +import java.math.BigDecimal; +import java.math.BigInteger; + +/* +A checker for the Javadoc specification. +It just relies on straightforward use of (expensive) BigDecimal arithmetic, +not optimized at all. + */ +abstract class ToDecimalChecker extends BasicChecker { + + // The string to check + private final String s; + + // The decimal parsed from s is c 10^q + private long c; + private int q; + + // The number of digits parsed from s: 10^(len10-1) <= c < 10^len10 + private int len10; + + ToDecimalChecker(String s) { + this.s = s; + } + + /* + Returns e be such that 10^(e-1) <= c 2^q < 10^e. + */ + static int e(double v) { + // log10(v) + 1 is a first good approximation of e + int e = (int) Math.floor(Math.log10(v)) + 1; + + // Full precision search for e such that 10^(e-1) <= c 2^q < 10^e. + BigDecimal bv = new BigDecimal(v); + BigDecimal low = new BigDecimal(BigInteger.ONE, -(e - 1)); + while (low.compareTo(bv) > 0) { + e -= 1; + low = new BigDecimal(BigInteger.ONE, -(e - 1)); + } + BigDecimal high = new BigDecimal(BigInteger.ONE, -e); + while (bv.compareTo(high) >= 0) { + e += 1; + high = new BigDecimal(BigInteger.ONE, -e); + } + return e; + } + + void assertTrue() { + if (isOK()) { + return; + } + String msg = "toString applied to the bits " + + hexBits() + + " returns " + + "\"" + s + "\"" + + ", which is not correct according to the specification."; + if (FAILURE_THROWS_EXCEPTION) { + throw new RuntimeException(msg); + } + System.err.println(msg); + } + + /* + Returns whether s syntactically meets the expected output of + toString. It is restricted to finite positive outputs. + It is an unusually long method but rather straightforward, too. + Many conditionals could be merged, but KISS here. + */ + private boolean parse(String t) { + try { + // first determine interesting boundaries in the string + StringReader r = new StringReader(t); + int ch = r.read(); + + int i = 0; + while (ch == '0') { + ++i; + ch = r.read(); + } + // i is just after zeroes starting the integer + + int p = i; + while ('0' <= ch && ch <= '9') { + c = 10 * c + (ch - '0'); + if (c < 0) { + return false; + } + ++len10; + ++p; + ch = r.read(); + } + // p is just after digits ending the integer + + int fz = p; + if (ch == '.') { + ++fz; + ch = r.read(); + } + // fz is just after a decimal '.' + + int f = fz; + while (ch == '0') { + c = 10 * c + (ch - '0'); + if (c < 0) { + return false; + } + ++len10; + ++f; + ch = r.read(); + } + // f is just after zeroes starting the fraction + + if (c == 0) { + len10 = 0; + } + int x = f; + while ('0' <= ch && ch <= '9') { + c = 10 * c + (ch - '0'); + if (c < 0) { + return false; + } + ++len10; + ++x; + ch = r.read(); + } + // x is just after digits ending the fraction + + int g = x; + if (ch == 'E') { + ++g; + ch = r.read(); + } + // g is just after an exponent indicator 'E' + + int ez = g; + if (ch == '-') { + ++ez; + ch = r.read(); + } + // ez is just after a '-' sign in the exponent + + int e = ez; + while (ch == '0') { + ++e; + ch = r.read(); + } + // e is just after zeroes starting the exponent + + int z = e; + while ('0' <= ch && ch <= '9') { + q = 10 * q + (ch - '0'); + if (q < 0) { + return false; + } + ++z; + ch = r.read(); + } + // z is just after digits ending the exponent + + // No other char after the number + if (z != t.length()) { + return false; + } + + // The integer must be present + if (p == 0) { + return false; + } + + // The decimal '.' must be present + if (fz == p) { + return false; + } + + // The fraction must be present + if (x == fz) { + return false; + } + + // The fraction is not 0 or it consists of exactly one 0 + if (f == x && f - fz > 1) { + return false; + } + + // Plain notation, no exponent + if (x == z) { + // At most one 0 starting the integer + if (i > 1) { + return false; + } + + // If the integer is 0, at most 2 zeroes start the fraction + if (i == 1 && f - fz > 2) { + return false; + } + + // The integer cannot have more than 7 digits + if (p > 7) { + return false; + } + + q = fz - x; + + // OK for plain notation + return true; + } + + // Computerized scientific notation + + // The integer has exactly one nonzero digit + if (i != 0 || p != 1) { + return false; + } + + // + // There must be an exponent indicator + if (x == g) { + return false; + } + + // There must be an exponent + if (ez == z) { + return false; + } + + // The exponent must not start with zeroes + if (ez != e) { + return false; + } + + if (g != ez) { + q = -q; + } + + // The exponent must not lie in [-3, 7) + if (-3 <= q && q < 7) { + return false; + } + + q += fz - x; + + // OK for computerized scientific notation + return true; + } catch (IOException ex) { + // An IOException on a StringReader??? Please... + return false; + } + } + + private boolean isOK() { + if (isNaN()) { + return s.equals("NaN"); + } + String t = s; + if (isNegative()) { + if (s.isEmpty() || s.charAt(0) != '-') { + return false; + } + negate(); + t = s.substring(1); + } + if (isInfinity()) { + return t.equals("Infinity"); + } + if (isZero()) { + return t.equals("0.0"); + } + if (!parse(t)) { + return false; + } + if (len10 < 2) { + c *= 10; + q -= 1; + len10 += 1; + } + if (2 > len10 || len10 > maxLen10()) { + return false; + } + + // The exponent is bounded + if (minExp() > q + len10 || q + len10 > maxExp()) { + return false; + } + + // s must recover v + try { + if (!recovers(t)) { + return false; + } + } catch (NumberFormatException e) { + return false; + } + + // Get rid of trailing zeroes, still ensuring at least 2 digits + while (len10 > 2 && c % 10 == 0) { + c /= 10; + q += 1; + len10 -= 1; + } + + if (len10 > 2) { + // Try with a shorter number less than v... + if (recovers(BigDecimal.valueOf(c / 10, -q - 1))) { + return false; + } + + // ... and with a shorter number greater than v + if (recovers(BigDecimal.valueOf(c / 10 + 1, -q - 1))) { + return false; + } + } + + // Try with the decimal predecessor... + BigDecimal dp = c == 10 ? + BigDecimal.valueOf(99, -q + 1) : + BigDecimal.valueOf(c - 1, -q); + if (recovers(dp)) { + BigDecimal bv = toBigDecimal(); + BigDecimal deltav = bv.subtract(BigDecimal.valueOf(c, -q)); + if (deltav.signum() >= 0) { + return true; + } + BigDecimal delta = dp.subtract(bv); + if (delta.signum() >= 0) { + return false; + } + int cmp = deltav.compareTo(delta); + return cmp > 0 || cmp == 0 && (c & 0x1) == 0; + } + + // ... and with the decimal successor + BigDecimal ds = BigDecimal.valueOf(c + 1, -q); + if (recovers(ds)) { + BigDecimal bv = toBigDecimal(); + BigDecimal deltav = bv.subtract(BigDecimal.valueOf(c, -q)); + if (deltav.signum() <= 0) { + return true; + } + BigDecimal delta = ds.subtract(bv); + if (delta.signum() <= 0) { + return false; + } + int cmp = deltav.compareTo(delta); + return cmp < 0 || cmp == 0 && (c & 0x1) == 0; + } + + return true; + } + + abstract BigDecimal toBigDecimal(); + + abstract boolean recovers(BigDecimal b); + + abstract boolean recovers(String s); + + abstract String hexBits(); + + abstract int minExp(); + + abstract int maxExp(); + + abstract int maxLen10(); + + abstract boolean isZero(); + + abstract boolean isInfinity(); + + abstract void negate(); + + abstract boolean isNegative(); + + abstract boolean isNaN(); + +} -------------- next part -------------- A non-text attachment was scrubbed... Name: JDK-4511638.patch Type: text/x-diff Size: 164465 bytes Desc: not available URL: From goetz.lindenmaier at sap.com Wed Apr 3 15:55:29 2019 From: goetz.lindenmaier at sap.com (Lindenmaier, Goetz) Date: Wed, 3 Apr 2019 15:55:29 +0000 Subject: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null. In-Reply-To: <13d21753-689e-547e-a0c7-9dbf9c9bee7f@oracle.com> References: <7c4b0bc27961471e91195bef9e767226@sap.com> <5c445ea9-24fb-0007-78df-41b94aadde2a@oracle.com> <8d1cc0b0-4a01-4564-73a9-4c635bfbfbaf@oracle.com> <01361236-c046-0cac-e09d-be59ea6499e0@oracle.com> <2d38e96dcd214dd091f4d79d2a9e71e3@sap.com> <440e685b-b528-056d-385f-9dc010d65e97@oracle.com> <7189ff5f-a73f-5109-1d6b-aa8a2635543a@oracle.com> <13d21753-689e-547e-a0c7-9dbf9c9bee7f@oracle.com> Message-ID: Hi Maurizio, I put your java PoC into a webrev, and added some tests: http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/06-java-Maurizio/ Please have a look at NullPointerExceptionTestMini4.java. It is failing, as the class does not reside in a file. Do you have an idea how to fix this? Further, I extended the implementation to cover all necessary bytecodes. I had hoped it would print a message on each test case in NullPointerExceptionTest. But it seems to lose track of the byte code index at some point if the method gets bigger. I have an idea how to fix this, though, so I'm not concerned about that. I'm currently looking at how to identify hidden frames... Best regards, Goetz. > -----Original Message----- > From: Maurizio Cimadamore > Sent: Freitag, 15. M?rz 2019 12:33 > To: Lindenmaier, Goetz ; Mandy Chung > ; Roger Riggs > Cc: Java Core Libs ; hotspot-runtime- > dev at openjdk.java.net > Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException > describing what is null. > > Hi Goetz, > please find the attached ASM-based patch. It is just a PoC, as such it > does not provide as fine-grained messages as the one discussed in the > RFE/JEP, but can be enhanced to cover custom debugging attribute, I believe. > > When running this: > > Object o = null; > o.toString(); > > you get: > > Exception in thread "main" java.lang.NullPointerException: attempt to > dereference 'null' when calling method 'toString' > ??? at org.oracle.npe.NPEHandler.main(NPEHandler.java:103) > > While when running this: > > Foo foo = null; > int y = foo.x; > > You get this: > > Exception in thread "main" java.lang.NullPointerException: attempt to > dereference 'null' when accessing field 'x' > ??? at org.oracle.npe.NPEHandler.main(NPEHandler.java:105) > > One problem I had is that ASM provides no way to get the instruction > given a program counter - which means we have to scan all the bytecodes > and update the sizes as we go along, and, ASM unfortunately doesn?t > expose opcode sizes either. A more robust solution would be to have a > big switch which returned the opcode size of any given opcode. Also, > accessing to StackWalker API on exception creation might not be > desirable in terms of performances, so this might be one of these area > where some VM help could be beneficial. Another problem is that we > cannot distinguish between user-generated exceptions (e.g. `throw new > NullPointerException`) and genuine NPE issued by the VM. > > But I guess the upshot is that it works to leave all the gory detail of > bytecode grovelling to a bytecode API - if the logic is applied lazily, > then the impact on performances should be minimal, and the solution more > maintainable longer term. > > Cheers > Maurizio > > On 15/03/2019 07:59, Lindenmaier, Goetz wrote: > > Yes, it would be nice if you shared that. From brian.goetz at oracle.com Wed Apr 3 19:03:37 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 3 Apr 2019 15:03:37 -0400 Subject: [PATCH] Some improvements for java.lang.Class In-Reply-To: <10151351553631340@myt6-fe24916a5562.qloud-c.yandex.net> References: <2796501552936166@myt6-add70abb4f02.qloud-c.yandex.net> <352521553106953@myt5-184376c2d7f8.qloud-c.yandex.net> <1a181b47-e392-c1f7-1ecc-2cf1ab5cd4d2@gmail.com> <10151351553631340@myt6-fe24916a5562.qloud-c.yandex.net> Message-ID: <7DEC01F5-AD44-4E50-BBEE-F493AB63583B@oracle.com> I agree that getting rid of the append(concatenation) is a good move regardless; that?s just wasteful movement. The rest of the patch seems harmless. As to applying the refactor more broadly, there?s a risk of recreating the ?append(concatenation)? problem, where the concatenation is hidden inside the call to repeat(). A loop over append() is likely to be more performant than append(s.repeat()), even those the latter is more abstract and harder to get wrong. If you?re willing to take the auto-refactor result and hand-edit it to eliminate the cases where we?d create new append(concat) situations, I?d be supportive of that as well. > On Mar 26, 2019, at 4:15 PM, ?????? ??????? wrote: > > Hello Peter, > > I was unaware of mentioned detail (thank you a lot for pointing that out, it made me read the whole JEP280 again) so I've rebenchmarked my changes compiled with -XDstringConcat=inline. > > 1) as of Class::getTypeName for Object[] it turned out, that String::repeat performs slightly better: > > Benchmark Mode Cnt Score Error Units > > getTypeName_patched avgt 25 36,676 ? 3,559 ns/op > getTypeName avgt 25 39,083 ? 1,737 ns/op > > getTypeName_patched:?gc.alloc.rate.norm avgt 25 152,000 ? 0,001 B/op > getTypeName:?gc.alloc.rate.norm avgt 25 152,000 ? 0,001 B/op > > > But for Object[][] situation is the opposite: > > Mode Cnt Score Error Units > > getTypeName_patched avgt 50 47,045 ? 0,455 ns/op > getTypeName avgt 50 40,536 ? 0,196 ns/op > > getTypeName_patched:?gc.alloc.rate.norm avgt 50 176,000 ? 0,001 B/op > getTypeName:?gc.alloc.rate.norm avgt 50 152,000 ? 0,001 B/op > > > 2) as of Class::methodToString patched version clearly wins: > > methodToString_1arg avgt 50 238,476 ? 1,641 ns/op > methodToString_1arg_patched avgt 50 197,900 ? 5,824 ns/op > > methodToString_1arg:?gc.alloc.rate.norm avgt 50 1209,600 ? 6,401 B/op > methodToString_1arg_patched:?gc.alloc.rate.norm avgt 50 936,000 ? 0,001 B/op > > methodToString_noArgs avgt 50 224,054 ? 1,840 ns/op > methodToString_noArgs_patched avgt 50 78,195 ? 0,418 ns/op > > methodToString_noArgs:?gc.alloc.rate.norm avgt 50 1131,200 ? 7,839 B/op > methodToString_noArgs_patched:?gc.alloc.rate.norm avgt 50 408,000 ? 0,001 B/op > > > As Brian suggested I've separated the changes. The patch attached contains only the changes for Class::methodToString. They are obviously helpful as they rid concatenation as argument of StringBuilder::append call (obvious antipattern to me) and skip Stream creation for empty array. > > String::repeat obviously requires more investigation, it might turn out we don't need it in java.base in majority of use cases or in all of them. > > Regards, > Sergei Tsypanov > > > > 21.03.2019, 00:56, "Peter Levart" : >> Hi Sergei, >> >> I don't know if you are aware that the new invokedynamic based >> translation of string concatenation expressions introduced in JDK 9 >> (http://openjdk.java.net/jeps/280) only applies to code outside >> java.base module. java.base module is still compiled with old-style >> StringBuilder based translation of string concatenation expressions >> because of bootstraping issues. >> >> If your benchmarks bellow are compiled with option >> -XDstringConcat=inline to disable JEP280 translation (as java.base >> module is), then it's OK. Else you are not benchmarking the right >> translation of the code as you intend to change the code in java.base >> module. >> >> Regards, Peter >> >> On 3/20/19 7:35 PM, ?????? ??????? wrote: >>> I had a brief conversation with Brian Goetz which has left off the mailing list for some reason. Here's the text: >>> --------------------------- >>> Brian: >>> >>> These enhancements seem reasonable; these are exactly the cases that String::repeat was intended for. (This is a ?is this a reasonable idea? review, not a code review.). >>> Have you looked for other places where similar transformations could be done? >>> >>> --------------------------- >>> Me: >>> >>> Hello, >>> after I had realized that looped StringBuilder::append calls can sometimes be replaced with String::repeat I requested corresponding inspection in IDEA issue tracker. >>> Using the inspection I?ve found 129 similar warnings in jdk13 repo. >>> Some of them are very promising, e.g. BigDecimal:: toPlainString where currently we have >>> >>>> int trailingZeros = checkScaleNonZero((-(long)scale)); >>>> StringBuilder buf; >>>> if(intCompact!=INFLATED) { >>>> buf = new StringBuilder(20+trailingZeros); >>>> buf.append(intCompact); >>>> } else { >>>> String str = intVal.toString(); >>>> buf = new StringBuilder(str.length()+trailingZeros); >>>> buf.append(str); >>>> } >>>> for (int i = 0; i < trailingZeros; i++) { >>>> buf.append('0'); >>>> } >>>> return buf.toString(); >>> which in fact can be simplified to >>> >>>> int trailingZeros = checkScaleNonZero((-(long)scale)); >>>> if(intCompact!=INFLATED) { >>>> return intCompact + "0".repeat(trailingZeros); >>>> } else { >>>> return intVal.toString() + "0".repeat(trailingZeros); >>>> } >>> The second solution is not only shorter and more simple but it likely to be significantly faster and memory-saving. >>> BTW, your reply to original message for some reason is missing from web-view. >>> >>> --------------------------- >>> Brian: >>> >>> Cool. Note that replacing append() calls with repeat is not necessarily a win for anything other than code compactness; String::repeat will create a new string, which will then get appended to another StrinBuilder. So when used correctly (such as presized StringBuilders) appending in a loop is probably just as fast (look at the implementation of String::repeat.). >>> >>>> if(intCompact!=INFLATED) { >>>> return intCompact + "0".repeat(trailingZeros); >>>> } else { >>>> return intVal.toString() + "0".repeat(trailingZeros); >>>> } >>> Which can be further simplified to >>> >>>> ((intCompact != INFLATED) ? intCompact : intVal.toString) + ?0?.repeat(trailingZeros); >>> >>> The second solution is not only shorter and more simple but it likely to be significantly faster and memory-saving. >>> I like short and simple. I am questioning the ?faster and memory saving.? That should be validated. >>> >>> --------------------------- >>> Me: >>> >>> I think optimizations provided by JEP 280 allow compiler to optimize String concatenation executed with '+' by using StringBuilder of exact size (when the size of all components is known, like in our case). >>> >>> I've checked this with benchmark >>> >>>> @State(Scope.Thread) >>>> @BenchmarkMode(Mode.AverageTime) >>>> @OutputTimeUnit(TimeUnit.NANOSECONDS) >>>> @Fork(jvmArgsAppend = {"-Xms2g", "-Xmx2g"}) >>>> public class ConcatBenchmark { >>>> >>>> @Param({"1", "2", "5", "8"}) >>>> private int trailingZeros; >>>> >>>> private final long intCompact = 1L; >>>> >>>> @Benchmark >>>> public String stringBuilder() { >>>> StringBuilder buf; >>>> buf = new StringBuilder(20 + trailingZeros); >>>> buf.append(intCompact); >>>> for (int i = 0; i < trailingZeros; i++) { >>>> buf.append('0'); >>>> } >>>> return buf.toString(); >>>> } >>>> @Benchmark >>>> public String stringRepeat() { >>>> return intCompact + "0".repeat(trailingZeros); >>>> } >>>> } >>> Results: >>> trailingZeros Mode Cnt Score Error Units >>> stringBuilder 1 avgt 15 17,683 ? 0,664 ns/op >>> stringRepeat 1 avgt 15 9,052 ? 0,042 ns/op >>> >>> stringBuilder 2 avgt 15 19,053 ? 1,206 ns/op >>> stringRepeat 2 avgt 15 15,864 ? 1,331 ns/op >>> >>> stringBuilder 5 avgt 15 25,839 ? 2,256 ns/op >>> stringRepeat 5 avgt 15 19,290 ? 1,685 ns/op >>> >>> stringBuilder 8 avgt 15 26,488 ? 0,371 ns/op >>> stringRepeat 8 avgt 15 19,420 ? 1,593 ns/op >>> >>> stringBuilder:?gc.alloc.rate.norm 1 avgt 15 88,000 ? 0,001 B/op >>> stringRepeat:?gc.alloc.rate.norm 1 avgt 15 48,000 ? 0,001 B/op >>> >>> stringBuilder:?gc.alloc.rate.norm 2 avgt 15 88,000 ? 0,001 B/op >>> stringRepeat:?gc.alloc.rate.norm 2 avgt 15 72,000 ? 0,001 B/op >>> >>> stringBuilder:?gc.alloc.rate.norm 5 avgt 15 96,000 ? 0,001 B/op >>> stringRepeat:?gc.alloc.rate.norm 5 avgt 15 72,000 ? 0,001 B/op >>> >>> stringBuilder:?gc.alloc.rate.norm 8 avgt 15 104,000 ? 0,001 B/op >>> stringRepeat:?gc.alloc.rate.norm 8 avgt 15 80,000 ? 0,001 B/op >>> >>> I think this is a useful optimization, so we should use String::repeat where possible. >>> >>> --------------------------- >>> Brian: >>> >>> My recommendation is to split your patch into two. The first is the straightforward ?replace loop with repeat? refactoring, which can be mechanically generated by the IDE. Here, you should examine each site to ensure that the transform seems sensible given the context. The second can then be additional hand-refactoring opportunities exposed by the first. The benefit of splitting it this way is that reviewing the first is far easier when you can say all the changes are mechanical. >>> >>> (Somehow this fell off the list; feel free to bring it back.) >>> >>> 18.03.2019, 21:13, "?????? ???????" : >>>> Hi, >>>> >>>> I have an enhancement proposal for java.lang.Class.methodToString and java.lang.Class.getTypeName. >>>> >>>> First one is used when NoSuchMethodException is thrown from Class::getMethod which is in turn widely used in Spring Framework and often throws. >>>> >>>> In current implementation we have 2 major problems: >>>> >>>> - we create stream for the case when argTypes is not null but empty (which happens e. g. when Class::getMethod is called without vararg and throws) >>>> - we have torn StringBuilder::append chain >>>> >>>> I?ve modified the method to skip creation of Stream for empty array and used separate StringBuilder for each case. Latter allowed to rid SB completely and use invokedynamic-based concatenation. >>>> >>>> I?ve compared both approaches for 2 cases: >>>> >>>> 1) argTypes is empty >>>> 2) argTypes.length == 1 >>>> >>>> Benchmark Mode Cnt Score Error Units >>>> >>>> methodToString_noArgs avgt 25 170,986 ? 5,708 ns/op >>>> methodToString_noArgs_patched avgt 25 26,883 ? 2,906 ns/op >>>> >>>> methodToString_1arg avgt 25 183,012 ? 0,701 ns/op >>>> methodToString_1arg_patched avgt 25 112,784 ? 0,920 ns/op >>>> >>>> methodToString_noArgs:?gc.alloc.rate.norm avgt 25 881,600 ? 9,786 B/op >>>> methodToString_noArgs_patched:?gc.alloc.rate.norm avgt 25 128,000 ? 0,001 B/op >>>> >>>> methodToString_1arg:?gc.alloc.rate.norm avgt 25 960,000 ? 0,001 B/op >>>> methodToString_1arg_patched:?gc.alloc.rate.norm avgt 25 552,000 ? 0,001 B/op >>>> >>>> We have the same problem regarding misusage of StringBuilder in Class:: getTypeName: >>>> >>>> StringBuilder sb = new StringBuilder(); >>>> sb.append(cl.getName()); >>>> for (int i = 0; i < dimensions; i++) { >>>> sb.append("[]"); >>>> } >>>> return sb.toString(); >>>> >>>> I suggest to use String::repeat instead of the loop: this again allows to get rid of StringBuilder and replace mentioned code with >>>> >>>> return cl.getName() + "[]".repeat(dimensions); >>>> >>>> Here are benchmark results executed for type Object[].class: >>>> >>>> Mode Cnt Score Error Units >>>> getTypeName_patched avgt 25 16,037 ? 0,431 ns/op >>>> getTypeName_patched:?gc.alloc.rate.norm avgt 25 64,000 ? 0,001 B/op >>>> >>>> getTypeName avgt 25 34,274 ? 1,432 ns/op >>>> getTypeName:?gc.alloc.rate.norm avgt 25 152,000 ? 0,001 B/op >>>> >>>> Regards, >>>> Sergei Tsypanov > From semyon.sadetsky at oracle.com Wed Apr 3 19:16:24 2019 From: semyon.sadetsky at oracle.com (semyon.sadetsky at oracle.com) Date: Wed, 3 Apr 2019 12:16:24 -0700 Subject: RFR: JDK-8208652: JPackageCreateInstallerFileAssociationsTest.java fails on Mac. Message-ID: Hello, bug: https://bugs.openjdk.java.net/browse/JDK-8208652 webrev: http://cr.openjdk.java.net/~ssadetsky/8208652/webrev.00 It is a fix for a test issue on Mac. Unlikely other platforms Mac platform sends the file path to open in a special OS OpenFile event the application should handle. The test application was modified to handle this event. --Semyon From alexander.matveev at oracle.com Wed Apr 3 21:21:29 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Wed, 3 Apr 2019 14:21:29 -0700 Subject: RFR: JDK-8208652: JPackageCreateInstallerFileAssociationsTest.java fails on Mac. In-Reply-To: References: Message-ID: Hi Semyon, Looks good. I assume you did run all tests on all platforms, since it is shared code for most tests. Thanks, Alexander On 4/3/2019 12:16 PM, semyon.sadetsky at oracle.com wrote: > Hello, > > bug: https://bugs.openjdk.java.net/browse/JDK-8208652 > > webrev: http://cr.openjdk.java.net/~ssadetsky/8208652/webrev.00 > > It is a fix for a test issue on Mac. Unlikely other platforms Mac > platform sends the file path to open in a special OS OpenFile event > the application should handle. The test application was modified to > handle this event. > > --Semyon > From semyon.sadetsky at oracle.com Wed Apr 3 21:30:07 2019 From: semyon.sadetsky at oracle.com (semyon.sadetsky at oracle.com) Date: Wed, 3 Apr 2019 14:30:07 -0700 Subject: RFR: JDK-8221876:[macOS] JPackage install takes long time Message-ID: <7584aae9-dbfd-a31b-f5c5-cf2f75c1b5b0@oracle.com> Hello, bug: https://bugs.openjdk.java.net/browse/JDK-8221876 webrev: http://cr.openjdk.java.net/~ssadetsky/8221876/webrev.00/ The fix eliminate delay in install which is caused by postinstall script introduced in 8215241 when it set permissions for large number of files. Actually setting permissions to the installation folder is sufficient. --Semyon From alexander.matveev at oracle.com Wed Apr 3 22:19:33 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Wed, 3 Apr 2019 15:19:33 -0700 Subject: RFR: JDK-8221876:[macOS] JPackage install takes long time In-Reply-To: <7584aae9-dbfd-a31b-f5c5-cf2f75c1b5b0@oracle.com> References: <7584aae9-dbfd-a31b-f5c5-cf2f75c1b5b0@oracle.com> Message-ID: <762db0cb-fc4a-de6b-c6d5-3f49c8ed2ad6@oracle.com> Hi Semyon, Looks good. Thanks, Alexander On 4/3/2019 2:30 PM, semyon.sadetsky at oracle.com wrote: > Hello, > > bug: https://bugs.openjdk.java.net/browse/JDK-8221876 > > webrev: http://cr.openjdk.java.net/~ssadetsky/8221876/webrev.00/ > > The fix eliminate delay in install which is caused by postinstall > script introduced in 8215241 when it set permissions for large number > of files. Actually setting permissions to? the installation folder is > sufficient. > > --Semyon > From brian.burkhalter at oracle.com Wed Apr 3 23:46:28 2019 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 3 Apr 2019 16:46:28 -0700 Subject: [PATCH] 4511638: Double.toString(double) sometimes produces incorrect results In-Reply-To: References: Message-ID: <4F722010-2DC8-40FB-97BA-5A69500810A7@oracle.com> Hi Raffaello, et. al. > On Apr 3, 2019, at 7:43 AM, Raffaello Giulietti wrote: > > in this patch there are additional white-box tests against critical package private entities in the jdk.internal.math classes. In particular the class jdk.internal.math.MathUtils is thoroughly tested. > > Also, the tag @key randomness is now used along jdk.test.lib.RandomFactory. Good. > To run the tests > make test TEST="jtreg:test/jdk/jdk/internal/math/ToDecimal? As a note to anyone else running these, I configured my OpenJDK build as bash ./configure --with-jtreg=$JTREG_HOME where $JTREG_HOME is the location of the unpacked jtreg archive. The tests passed, as expected: ============================== Test summary ============================== TEST TOTAL PASS FAIL ERROR jtreg:test/jdk/jdk/internal/math/ToDecimal 3 3 0 0 ============================== TEST SUCCESS > Brian Burkhalter, my sponsor, will soon publish the patch in webrev form. Done [1]. > Of course, if anybody would like to step forward as a reviewer I'll be glad to help. Any reviews would of course be most welcome, both of the patch itself, and of the CSR [2], provided for the latter one has a JBS login. Thanks, Brian [1] http://cr.openjdk.java.net/~bpb/4511638/webrev.02/ [2] https://bugs.openjdk.java.net/browse/JDK-8202555 From kustaa.nyholm at sparetimelabs.com Thu Apr 4 05:51:19 2019 From: kustaa.nyholm at sparetimelabs.com (Kustaa Nyholm) Date: Thu, 4 Apr 2019 08:51:19 +0300 Subject: Robot.mouseMove() in macOS Mojave Message-ID: <6A3A3D0E-2145-4530-8604-C2E96F875DC1@sparetimelabs.com> Hi, I've got an application where zooming with the scroll wheel on the mouse will also center the mouse on the screen (well window actually). This has worked since day one for some 15 years. The mouse centring is implemented with Robot.mouseMove() method. This morning I received a message from a beta tester that my latest build fails to center the cursor on macOS Mojave. I've not investigated this further except to check that it works for me on High Sierra. So I'm canvassing here to see if this is a know issue or information to the contrary. cheers Kusti From david.holmes at oracle.com Thu Apr 4 05:56:48 2019 From: david.holmes at oracle.com (David Holmes) Date: Thu, 4 Apr 2019 15:56:48 +1000 Subject: Robot.mouseMove() in macOS Mojave In-Reply-To: <6A3A3D0E-2145-4530-8604-C2E96F875DC1@sparetimelabs.com> References: <6A3A3D0E-2145-4530-8604-C2E96F875DC1@sparetimelabs.com> Message-ID: <40238b95-6920-93d8-f363-2f96a6b4b9d9@oracle.com> Hi Kusti, The folks on swing-dev or awt-dev are probably the ones most likely to be able to assist. Cheers, David On 4/04/2019 3:51 pm, Kustaa Nyholm wrote: > Hi, > > > I've got an application where zooming with the scroll wheel on the mouse will also center the mouse on the screen (well window actually). > This has worked since day one for some 15 years. > > The mouse centring is implemented with Robot.mouseMove() method. > > This morning I received a message from a beta tester that my latest build fails to center the cursor on macOS Mojave. > > I've not investigated this further except to check that it works for me on High Sierra. > > So I'm canvassing here to see if this is a know issue or information to the contrary. > > cheers Kusti > From philip.race at oracle.com Thu Apr 4 06:09:49 2019 From: philip.race at oracle.com (Philip Race) Date: Wed, 03 Apr 2019 23:09:49 -0700 Subject: Robot.mouseMove() in macOS Mojave In-Reply-To: <40238b95-6920-93d8-f363-2f96a6b4b9d9@oracle.com> References: <6A3A3D0E-2145-4530-8604-C2E96F875DC1@sparetimelabs.com> <40238b95-6920-93d8-f363-2f96a6b4b9d9@oracle.com> Message-ID: <5CA59FAD.60901@oracle.com> awt-dev. But try including the exact jdk version + a test case when you do since I am not sure that exact issue has been seen. Problems with needing to allow accessibility is the mojave specific issue I can recall. -phil. On 4/3/19, 10:56 PM, David Holmes wrote: > Hi Kusti, > > The folks on swing-dev or awt-dev are probably the ones most likely to > be able to assist. > > Cheers, > David > > On 4/04/2019 3:51 pm, Kustaa Nyholm wrote: >> Hi, >> >> >> I've got an application where zooming with the scroll wheel on the >> mouse will also center the mouse on the screen (well window actually). >> This has worked since day one for some 15 years. >> >> The mouse centring is implemented with Robot.mouseMove() method. >> >> This morning I received a message from a beta tester that my latest >> build fails to center the cursor on macOS Mojave. >> >> I've not investigated this further except to check that it works for >> me on High Sierra. >> >> So I'm canvassing here to see if this is a know issue or information >> to the contrary. >> >> cheers Kusti >> From kustaa.nyholm at sparetimelabs.com Thu Apr 4 06:25:37 2019 From: kustaa.nyholm at sparetimelabs.com (Kustaa Nyholm) Date: Thu, 4 Apr 2019 09:25:37 +0300 Subject: The application requires 10.13 or later. Message-ID: <591325B0-7411-4329-90CE-EF2083CAF551@sparetimelabs.com> Hi, last night I released a new version of my app and one of the testers reported he gets a dialog that says: "You can't use this version of the application with this version of OS X. You havew OS X 10.11.6. The application requires 10.13 or later." Now this is a first version of this particular app that has been packaged with jpackage so I suspect that this is the culprit, previous version used the commercial JWrapper (not that it matters) which worked. Have not investigated this further yet. My question is if this is a true technical limitation or just that the Xcode used to build the C-code that starts the JVM was built with settings that prevent it from running in pre 10.13 versions and that check and dialog was built inform the user. Hmm ... something wrong with my thinking above as in that case it would be OS that would put up this dialog and I would have thought that the OS can address itself properly as it is now "macOS" and not "OS X". So I guess the dialog is coming from the stub/launcher in .app/contents/MacOS. But the question remains if this is a true technical limitation or policy decisions and if so is there a work around? Could I compile the launcher myself ? If I gave up the .app packaging and launched JVM from a script with the app in in a .jar should that work? ATM I have no access to pre 10.13 . The embedded JVM is: JVM-Version 11.0.1+13 JVM-Vendor Oracle Corporation JVM-Name OpenJDK 64-Bit Server VM For packaging I use 'jpackage' from jdk-13. cheers Kusti From philip.race at oracle.com Thu Apr 4 06:43:32 2019 From: philip.race at oracle.com (Philip Race) Date: Wed, 03 Apr 2019 23:43:32 -0700 Subject: The application requires 10.13 or later. In-Reply-To: <591325B0-7411-4329-90CE-EF2083CAF551@sparetimelabs.com> References: <591325B0-7411-4329-90CE-EF2083CAF551@sparetimelabs.com> Message-ID: <5CA5A794.1080800@oracle.com> JDK 11 runs on older versions. I don't see where that message would come from in the jpackage code but I could just be missing it. It may be more to do with you having run jpackage on 10.13 and the question is can it target an earlier version of MacOS than the one on which the .pkg is created ? -phil. On 4/3/19, 11:25 PM, Kustaa Nyholm wrote: > Hi, > > last night I released a new version of my app and one of the testers reported he > gets a dialog that says: > > > "You can't use this version of the application with this version of OS X. > You havew OS X 10.11.6. The application requires 10.13 or later." > > Now this is a first version of this particular app that has been packaged with > jpackage so I suspect that this is the culprit, previous version used the > commercial JWrapper (not that it matters) which worked. > > Have not investigated this further yet. > > My question is if this is a true technical limitation or just that the Xcode > used to build the C-code that starts the JVM was built with settings that > prevent it from running in pre 10.13 versions and that check and dialog > was built inform the user. > > Hmm ... something wrong with my thinking above as in that case it would be > OS that would put up this dialog and I would have thought that the OS can > address itself properly as it is now "macOS" and not "OS X". > > So I guess the dialog is coming from the stub/launcher in .app/contents/MacOS. > > But the question remains if this is a true technical limitation or policy decisions > and if so is there a work around? > > Could I compile the launcher myself ? > > If I gave up the .app packaging and launched JVM from a script with the app in > in a .jar should that work? > > ATM I have no access to pre 10.13 . > > The embedded JVM is: > > > JVM-Version 11.0.1+13 > JVM-Vendor Oracle Corporation > JVM-Name OpenJDK 64-Bit Server VM > > For packaging I use 'jpackage' from jdk-13. > > cheers Kusti > From kustaa.nyholm at sparetimelabs.com Thu Apr 4 09:11:41 2019 From: kustaa.nyholm at sparetimelabs.com (Kustaa Nyholm) Date: Thu, 4 Apr 2019 12:11:41 +0300 Subject: Fwd: The application requires 10.13 or later. References: <425ECEAE-B201-453F-AF89-456F622D6EE3@sparetimelabs.com> Message-ID: <8A46E578-051C-4B75-AF63-79C17B156589@sparetimelabs.com> Sorry I posted below off-list. > Begin forwarded message: > > From: Kustaa Nyholm > Subject: Re: The application requires 10.13 or later. > Date: 4 April 2019 at 10.00.39 EEST > To: Philip Race > > Thanks Phil for the confirmation that 11 runs on older version, so > that is one way to work around that issue by just starting the > JVM manually. > > > IIRC jpackage is not available with jdk11 and hence I used jdk13. > > Without knowing anything about the details I would have presumed that > all the relevant code native code that jpackage uses come as pre-compiled > and thus the OS version on which jpackage is used to create the .app image > should not matter ? > > Where would be the best place to ask about the jpackage in jdk13? > > wbr > From kustaa.nyholm at sparetimelabs.com Thu Apr 4 09:22:47 2019 From: kustaa.nyholm at sparetimelabs.com (Kustaa Nyholm) Date: Thu, 4 Apr 2019 12:22:47 +0300 Subject: jpackaged .app not compatible with macOS sandboxing? Message-ID: <269EB126-0208-463F-98F2-828B33750338@sparetimelabs.com> I've got an application that I package with jdk13 jpackage. The embedded JDK is 11.0.1+13. As reported by one of my testers on macOS Mojave it is not possible to add it to the list of applications that are allowed to control the computer (in System Preferences / Security & Privacy / Privacy / Accessibility) , which is required for the Robot.moveMouse() method and cousins to work. As experienced by myself on High Sierra, it is possible to add it to the list and while adding the app the file dialog displays the correct name and icon for the app but in the list it appears with generic Java coffee cup icon and the name of the application seems be same as the executable in the app bundle in .app/contents/MacOS/. Anyone else seen this? Should I file a bug report? wbr Kusti From matthias.baesken at sap.com Thu Apr 4 10:19:12 2019 From: matthias.baesken at sap.com (Baesken, Matthias) Date: Thu, 4 Apr 2019 10:19:12 +0000 Subject: RFR: 8218547: Simplify JLI_Open on Windows in native code (libjli) - was : RE: RFR : 8217093: Support extended-length paths in parse_manifest.c on windows In-Reply-To: References: <758af3c4-c59f-ea25-8491-2dcdab7bda17@oracle.com> <43304634-d902-b006-3159-3537433d9f67@oracle.com> Message-ID: Hello, is the latest revision fine with you ? May I add you as a reviewer ? Thanks, Matthias > -----Original Message----- > From: Baesken, Matthias > Sent: Dienstag, 2. April 2019 14:55 > To: 'Alan Bateman' > Cc: core-libs-dev at openjdk.java.net > Subject: RE: RFR: 8218547: Simplify JLI_Open on Windows in native code > (libjli) - was : RE: RFR : 8217093: Support extended-length paths in > parse_manifest.c on windows > > Hi Alan, here is a new webrev : > > http://cr.openjdk.java.net/~mbaesken/webrevs/8218547.3/webrev/ > > re-formatted the comment in java_md.c to avoid VERY LONG lines > adjusted test/jdk/tools/launcher/Arrrghs.java > > > Best regards, Matthias > > > > > -----Original Message----- > > From: Alan Bateman > > Sent: Samstag, 30. M?rz 2019 10:04 > > To: Baesken, Matthias > > Cc: core-libs-dev at openjdk.java.net > > Subject: Re: RFR: 8218547: Simplify JLI_Open on Windows in native code > > (libjli) - was : RE: RFR : 8217093: Support extended-length paths in > > parse_manifest.c on windows > > > > On 29/03/2019 12:36, Baesken, Matthias wrote: > > > Thanks. Alan, are you fine with the current webrev, if yes may I add you > as > > reviewer ? > > > > > The update to java_md.c looks okay, I probably would re-format the > > comment to void the line longs but it is otherwise okay. > > > > I think the new test needs a of bit clean-up, L490 is the main issue. > > One suggest is to rename pLong to longPath and build up ots value in a > > loop to avoid having a 340+ character line? The other variables names > > are very strange too but I can you can eliminate some of them by > > changing L491-492 to: > > ???? Path jarPath = Files.createDirectories(longPah).resolve("foo.jar"); > > > > -Alan > > From claes.redestad at oracle.com Thu Apr 4 10:29:29 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 4 Apr 2019 12:29:29 +0200 Subject: RFR: 8221980: Simplify Optional implementation Message-ID: <5db585d9-379b-71b6-a057-64f209c59379@oracle.com> Hi, the current code for Optional.ofNullable() null-checks the value, then calls of(), which calls new Optional(), which null-checks again via Objects.requireNonNull(). This can be simplified by refactoring so that we only null-check once and chain through fewer methods. Bug: https://bugs.openjdk.java.net/browse/JDK-8221980 Webrev: http://cr.openjdk.java.net/~redestad/8221980/open.00/ While JITs are likely to inline all this and generate the optimal code, it can fail to do so due inlining heuristics. This simplification reduces the risk of hitting such limits, while also speeding up code executed during startup and warmup phases. Testing: tier1-2, verified a small improvement in startup profiles Thanks! /Claes From claes.redestad at oracle.com Thu Apr 4 10:29:20 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 4 Apr 2019 12:29:20 +0200 Subject: RFR: 8221921: Implement size() / isEmpty() in immutable collections Message-ID: <74150e24-01ec-aa55-97a5-145010106a8e@oracle.com> Hi, a few of the ImmutableCollections are inheriting size and/or isEmpty from abstract base classes. A few of these are inefficiently implemented, e.g., on a Map1, isEmpty() will effectively be "return entrySet().size() == 0" when it could be simply "return false". This patch provide specialized implementations which JITs do the right thing while also helping startup slightly. Bug: https://bugs.openjdk.java.net/browse/JDK-8221921 Webrev: http://cr.openjdk.java.net/~redestad/8221921/open.00/ Testing: tier1-2, verified a tiny improvement in startup profiles Thanks! /Claes From claes.redestad at oracle.com Thu Apr 4 10:29:35 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 4 Apr 2019 12:29:35 +0200 Subject: RFR: 8221981: Simplify Map/List/Set.of() implementation Message-ID: <6ea2f6d8-70ad-fdaa-cde8-445fb4473eab@oracle.com> Hi, current implementations of the empty static factories (Map.of(), ...) delegate to static methods in java.util.ImmutableCollections. This indirection isn't really useful and adds a very small startup cost. Bug: https://bugs.openjdk.java.net/browse/JDK-8221981 Webrev: http://cr.openjdk.java.net/~redestad/8221981/open.00/ Testing: tier1-2, verified a tiny improvement in startup profiles Thanks! /Claes From kevin.rushforth at oracle.com Thu Apr 4 11:41:37 2019 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Thu, 4 Apr 2019 04:41:37 -0700 Subject: Fwd: The application requires 10.13 or later. In-Reply-To: <8A46E578-051C-4B75-AF63-79C17B156589@sparetimelabs.com> References: <425ECEAE-B201-453F-AF89-456F622D6EE3@sparetimelabs.com> <8A46E578-051C-4B75-AF63-79C17B156589@sparetimelabs.com> Message-ID: This is the right mailing list to ask questions about jpackage. I have a macOS running 10.12.6, so I can take a look at this later today and get back to you (or maybe Andy will reply). -- Kevin On 4/4/2019 2:11 AM, Kustaa Nyholm wrote: > Sorry I posted below off-list. > > >> Begin forwarded message: >> >> From: Kustaa Nyholm >> Subject: Re: The application requires 10.13 or later. >> Date: 4 April 2019 at 10.00.39 EEST >> To: Philip Race >> >> Thanks Phil for the confirmation that 11 runs on older version, so >> that is one way to work around that issue by just starting the >> JVM manually. >> >> >> IIRC jpackage is not available with jdk11 and hence I used jdk13. >> >> Without knowing anything about the details I would have presumed that >> all the relevant code native code that jpackage uses come as pre-compiled >> and thus the OS version on which jpackage is used to create the .app image >> should not matter ? >> >> Where would be the best place to ask about the jpackage in jdk13? >> >> wbr >> From kevin.rushforth at oracle.com Thu Apr 4 11:47:10 2019 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Thu, 4 Apr 2019 04:47:10 -0700 Subject: jpackaged .app not compatible with macOS sandboxing? In-Reply-To: <269EB126-0208-463F-98F2-828B33750338@sparetimelabs.com> References: <269EB126-0208-463F-98F2-828B33750338@sparetimelabs.com> Message-ID: <853d7bfe-b72a-44f7-fcec-a80bddaefff3@oracle.com> I have seen this problem running robot-based tests on Mojave using a standard JDK, so I don't think this is specific to jpackage. I had to grant permission to control the computer to the terminal used to execute java rather than java itself. You could try that as a workaround. -- Kevin On 4/4/2019 2:22 AM, Kustaa Nyholm wrote: > I've got an application that I package with jdk13 jpackage. > > The embedded JDK is 11.0.1+13. > > As reported by one of my testers on macOS Mojave it is not possible to add it to the list of applications that are allowed to control the computer (in System Preferences / Security & Privacy / Privacy / Accessibility) , which is required for the Robot.moveMouse() method and cousins to work. > > As experienced by myself on High Sierra, it is possible to add it to the list and while adding the app the file dialog displays the correct name and icon for the app but in the list it appears with generic Java coffee cup icon and the name of the application seems be same as the executable in the app bundle in .app/contents/MacOS/. > > Anyone else seen this? > > Should I file a bug report? > > wbr Kusti > > > From andy.herrick at oracle.com Thu Apr 4 12:12:42 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Thu, 4 Apr 2019 08:12:42 -0400 Subject: RFR: JDK-8221876:[macOS] JPackage install takes long time In-Reply-To: <7584aae9-dbfd-a31b-f5c5-cf2f75c1b5b0@oracle.com> References: <7584aae9-dbfd-a31b-f5c5-cf2f75c1b5b0@oracle.com> Message-ID: looks good. /Andy On 4/3/2019 5:30 PM, semyon.sadetsky at oracle.com wrote: > Hello, > > bug: https://bugs.openjdk.java.net/browse/JDK-8221876 > > webrev: http://cr.openjdk.java.net/~ssadetsky/8221876/webrev.00/ > > The fix eliminate delay in install which is caused by postinstall > script introduced in 8215241 when it set permissions for large number > of files. Actually setting permissions to? the installation folder is > sufficient. > > --Semyon > From kustaa.nyholm at sparetimelabs.com Thu Apr 4 12:32:11 2019 From: kustaa.nyholm at sparetimelabs.com (Kustaa Nyholm) Date: Thu, 4 Apr 2019 15:32:11 +0300 Subject: jpackaged .app not compatible with macOS sandboxing? In-Reply-To: <853d7bfe-b72a-44f7-fcec-a80bddaefff3@oracle.com> References: <269EB126-0208-463F-98F2-828B33750338@sparetimelabs.com> <853d7bfe-b72a-44f7-fcec-a80bddaefff3@oracle.com> Message-ID: <51EE182D-9BCB-46A8-A4D9-A47523C7F66A@sparetimelabs.com> > On 4 Apr 2019, at 14.47, Kevin Rushforth wrote: > > I have seen this problem running robot-based tests on Mojave using a standard JDK, so I don't think this is specific to jpackage. I had to grant permission to control the computer to the terminal used to execute java rather than java itself. You could try that as a workaround. > > -- Kevin > Thanks Kevin, can you elaborate a bit as I did not fully follow what you wrote. As I launch the application by double clicking at the .app where does the terminal come in? Also is this a work around for being able to grant the control to the app or to the phenomenon that the icon and name are wrong in the System Preferences pane where the access is granted? wbr Kusti From christoph.langer at sap.com Thu Apr 4 12:51:36 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Thu, 4 Apr 2019 12:51:36 +0000 Subject: RFR: 8221980: Simplify Optional implementation In-Reply-To: <5db585d9-379b-71b6-a057-64f209c59379@oracle.com> References: <5db585d9-379b-71b6-a057-64f209c59379@oracle.com> Message-ID: Hi Claes, this looks good to me. Best regards Christoph > -----Original Message----- > From: core-libs-dev On Behalf > Of Claes Redestad > Sent: Donnerstag, 4. April 2019 12:29 > To: core-libs-dev > Subject: RFR: 8221980: Simplify Optional implementation > > Hi, > > the current code for Optional.ofNullable() null-checks the value, then > calls of(), which calls new Optional(), which null-checks again via > Objects.requireNonNull(). This can be simplified by refactoring so that > we only null-check once and chain through fewer methods. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8221980 > Webrev: http://cr.openjdk.java.net/~redestad/8221980/open.00/ > > While JITs are likely to inline all this and generate the optimal > code, it can fail to do so due inlining heuristics. This simplification > reduces the risk of hitting such limits, while also speeding up code > executed during startup and warmup phases. > > Testing: tier1-2, verified a small improvement in startup profiles > > Thanks! > > /Claes From andy.herrick at oracle.com Thu Apr 4 13:08:40 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Thu, 4 Apr 2019 09:08:40 -0400 Subject: Fwd: The application requires 10.13 or later. In-Reply-To: References: <425ECEAE-B201-453F-AF89-456F622D6EE3@sparetimelabs.com> <8A46E578-051C-4B75-AF63-79C17B156589@sparetimelabs.com> Message-ID: On 4/4/2019 7:41 AM, Kevin Rushforth wrote: > This is the right mailing list to ask questions about jpackage. I have > a macOS running 10.12.6, so I can take a look at this later today and > get back to you (or maybe Andy will reply). Yes , we need to test and fix any problems with installing and running applications on earlier OS versions than the version built on, and that applies to all supported OS's.? We will look into it, file appropriate bugs, and fix. /Andy > > -- Kevin > > > On 4/4/2019 2:11 AM, Kustaa Nyholm wrote: >> Sorry I posted below off-list. >> >> >>> Begin forwarded message: >>> >>> From: Kustaa Nyholm >>> Subject: Re: The application requires 10.13 or later. >>> Date: 4 April 2019 at 10.00.39 EEST >>> To: Philip Race >>> >>> Thanks Phil for the confirmation that 11 runs on older version, so >>> that is one way to work around that issue by just starting the >>> JVM manually. >>> >>> >>> IIRC jpackage is not available with jdk11 and hence I used jdk13. >>> >>> Without knowing anything about the details I would have presumed that >>> all the relevant code native code that jpackage uses come as >>> pre-compiled >>> and thus the OS version on which jpackage is used to create the .app >>> image >>> should not matter ? >>> >>> Where would be the best place to ask about the jpackage in jdk13? >>> >>> wbr >>> > From andy.herrick at oracle.com Thu Apr 4 13:13:50 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Thu, 4 Apr 2019 09:13:50 -0400 Subject: jpackaged .app not compatible with macOS sandboxing? In-Reply-To: <269EB126-0208-463F-98F2-828B33750338@sparetimelabs.com> References: <269EB126-0208-463F-98F2-828B33750338@sparetimelabs.com> Message-ID: <890699b0-70bb-7990-c258-77e1da4b00b5@oracle.com> We will file a bug for this part, and address it soon. /Andy On 4/4/2019 5:22 AM, Kustaa Nyholm wrote: > As experienced by myself on High Sierra, it is possible to add it to the list and while adding the app the file dialog displays the correct name and icon for the app but in the list it appears with generic Java coffee cup icon and the name of the application seems be same as the executable in the app bundle in .app/contents/MacOS/. From claes.redestad at oracle.com Thu Apr 4 13:16:00 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 4 Apr 2019 15:16:00 +0200 Subject: RFR: 8221980: Simplify Optional implementation In-Reply-To: References: <5db585d9-379b-71b6-a057-64f209c59379@oracle.com> Message-ID: Hi Christoph, On 2019-04-04 14:51, Langer, Christoph wrote: > Hi Claes, > > this looks good to me. thank you for reviewing! /Claes From Alan.Bateman at oracle.com Thu Apr 4 13:18:14 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 4 Apr 2019 14:18:14 +0100 Subject: RFR: 8218547: Simplify JLI_Open on Windows in native code (libjli) - was : RE: RFR : 8217093: Support extended-length paths in parse_manifest.c on windows In-Reply-To: References: <758af3c4-c59f-ea25-8491-2dcdab7bda17@oracle.com> <43304634-d902-b006-3159-3537433d9f67@oracle.com> Message-ID: On 02/04/2019 13:54, Baesken, Matthias wrote: > Hi Alan, here is a new webrev : > > http://cr.openjdk.java.net/~mbaesken/webrevs/8218547.3/webrev/ > > re-formatted the comment in java_md.c to avoid VERY LONG lines > adjusted test/jdk/tools/launcher/Arrrghs.java > > > Best regards, Matthias Using String.repeat instead of 340+ character line is much better :-)??? So yes, I think this version looks good. -Alan From kevin.rushforth at oracle.com Thu Apr 4 14:18:38 2019 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Thu, 4 Apr 2019 07:18:38 -0700 Subject: jpackaged .app not compatible with macOS sandboxing? In-Reply-To: <51EE182D-9BCB-46A8-A4D9-A47523C7F66A@sparetimelabs.com> References: <269EB126-0208-463F-98F2-828B33750338@sparetimelabs.com> <853d7bfe-b72a-44f7-fcec-a80bddaefff3@oracle.com> <51EE182D-9BCB-46A8-A4D9-A47523C7F66A@sparetimelabs.com> Message-ID: <18d58c72-2caf-60d9-0ede-6eaee61cb6c6@oracle.com> On 4/4/2019 5:32 AM, Kustaa Nyholm wrote: >> On 4 Apr 2019, at 14.47, Kevin Rushforth wrote: >> >> I have seen this problem running robot-based tests on Mojave using a standard JDK, so I don't think this is specific to jpackage. I had to grant permission to control the computer to the terminal used to execute java rather than java itself. You could try that as a workaround. >> > As I launch the application by double clicking at the .app where does the terminal come in? I see. In that case, my suggestion won't help you (although as a test of whether this is the issue, you could try launching the app from the terminal to see if that makes a difference). >> Also is this a work around for being able to grant the control to the app or >> to the phenomenon that the icon and name are wrong in the System Preferences pane >> where the access is granted? I meant as a workaround of the problem of not being able to grant access to the application. It seems we will need to find a solution to this, so I'll file a bug (which may or may not be related to jpacakge). -- Kevin From adinn at redhat.com Thu Apr 4 15:19:08 2019 From: adinn at redhat.com (Andrew Dinn) Date: Thu, 4 Apr 2019 16:19:08 +0100 Subject: RFR: 8221477: Inject os/cpu-specific constants into Unsafe from JVM In-Reply-To: <2fc62430-2e2e-9ee5-ccf1-f1cde5cea416@redhat.com> References: <2fc62430-2e2e-9ee5-ccf1-f1cde5cea416@redhat.com> Message-ID: <49615c26-8ad8-ca99-a66f-d5884164d99f@redhat.com> New webrev is now available. Re-reviews welcome. JIRA: https://bugs.openjdk.java.net/browse/JDK-8221477 Webrev: http://cr.openjdk.java.net/~adinn/8221477/webrev.03 This version should address all comments from Thomas, David and Coleen. Testing Tier1 test passed. Submit test passed. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From sean.bridges at gmail.com Thu Apr 4 17:14:01 2019 From: sean.bridges at gmail.com (Sean Bridges) Date: Thu, 4 Apr 2019 10:14:01 -0700 Subject: can File.exists can return false if the file exists? Message-ID: Hey, Is it possible for File.exists(...) to return false even if the file exists. The java docs for File.exists say, "return true if and only if the file or directory denoted by this abstract pathname exists; false otherwise" Looking at the implementation, the method does, s.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0 But FileSystem.getBooleanAttributes says, "Return the simple boolean attributes for the file or directory denoted by the given abstract pathname, *or zero if it does not exist or some* * other I/O error occurs*." So it seems that File.exists can return false for files which exist. I think we ran into this on a linux server which reached the limit on open file handles, and File#exists returned false even though the file existed. Is there a way to reliably tell in java if a files exists. Even a method which returned true/false/unknown would be preferable. Thanks, Sean From Alan.Bateman at oracle.com Thu Apr 4 19:47:45 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 4 Apr 2019 20:47:45 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> Message-ID: On 03/04/2019 10:10, Andrew Dinn wrote: > : > I still have two undecided points you might advise on: > > Does the javadoc for FileChannel.map and/or FileChannelImpl.map need > updating to record the possibility that UOE might be thrown? I don't think I understand your question about FileChannel.map as you've already got @throws UOE in the patch. FileChannelImpl.map is JDK internal/implementation so nothing to do there (beyond the implementation change that you already have). > > Do I need to update any other implementations of map to cater for the > possibility of user-defined map modes? > No, the there shouldn't be anywhere else that needs updating. I looked through webrev.01. The package description has a catch-all for NPE so you need to specify that in each method. In the constructor it would be better to check for length 0 before assigning name (and of course name.length will throw NPE so you get that check for free). The test looks okay although I would probably catch the specific exceptions rather than catching Exception and catching them later but it amounts to the same checking. -Alan. From ecki at zusammenkunft.net Thu Apr 4 20:22:53 2019 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Thu, 4 Apr 2019 20:22:53 +0000 Subject: can File.exists can return false if the file exists? In-Reply-To: References: Message-ID: Yes it can and does, the getBooleanAttributes method of the filesystem providers cannot communicate IOExceptions, so it will have to return unset flags for this?s case. (Also there are some OS specific conditions where the file stat might be stale, especially if it is a networked filesystem). The missing possibility for returning IOExceptions on File IO was one of the drivers for NIO APIs (unfortunately the alternative Files.exist(Path) took no advantage of this) What you can do is to open the file and inspect the exception and/or use Files.walkFileTree to iterate the parent (as it gives you basicfileattributes view based on the directory read) . Gruss Bernd -- http://bernd.eckenfels.net ________________________________ Von: core-libs-dev im Auftrag von Sean Bridges Gesendet: Donnerstag, April 4, 2019 9:45 PM An: core-libs-dev at openjdk.java.net Betreff: can File.exists can return false if the file exists? Hey, Is it possible for File.exists(...) to return false even if the file exists. The java docs for File.exists say, "return true if and only if the file or directory denoted by this abstract pathname exists; false otherwise" Looking at the implementation, the method does, s.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0 But FileSystem.getBooleanAttributes says, "Return the simple boolean attributes for the file or directory denoted by the given abstract pathname, *or zero if it does not exist or some* * other I/O error occurs*." So it seems that File.exists can return false for files which exist. I think we ran into this on a linux server which reached the limit on open file handles, and File#exists returned false even though the file existed. Is there a way to reliably tell in java if a files exists. Even a method which returned true/false/unknown would be preferable. Thanks, Sean From stuart.marks at oracle.com Thu Apr 4 20:41:17 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 4 Apr 2019 13:41:17 -0700 Subject: RFR: 8221921: Implement size() / isEmpty() in immutable collections In-Reply-To: <74150e24-01ec-aa55-97a5-145010106a8e@oracle.com> References: <74150e24-01ec-aa55-97a5-145010106a8e@oracle.com> Message-ID: <942dfddd-eec4-4b41-925b-d00e25c62b74@oracle.com> On 4/4/19 3:29 AM, Claes Redestad wrote: > a few of the ImmutableCollections are inheriting size and/or isEmpty > from abstract base classes. A few of these are inefficiently > implemented, e.g., on a Map1, isEmpty() will effectively be > "return entrySet().size() == 0" when it could be simply "return > false". Ugh! > This patch provide specialized implementations which JITs do the right > thing while also helping startup slightly. > > Bug:??? https://bugs.openjdk.java.net/browse/JDK-8221921 > Webrev: http://cr.openjdk.java.net/~redestad/8221921/open.00/ > > Testing: tier1-2, verified a tiny improvement in startup profiles [this is from ListN] > @@ -483,11 +488,11 @@ > elements = tmp; > } > > @Override > public boolean isEmpty() { > - return size() == 0; > + return elements.length == 0; > } > > @Override > public int size() { > return elements.length; You're really splitting bytecodes aren't you? :-) Anyway, changeset looks good. s'marks From stuart.marks at oracle.com Thu Apr 4 20:43:47 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 4 Apr 2019 13:43:47 -0700 Subject: RFR: 8221981: Simplify Map/List/Set.of() implementation In-Reply-To: <6ea2f6d8-70ad-fdaa-cde8-445fb4473eab@oracle.com> References: <6ea2f6d8-70ad-fdaa-cde8-445fb4473eab@oracle.com> Message-ID: <260f8df2-6052-f0c4-dad2-762281f43e0e@oracle.com> On 4/4/19 3:29 AM, Claes Redestad wrote: > current implementations of the empty static factories (Map.of(), ...) > delegate to static methods in java.util.ImmutableCollections. This > indirection isn't really useful and adds a very small startup cost. > > Bug:??? https://bugs.openjdk.java.net/browse/JDK-8221981 > Webrev: http://cr.openjdk.java.net/~redestad/8221981/open.00/ > > Testing: tier1-2, verified a tiny improvement in startup profiles Changes look good, thanks. s'marks From stuart.marks at oracle.com Thu Apr 4 20:45:46 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 4 Apr 2019 13:45:46 -0700 Subject: RFR: 8221980: Simplify Optional implementation In-Reply-To: <5db585d9-379b-71b6-a057-64f209c59379@oracle.com> References: <5db585d9-379b-71b6-a057-64f209c59379@oracle.com> Message-ID: On 4/4/19 3:29 AM, Claes Redestad wrote: > the current code for Optional.ofNullable() null-checks the value, then > calls of(), which calls new Optional(), which null-checks again via > Objects.requireNonNull(). This can be simplified by refactoring so that we only > null-check once and chain through fewer methods. > > Bug:??? https://bugs.openjdk.java.net/browse/JDK-8221980 > Webrev: http://cr.openjdk.java.net/~redestad/8221980/open.00/ > > While JITs are likely to inline all this and generate the optimal > code, it can fail to do so due inlining heuristics. This simplification > reduces the risk of hitting such limits, while also speeding up code > executed during startup and warmup phases. > > Testing: tier1-2, verified a small improvement in startup profiles Changes look good, thanks. s'marks From claes.redestad at oracle.com Thu Apr 4 21:03:43 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 4 Apr 2019 23:03:43 +0200 Subject: RFR: 8221980: Simplify Optional implementation In-Reply-To: References: <5db585d9-379b-71b6-a057-64f209c59379@oracle.com> Message-ID: <4b2f7fca-4fbf-2ab6-2874-0340b8fac517@oracle.com> On 2019-04-04 22:45, Stuart Marks wrote: > > Changes look good, thanks. Thanks for reviewing this, 8221921 and 8221981, Stuart! /Claes From stuart.marks at oracle.com Thu Apr 4 21:11:57 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 4 Apr 2019 14:11:57 -0700 Subject: RFR: 8221924: get(null) on single-entry unmodifiable Map returns null instead of throwing NPE Message-ID: Hi all, An unmodifiable map with one entry doesn't throw NPE from get(null). Instead, it returns null. This makes it quite an outlier: Map.of().get(null) ==> NPE Map.of().containsKey(null) ==> NPE Map.of().containsValue(null) ==> NPE Map.of(1, 2).get(null) ==> returns null *** Map.of(1, 2).containsKey(null) ==> NPE Map.of(1, 2).containsValue(null) ==> NPE Map.of(1, 2, 3, 4).get(null) ==> NPE Map.of(1, 2, 3, 4).containsKey(null) ==> NPE Map.of(1, 2, 3, 4).containsValue(null) ==> NPE It should be fixed to throw NPE like all the other cases. This is a tiny incompatible change, so I intend to file a CSR. Tier1, 2, and 3 tests all pass though. I think this change should also be backported to 11. We're fairly early in the 11 LTS lifetime, so it'd be good to fix this now. Bug: https://bugs.openjdk.java.net/browse/JDK-8221924 Webrev: http://cr.openjdk.java.net/~smarks/reviews/8221924/webrev.0/ Thanks, s'marks From claes.redestad at oracle.com Thu Apr 4 21:27:47 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 4 Apr 2019 23:27:47 +0200 Subject: RFR: 8221924: get(null) on single-entry unmodifiable Map returns null instead of throwing NPE In-Reply-To: References: Message-ID: On 2019-04-04 23:11, Stuart Marks wrote:> > Webrev: > > ????http://cr.openjdk.java.net/~smarks/reviews/8221924/webrev.0/ Changes and new test looks good. Thanks! /Claes From lance.andersen at oracle.com Thu Apr 4 21:35:22 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 4 Apr 2019 17:35:22 -0400 Subject: RFR: 8221924: get(null) on single-entry unmodifiable Map returns null instead of throwing NPE In-Reply-To: References: Message-ID: <6A36705F-329B-4D81-935D-E3BBF6B29E8A@oracle.com> Hi Stuart, Minor but... You probably want to add 8221924 to @bug in the test Best Lance > On Apr 4, 2019, at 5:11 PM, Stuart Marks wrote: > > Hi all, > > An unmodifiable map with one entry doesn't throw NPE from get(null). Instead, it returns null. This makes it quite an outlier: > > Map.of().get(null) ==> NPE > Map.of().containsKey(null) ==> NPE > Map.of().containsValue(null) ==> NPE > > Map.of(1, 2).get(null) ==> returns null *** > Map.of(1, 2).containsKey(null) ==> NPE > Map.of(1, 2).containsValue(null) ==> NPE > > Map.of(1, 2, 3, 4).get(null) ==> NPE > Map.of(1, 2, 3, 4).containsKey(null) ==> NPE > Map.of(1, 2, 3, 4).containsValue(null) ==> NPE > > It should be fixed to throw NPE like all the other cases. > > This is a tiny incompatible change, so I intend to file a CSR. Tier1, 2, and 3 tests all pass though. > > I think this change should also be backported to 11. We're fairly early in the 11 LTS lifetime, so it'd be good to fix this now. > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8221924 > > Webrev: > > http://cr.openjdk.java.net/~smarks/reviews/8221924/webrev.0/ > > Thanks, > > s'marks 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 stuart.marks at oracle.com Thu Apr 4 21:50:35 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 4 Apr 2019 14:50:35 -0700 Subject: RFR: 8221924: get(null) on single-entry unmodifiable Map returns null instead of throwing NPE In-Reply-To: <6A36705F-329B-4D81-935D-E3BBF6B29E8A@oracle.com> References: <6A36705F-329B-4D81-935D-E3BBF6B29E8A@oracle.com> Message-ID: <37a79c51-39f3-0e48-06ae-9f2ca57b00f5@oracle.com> On 4/4/19 2:35 PM, Lance Andersen wrote: > You probably want to add?8221924 to @bug in the test Oh yes, good point, I'll do that. thanks, s'marks From andy.herrick at oracle.com Thu Apr 4 23:27:47 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Thu, 4 Apr 2019 19:27:47 -0400 Subject: RFR: JDK-8221779: Help text changes from JDK-8221777 and other jpackage EA5 feedback Message-ID: Please review the jpackage fix for bug [1] at [2]. This is a fix for the JDK-8200758-branch branch of the open sandbox repository (jpackage). [1] https://bugs.openjdk.java.net/browse/JDK-8221779 [2] http://cr.openjdk.java.net/~herrick/8221779/ /Andy From andy.herrick at oracle.com Thu Apr 4 23:32:06 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Thu, 4 Apr 2019 19:32:06 -0400 Subject: RFR: JDK8221777: CLI changes from jpackage EA5 feedback Message-ID: <2d6f1178-fc39-9c7a-9a98-9af7317a29df@oracle.com> Please review the jpackage fix for bug [1] at [2]. This is a fix for the JDK-8200758-branch branch of the open sandbox repository (jpackage). This change renames the "create-image" mode to "create-app-image", and removes the "--files" options . [1] https://bugs.openjdk.java.net/browse/JDK-8221777 [2] http://cr.openjdk.java.net/~herrick/8221777/ /Andy From alexander.matveev at oracle.com Thu Apr 4 23:45:43 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Thu, 4 Apr 2019 16:45:43 -0700 Subject: RFR: JDK-8221779: Help text changes from JDK-8221777 and other jpackage EA5 feedback In-Reply-To: References: Message-ID: <6e4fd1ba-eb8d-d767-a5b8-996405bfe9b2@oracle.com> Hi Andy, Looks good. Thanks, Alexander On 4/4/2019 4:27 PM, Andy Herrick wrote: > Please review the jpackage fix for bug [1] at [2]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > [1] https://bugs.openjdk.java.net/browse/JDK-8221779 > > [2] http://cr.openjdk.java.net/~herrick/8221779/ > > /Andy > From brian.burkhalter at oracle.com Thu Apr 4 23:50:00 2019 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Thu, 4 Apr 2019 16:50:00 -0700 Subject: 8221597: A typo in the Java API doc for File.getUsableSpace() Message-ID: <0D7DFC03-77C1-4497-840D-2B0F0C7457A8@oracle.com> Please review this one word change to fix [1]. Summary: s/unallocated/unavailable/ at line 1872 --- a/src/java.base/share/classes/java/io/File.java +++ b/src/java.base/share/classes/java/io/File.java @@ -1869,7 +1869,7 @@ * *

        The returned number of available bytes is a hint, but not a * guarantee, that it is possible to use most or any of these bytes. The - * number of unallocated bytes is most likely to be accurate immediately + * number of available bytes is most likely to be accurate immediately * after this call. It is likely to be made inaccurate by any external * I/O operations including those made on the system outside of this * virtual machine. This method makes no guarantee that write operations Thanks, Brian [1] https://bugs.openjdk.java.net/browse/JDK-8221597 From brian.burkhalter at oracle.com Thu Apr 4 23:54:02 2019 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Thu, 4 Apr 2019 16:54:02 -0700 Subject: 8221597: A typo in the Java API doc for File.getUsableSpace() In-Reply-To: <0D7DFC03-77C1-4497-840D-2B0F0C7457A8@oracle.com> References: <0D7DFC03-77C1-4497-840D-2B0F0C7457A8@oracle.com> Message-ID: <71E5DD14-3649-4070-BC1B-B6C24B1440AD@oracle.com> Oops: unavailable -> available. > On Apr 4, 2019, at 4:50 PM, Brian Burkhalter wrote: > > Summary: s/unallocated/unavailable/ at line 1872 From joe.darcy at oracle.com Thu Apr 4 23:59:45 2019 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Thu, 04 Apr 2019 16:59:45 -0700 Subject: 8221597: A typo in the Java API doc for File.getUsableSpace() In-Reply-To: <71E5DD14-3649-4070-BC1B-B6C24B1440AD@oracle.com> References: <0D7DFC03-77C1-4497-840D-2B0F0C7457A8@oracle.com> <71E5DD14-3649-4070-BC1B-B6C24B1440AD@oracle.com> Message-ID: <5CA69A71.5070205@oracle.com> +1 -Joe On 4/4/2019 4:54 PM, Brian Burkhalter wrote: > Oops: unavailable -> available. > >> On Apr 4, 2019, at 4:50 PM, Brian Burkhalter wrote: >> >> Summary: s/unallocated/unavailable/ at line 1872 From lance.andersen at oracle.com Fri Apr 5 00:00:37 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 4 Apr 2019 20:00:37 -0400 Subject: 8221597: A typo in the Java API doc for File.getUsableSpace() In-Reply-To: <71E5DD14-3649-4070-BC1B-B6C24B1440AD@oracle.com> References: <0D7DFC03-77C1-4497-840D-2B0F0C7457A8@oracle.com> <71E5DD14-3649-4070-BC1B-B6C24B1440AD@oracle.com> Message-ID: <1DCC290E-F8DF-4E08-BF80-F48B5F96295D@oracle.com> Looks Ok Brian > On Apr 4, 2019, at 7:54 PM, Brian Burkhalter wrote: > > Oops: unavailable -> available. > >> On Apr 4, 2019, at 4:50 PM, Brian Burkhalter wrote: >> >> Summary: s/unallocated/unavailable/ at line 1872 > 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 kevin.rushforth at oracle.com Fri Apr 5 01:17:42 2019 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Thu, 4 Apr 2019 18:17:42 -0700 Subject: RFR: JDK-8221779: Help text changes from JDK-8221777 and other jpackage EA5 feedback In-Reply-To: <6e4fd1ba-eb8d-d767-a5b8-996405bfe9b2@oracle.com> References: <6e4fd1ba-eb8d-d767-a5b8-996405bfe9b2@oracle.com> Message-ID: Looks good to me, too. -- Kevin On 4/4/2019 4:45 PM, Alexander Matveev wrote: > Hi Andy, > > Looks good. > > Thanks, > Alexander > > On 4/4/2019 4:27 PM, Andy Herrick wrote: >> Please review the jpackage fix for bug [1] at [2]. >> >> This is a fix for the JDK-8200758-branch branch of the open sandbox >> repository (jpackage). >> >> [1] https://bugs.openjdk.java.net/browse/JDK-8221779 >> >> [2] http://cr.openjdk.java.net/~herrick/8221779/ >> >> /Andy >> > From kevin.rushforth at oracle.com Fri Apr 5 01:24:31 2019 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Thu, 4 Apr 2019 18:24:31 -0700 Subject: RFR: JDK8221777: CLI changes from jpackage EA5 feedback In-Reply-To: <2d6f1178-fc39-9c7a-9a98-9af7317a29df@oracle.com> References: <2d6f1178-fc39-9c7a-9a98-9af7317a29df@oracle.com> Message-ID: <6bccbbb4-207b-c2d7-a7d7-9e5008a94c75@oracle.com> Looks good to me. -- Kevin On 4/4/2019 4:32 PM, Andy Herrick wrote: > Please review the jpackage fix for bug [1] at [2]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > This change renames the "create-image" mode to "create-app-image", and > removes the "--files" options . > > > [1] https://bugs.openjdk.java.net/browse/JDK-8221777 > > [2] http://cr.openjdk.java.net/~herrick/8221777/ > > > /Andy > From alexander.matveev at oracle.com Fri Apr 5 02:02:43 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Thu, 4 Apr 2019 19:02:43 -0700 Subject: RFR: JDK8221777: CLI changes from jpackage EA5 feedback In-Reply-To: <2d6f1178-fc39-9c7a-9a98-9af7317a29df@oracle.com> References: <2d6f1178-fc39-9c7a-9a98-9af7317a29df@oracle.com> Message-ID: Hi Andy, Looks good. Thanks, Alexander On 4/4/2019 4:32 PM, Andy Herrick wrote: > Please review the jpackage fix for bug [1] at [2]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > This change renames the "create-image" mode to "create-app-image", and > removes the "--files" options . > > > [1] https://bugs.openjdk.java.net/browse/JDK-8221777 > > [2] http://cr.openjdk.java.net/~herrick/8221777/ > > > /Andy > From david.holmes at oracle.com Fri Apr 5 03:54:10 2019 From: david.holmes at oracle.com (David Holmes) Date: Fri, 5 Apr 2019 13:54:10 +1000 Subject: RFR: 8221477: Inject os/cpu-specific constants into Unsafe from JVM In-Reply-To: <49615c26-8ad8-ca99-a66f-d5884164d99f@redhat.com> References: <2fc62430-2e2e-9ee5-ccf1-f1cde5cea416@redhat.com> <49615c26-8ad8-ca99-a66f-d5884164d99f@redhat.com> Message-ID: Hi Andrew, This all looks good to me - thanks for making the changes. Two nits: - BE was barely acceptable when used like a local variable, but now I think BIG_ENDIAN would be better. - If you don't use static import you can name the UnsafeConstants fields the obvious way without clashing with public fields in Unsafe. Feel free to ignore those nits. If you do make a change no need to see another webrev. Thanks, David On 5/04/2019 1:19 am, Andrew Dinn wrote: > New webrev is now available. Re-reviews welcome. > > JIRA: https://bugs.openjdk.java.net/browse/JDK-8221477 > Webrev: http://cr.openjdk.java.net/~adinn/8221477/webrev.03 > > This version should address all comments from Thomas, David and Coleen. > > Testing > Tier1 test passed. > Submit test passed. > > regards, > > > Andrew Dinn > ----------- > Senior Principal Software Engineer > Red Hat UK Ltd > Registered in England and Wales under Company Registration No. 03798903 > Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander > From peter.levart at gmail.com Fri Apr 5 07:04:59 2019 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 5 Apr 2019 09:04:59 +0200 Subject: RFR: 8221924: get(null) on single-entry unmodifiable Map returns null instead of throwing NPE In-Reply-To: References: Message-ID: <253385b4-86c4-edab-3b2d-f7e9991371c2@gmail.com> Map1.get() should be much faster with this patch too, right? Peter On 4/4/19 11:11 PM, Stuart Marks wrote: > Hi all, > > An unmodifiable map with one entry doesn't throw NPE from get(null). > Instead, it returns null. This makes it quite an outlier: > > Map.of().get(null) ==> NPE > Map.of().containsKey(null) ==> NPE > Map.of().containsValue(null) ==> NPE > > Map.of(1, 2).get(null) ==> returns null? *** > Map.of(1, 2).containsKey(null) ==> NPE > Map.of(1, 2).containsValue(null) ==> NPE > > Map.of(1, 2, 3, 4).get(null) ==> NPE > Map.of(1, 2, 3, 4).containsKey(null) ==> NPE > Map.of(1, 2, 3, 4).containsValue(null) ==> NPE > > It should be fixed to throw NPE like all the other cases. > > This is a tiny incompatible change, so I intend to file a CSR. Tier1, > 2, and 3 tests all pass though. > > I think this change should also be backported to 11. We're fairly > early in the 11 LTS lifetime, so it'd be good to fix this now. > > Bug: > > ????https://bugs.openjdk.java.net/browse/JDK-8221924 > > Webrev: > > ????http://cr.openjdk.java.net/~smarks/reviews/8221924/webrev.0/ > > Thanks, > > s'marks From peter.levart at gmail.com Fri Apr 5 07:37:20 2019 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 5 Apr 2019 09:37:20 +0200 Subject: RFR: 8221477: Inject os/cpu-specific constants into Unsafe from JVM In-Reply-To: <49615c26-8ad8-ca99-a66f-d5884164d99f@redhat.com> References: <2fc62430-2e2e-9ee5-ccf1-f1cde5cea416@redhat.com> <49615c26-8ad8-ca99-a66f-d5884164d99f@redhat.com> Message-ID: Hi Andrew, For a casual reader (like me) the comments in the UnsafeConstants for each field: ? 69????? * @implNote ? 70????? * The actual value for this field is injected by the JVM. ...make one wonder what is actually going on regarding the static initializer at the end of the class. Is it actually executed? Is it there just to silence the javac and prevent fields from becoming compile-time constants? Reading the patch further uncovers the secret: 3645?? // initialize the hardware-specific constants needed by Unsafe 3646 initialize_class(vmSymbols::jdk_internal_misc_UnsafeConstants(), CHECK); 3647?? jdk_internal_misc_UnsafeConstants::set_unsafe_constants(); If my understanding is correct, then the static initializer *is* executed and then the fields' values are overwritten with injected values. So perhaps it might be nice to write that down in the javadoc like: ? 69????? * @implNote ? 70????? * The actual value for this field is injected by the JVM immediately after the class initialization. Or something similar in the class-level javadoc. Just for the peace of mind of casual readers or perhaps someone that might later add a field to this class and try to initialize it in the static initializer, although I think this class is reserved for injected fields only... Regards, Peter On 4/4/19 5:19 PM, Andrew Dinn wrote: > New webrev is now available. Re-reviews welcome. > > JIRA: https://bugs.openjdk.java.net/browse/JDK-8221477 > Webrev: http://cr.openjdk.java.net/~adinn/8221477/webrev.03 > > This version should address all comments from Thomas, David and Coleen. > > Testing > Tier1 test passed. > Submit test passed. > > regards, > > > Andrew Dinn > ----------- > Senior Principal Software Engineer > Red Hat UK Ltd > Registered in England and Wales under Company Registration No. 03798903 > Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From david.holmes at oracle.com Fri Apr 5 08:45:09 2019 From: david.holmes at oracle.com (David Holmes) Date: Fri, 5 Apr 2019 18:45:09 +1000 Subject: RFR: 8221477: Inject os/cpu-specific constants into Unsafe from JVM In-Reply-To: References: <2fc62430-2e2e-9ee5-ccf1-f1cde5cea416@redhat.com> <49615c26-8ad8-ca99-a66f-d5884164d99f@redhat.com> Message-ID: Hi Peter, On 5/04/2019 5:37 pm, Peter Levart wrote: > Hi Andrew, > > For a casual reader (like me) the comments in the UnsafeConstants for > each field: > > ? 69????? * @implNote > ? 70????? * The actual value for this field is injected by the JVM. > > ...make one wonder what is actually going on regarding the static > initializer at the end of the class. Is it actually executed? Is it > there just to silence the javac and prevent fields from becoming > compile-time constants? That's what the earlier class comment is about: * @implNote * * The JVM injects hardware-specific values into all the static fields * of this class during JVM initialization. The static initialization * block exists to prevent the fields from being considered constant * variables, so the field values will be not be compiled directly into * any class that uses them. */ Cheers, David > Reading the patch further uncovers the secret: > > 3645?? // initialize the hardware-specific constants needed by Unsafe > 3646 initialize_class(vmSymbols::jdk_internal_misc_UnsafeConstants(), > CHECK); > 3647?? jdk_internal_misc_UnsafeConstants::set_unsafe_constants(); > > If my understanding is correct, then the static initializer *is* > executed and then the fields' values are overwritten with injected values. > > So perhaps it might be nice to write that down in the javadoc like: > > ? 69????? * @implNote > ? 70????? * The actual value for this field is injected by the JVM > immediately after the class initialization. > > Or something similar in the class-level javadoc. > > Just for the peace of mind of casual readers or perhaps someone that > might later add a field to this class and try to initialize it in the > static initializer, although I think this class is reserved for injected > fields only... > > Regards, Peter > > On 4/4/19 5:19 PM, Andrew Dinn wrote: >> New webrev is now available. Re-reviews welcome. >> >> JIRA:?? https://bugs.openjdk.java.net/browse/JDK-8221477 >> Webrev: http://cr.openjdk.java.net/~adinn/8221477/webrev.03 >> >> This version should address all comments from Thomas, David and Coleen. >> >> Testing >> Tier1 test passed. >> Submit test passed. >> >> regards, >> >> >> Andrew Dinn >> ----------- >> Senior Principal Software Engineer >> Red Hat UK Ltd >> Registered in England and Wales under Company Registration No. 03798903 >> Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander > From adinn at redhat.com Fri Apr 5 08:48:15 2019 From: adinn at redhat.com (Andrew Dinn) Date: Fri, 5 Apr 2019 09:48:15 +0100 Subject: RFR: 8221477: Inject os/cpu-specific constants into Unsafe from JVM In-Reply-To: References: <2fc62430-2e2e-9ee5-ccf1-f1cde5cea416@redhat.com> <49615c26-8ad8-ca99-a66f-d5884164d99f@redhat.com> Message-ID: Hi Peter, Thanks for the last-minute recommendation! On 05/04/2019 08:37, Peter Levart wrote: > For a casual reader (like me) the comments in the UnsafeConstants for > each field: > > ? 69????? * @implNote > ? 70????? * The actual value for this field is injected by the JVM. > > ...make one wonder what is actually going on regarding the static > initializer at the end of the class. Is it actually executed? Is it > there just to silence the javac and prevent fields from becoming > compile-time constants? Regarding the static initializer ... there is an explanatory implNote explaining the rationale for the static block in the class javadoc at the top of the file. I agree this could be improved by explaining that the block is executed and then its settings are overridden: * @implNote * * The JVM injects hardware-specific values into all the static fields * of this class during JVM initialization. The static initialization * block is executed when the class is initialized then JVM injection * updates the fields with the correct constants. The static block * is required to prevent the fields from being considered constant * variables, so the field values will be not be compiled directly into * any class that uses them. Regarding the field Javadoc ... I understand that an OpenJDK dev might want a correct and complete model for what exactly happens during init however that is rather a moot point as regards semantics of the value in the Java code. The nett effect is as the javadoc states -- the value is injected by the JVM and, per the text above, that value identifies the relevant hardware/os config parameter. So, I'll stop at expanding the class-level comment. > Just for the peace of mind of casual readers or perhaps someone that > might later add a field to this class and try to initialize it in the > static initializer, although I think this class is reserved for injected > fields only... Understood. I think the class-level comment already makes that latter detail explicit and the revised version gives enough warning to devs. I hope the above changes is acceptable. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From adinn at redhat.com Fri Apr 5 08:49:50 2019 From: adinn at redhat.com (Andrew Dinn) Date: Fri, 5 Apr 2019 09:49:50 +0100 Subject: RFR: 8221477: Inject os/cpu-specific constants into Unsafe from JVM In-Reply-To: References: <2fc62430-2e2e-9ee5-ccf1-f1cde5cea416@redhat.com> <49615c26-8ad8-ca99-a66f-d5884164d99f@redhat.com> Message-ID: <9f1a1032-6739-5f15-ee39-9376bbaa4c20@redhat.com> HI David, On 05/04/2019 04:54, David Holmes wrote: > Hi Andrew, > > This all looks good to me - thanks for making the changes. Thank you for the corrections and improvements. > Two nits: > - BE was barely acceptable when used like a local variable, but now I > think BIG_ENDIAN would be better. > - If you don't use static import you can name the UnsafeConstants fields > the obvious way without clashing with public fields in Unsafe. > > Feel free to ignore those nits. If you do make a change no need to see > another webrev. Well, I changed BE to BIG_ENDIAN and it doesn't look as messy as I thought. So BIG_ENDIAN it is. However, omitting the static import requires UnsafeConstants.BIG_ENDIAN at multiple mentions. That does look too cluttered for comfortable reading. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From adinn at redhat.com Fri Apr 5 09:24:46 2019 From: adinn at redhat.com (Andrew Dinn) Date: Fri, 5 Apr 2019 10:24:46 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> Message-ID: <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> Hi Alan, Thanks for the feedback. On 04/04/2019 20:47, Alan Bateman wrote: > On 03/04/2019 10:10, Andrew Dinn wrote: >> : >> I still have two undecided points you might advise on: >> >> Does the javadoc for FileChannel.map and/or FileChannelImpl.map need >> updating to record the possibility that UOE might be thrown? > I don't think I understand your question about FileChannel.map as you've > already got @throws UOE in the patch. Yes, indeed :-) > FileChannelImpl.map is JDK internal/implementation so nothing to do > there (beyond the implementation change that you already have). Ok, thanks. > I looked through webrev.01. The package description has a catch-all for > NPE so you need to specify that in each method. In the constructor it > would be better to check for length 0 before assigning name (and of > course name.length will throw NPE so you get that check for free). The > test looks okay although I would probably catch the specific exceptions > rather than catching Exception and catching them later but it amounts to > the same checking. Sorry, I am afraid I don't understand what you mean by "The package description has a catch-all for NPE so you need to specify that in each method." What is the "package description"? Which methods of which class does the term "each method" range over? I have removed the call to Objects.requireNonNull from the MapMode constructor and let the call to length generate the NPE. The assignment of field name now follows the length check. I'll await answers to the above questions before presenting another webrev. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From thomas.stuefe at gmail.com Fri Apr 5 09:46:28 2019 From: thomas.stuefe at gmail.com (=?UTF-8?Q?Thomas_St=C3=BCfe?=) Date: Fri, 5 Apr 2019 11:46:28 +0200 Subject: RFR: 8221477: Inject os/cpu-specific constants into Unsafe from JVM In-Reply-To: <49615c26-8ad8-ca99-a66f-d5884164d99f@redhat.com> References: <2fc62430-2e2e-9ee5-ccf1-f1cde5cea416@redhat.com> <49615c26-8ad8-ca99-a66f-d5884164d99f@redhat.com> Message-ID: Still looking good :) ..Thomas On Thu, Apr 4, 2019 at 5:19 PM Andrew Dinn wrote: > New webrev is now available. Re-reviews welcome. > > JIRA: https://bugs.openjdk.java.net/browse/JDK-8221477 > Webrev: http://cr.openjdk.java.net/~adinn/8221477/webrev.03 > > This version should address all comments from Thomas, David and Coleen. > > Testing > Tier1 test passed. > Submit test passed. > > regards, > > > Andrew Dinn > ----------- > Senior Principal Software Engineer > Red Hat UK Ltd > Registered in England and Wales under Company Registration No. 03798903 > Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander > From Alan.Bateman at oracle.com Fri Apr 5 09:47:33 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 5 Apr 2019 10:47:33 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> Message-ID: <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> On 05/04/2019 10:24, Andrew Dinn wrote: > : > Sorry, I am afraid I don't understand what you mean by "The package > description has a catch-all for NPE so you need to specify that in each > method." > > What is the "package description"? package-info.java has the package description. Near the end you should see the statement "Unless otherwise noted, passing a null ...".?? There are several areas of API that have statements like this to avoid cluttering the javadoc of every constructor/method that can throw NPE when invokes with a null argument. So this is why you don't see "@throws NullPointerException" here. -Alan From adinn at redhat.com Fri Apr 5 10:50:30 2019 From: adinn at redhat.com (Andrew Dinn) Date: Fri, 5 Apr 2019 11:50:30 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> Message-ID: <296e270c-0db1-1cdb-c4c3-147cbfd417ea@redhat.com> On 05/04/2019 10:47, Alan Bateman wrote: > On 05/04/2019 10:24, Andrew Dinn wrote: >> : >> Sorry, I am afraid I don't understand what you mean by "The package >> description has a catch-all for NPE so you need to specify that in each >> method." >> >> What is the "package description"? > package-info.java has the package description. Near the end you should > see the statement "Unless otherwise noted, passing a null ...".?? There > are several areas of API that have statements like this to avoid > cluttering the javadoc of every constructor/method that can throw NPE > when invokes with a null argument. So this is why you don't see "@throws > NullPointerException" here. Ah ok, got it now. I think I was confused by a missing 'not' in your original response. I have now removed the @throws for NPE from the MapMode constructor javadoc as well as letting the call to length() perform the null check. new webrev: http://cr.openjdk.java.net/~adinn/8221397/webrev.00/ JIRA: https://bugs.openjdk.java.net/browse/JDK-8221397 Testing: Successfully runs updated MapTest Submit job in progress Is this ok to push (modulo submit returning ok) or do I need another review for you and/or some other reviewer? regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From GROEGES at uk.ibm.com Fri Apr 5 10:59:34 2019 From: GROEGES at uk.ibm.com (Steve Groeger) Date: Fri, 5 Apr 2019 10:59:34 +0000 Subject: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException Message-ID: Hi all, Please could I have a review for this bug: https://bugs.openjdk.java.net/browse/JDK-8222027 The webrev is here: http://cr.openjdk.java.net/~sgroeger/8222027/webrev.00/ Thanks Steve Groeger IBM Runtime Technologies Hursley, Winchester Tel: (44) 1962 816911 Mobex: 279990 Mobile: 07718 517 129 Fax (44) 1962 816800 Lotus Notes: Steve Groeger/UK/IBM Internet: groeges at uk.ibm.com Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From daniel.fuchs at oracle.com Fri Apr 5 11:33:00 2019 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 5 Apr 2019 12:33:00 +0100 Subject: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException In-Reply-To: References: Message-ID: <501ff931-c50e-ac82-6ac6-ae71a6da0ffa@oracle.com> Hi Steve, Good analysis! I believe we can make the fix even more simpler by simply moving: TestLogger test = new TestLogger(..); LogManager.getLogManager().addLogger(test); at the beginning of main. If we do that then we can get rid of the new local variable 'tl' and of the reachabilityFence() call. I see no real reason why the test wants to obtain the TestLogger test from the LogManager. If you wanted to be extra cautious in preserving the original test then you could also add: if (test != Logger.getLogger("com.foo.bar.zzz")) { throw new AssertionError("wrong logger returned for"); } in place of line 149... best regards, -- daniel On 05/04/2019 11:59, Steve Groeger wrote: > Hi all, > > Please could I have a review for this bug: > https://bugs.openjdk.java.net/browse/JDK-8222027 > > The webrev is here: > http://cr.openjdk.java.net/~sgroeger/8222027/webrev.00/ > > Thanks > Steve Groeger > IBM Runtime Technologies > Hursley, Winchester > Tel: (44) 1962 816911 Mobex: 279990 Mobile: 07718 517 129 > Fax (44) 1962 816800 > Lotus Notes: Steve Groeger/UK/IBM > Internet: groeges at uk.ibm.com > > Unless stated otherwise above: > IBM United Kingdom Limited - Registered in England and Wales with number > 741598. > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU > Unless stated otherwise above: > IBM United Kingdom Limited - Registered in England and Wales with number > 741598. > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU > From GROEGES at uk.ibm.com Fri Apr 5 12:14:21 2019 From: GROEGES at uk.ibm.com (Steve Groeger) Date: Fri, 5 Apr 2019 12:14:21 +0000 Subject: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException In-Reply-To: <501ff931-c50e-ac82-6ac6-ae71a6da0ffa@oracle.com> References: <501ff931-c50e-ac82-6ac6-ae71a6da0ffa@oracle.com> Message-ID: Hi Daniel, Thanks for the quick review. I too didnt see why the test wanted to obtain the TestLogger from the LogManager, but I left it doing that just in case there was a reason. If you think this is not needed then I agree with your suggested modifications. I have created a new webrev here: http://cr.openjdk.java.net/~sgroeger/8222027/webrev.01/ Hopefully I understood what you were saying and these modification are OK. Please can you re-review these and let me know if OK. Thanks Steve Groeger IBM Runtime Technologies Hursley, Winchester Tel: (44) 1962 816911 Mobex: 279990 Mobile: 07718 517 129 Fax (44) 1962 816800 Lotus Notes: Steve Groeger/UK/IBM Internet: groeges at uk.ibm.com Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From: Daniel Fuchs To: Steve Groeger , OpenJDK Core Libs Developers Date: 05/04/2019 12:33 Subject: Re: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException Hi Steve, Good analysis! I believe we can make the fix even more simpler by simply moving: TestLogger test = new TestLogger(..); LogManager.getLogManager().addLogger(test); at the beginning of main. If we do that then we can get rid of the new local variable 'tl' and of the reachabilityFence() call. I see no real reason why the test wants to obtain the TestLogger test from the LogManager. If you wanted to be extra cautious in preserving the original test then you could also add: if (test != Logger.getLogger("com.foo.bar.zzz")) { throw new AssertionError("wrong logger returned for"); } in place of line 149... best regards, -- daniel On 05/04/2019 11:59, Steve Groeger wrote: > Hi all, > > Please could I have a review for this bug: > https://urldefense.proofpoint.com/v2/url?u=https-3A__bugs.openjdk.java.net_browse_JDK-2D8222027&d=DwICaQ&c=jf_iaSHvJObTbx-siA1ZOg&r=78GW2OHz7nNTH2dBkTx7-TKh2QCt3JD3zukzeUO8RpA&m=vsQw_J6ayah_8Mfm2NZW325v0r3T0Rzioj6n2akcK-U&s=pWQmGrLRqS6PRAKlVdBDQHANX9mxEh_82DFbYOnjkrM&e= > > The webrev is here: > https://urldefense.proofpoint.com/v2/url?u=http-3A__cr.openjdk.java.net_-7Esgroeger_8222027_webrev.00_&d=DwICaQ&c=jf_iaSHvJObTbx-siA1ZOg&r=78GW2OHz7nNTH2dBkTx7-TKh2QCt3JD3zukzeUO8RpA&m=vsQw_J6ayah_8Mfm2NZW325v0r3T0Rzioj6n2akcK-U&s=ywDuRVNHnc3rBAl5qGPF6xTPfy2lL213_eaNBQOOudA&e= > > Thanks > Steve Groeger > IBM Runtime Technologies > Hursley, Winchester > Tel: (44) 1962 816911 Mobex: 279990 Mobile: 07718 517 129 > Fax (44) 1962 816800 > Lotus Notes: Steve Groeger/UK/IBM > Internet: groeges at uk.ibm.com > > Unless stated otherwise above: > IBM United Kingdom Limited - Registered in England and Wales with number > 741598. > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU > Unless stated otherwise above: > IBM United Kingdom Limited - Registered in England and Wales with number > 741598. > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU > Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From daniel.fuchs at oracle.com Fri Apr 5 12:48:58 2019 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 5 Apr 2019 13:48:58 +0100 Subject: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException In-Reply-To: References: <501ff931-c50e-ac82-6ac6-ae71a6da0ffa@oracle.com> Message-ID: <1a9a27e6-d196-3fa1-fda4-9a3a80b327cc@oracle.com> Hi Steve, On 05/04/2019 13:14, Steve Groeger wrote: > Hi Daniel, > > Thanks for the quick review. > I too didnt see why the test wanted to obtain the TestLogger from the > LogManager, but I left it doing that just in case there was a reason. > If you think this is not needed then I agree with your suggested > modifications. I have created a new webrev here: > _http://cr.openjdk.java.net/~sgroeger/8222027/webrev.01/_ Perfect! Maybe remove the trailing " for" in throw new AssertionError("wrong logger returned for"); Sorry - that was my mistake... No need for a new webrev. Reviewed. best regards, -- daniel > Hopefully I understood what you were saying and these modification are > OK. Please can you re-review these and let me know if OK. > > Thanks > Steve Groeger > IBM Runtime Technologies > Hursley, Winchester > Tel: (44) 1962 816911 ?Mobex: 279990 ?Mobile: 07718 517 129 > Fax (44) 1962 816800 > Lotus Notes: Steve Groeger/UK/IBM > Internet: groeges at uk.ibm.com > > Unless stated otherwise above: > IBM United Kingdom Limited - Registered in England and Wales with number > 741598. > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU > > > > From: Daniel Fuchs > To: Steve Groeger , OpenJDK Core Libs Developers > > Date: 05/04/2019 12:33 > Subject: Re: RFR: TEST_BUG: 8222027 - > java/util/logging/LogManager/TestLoggerNames.java generates intermittent > ClassCastException > ------------------------------------------------------------------------ > > > > Hi Steve, > > Good analysis! I believe we can make the fix even > more simpler by simply moving: > > TestLogger test = new TestLogger(..); > LogManager.getLogManager().addLogger(test); > > at the beginning of main. If we do that then we can get > rid of the new local variable 'tl' and of the > reachabilityFence() call. > > I see no real reason why the test wants to obtain > the TestLogger test from the LogManager. > > If you wanted to be extra cautious in preserving the original > test then you could also add: > > if (test != Logger.getLogger("com.foo.bar.zzz")) { > ? ? throw new AssertionError("wrong logger returned for"); > } > > in place of line 149... > > best regards, > > -- daniel > > On 05/04/2019 11:59, Steve Groeger wrote: > > Hi all, > > > > Please could I have a review for this bug: > > https://bugs.openjdk.java.net/browse/JDK-8222027 > > > > The webrev is here: > > http://cr.openjdk.java.net/~sgroeger/8222027/webrev.00/ > > > > Thanks > > Steve Groeger > > IBM Runtime Technologies > > Hursley, Winchester > > Tel: (44) 1962 816911 ?Mobex: 279990 ?Mobile: 07718 517 129 > > Fax (44) 1962 816800 > > Lotus Notes: Steve Groeger/UK/IBM > > Internet: groeges at uk.ibm.com > > > > Unless stated otherwise above: > > IBM United Kingdom Limited - Registered in England and Wales with number > > 741598. > > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire > PO6 3AU > > Unless stated otherwise above: > > IBM United Kingdom Limited - Registered in England and Wales with number > > 741598. > > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire > PO6 3AU > > > > > > > > Unless stated otherwise above: > IBM United Kingdom Limited - Registered in England and Wales with number > 741598. > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From peter.levart at gmail.com Fri Apr 5 12:52:10 2019 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 5 Apr 2019 14:52:10 +0200 Subject: RFR: 8221477: Inject os/cpu-specific constants into Unsafe from JVM In-Reply-To: References: <2fc62430-2e2e-9ee5-ccf1-f1cde5cea416@redhat.com> <49615c26-8ad8-ca99-a66f-d5884164d99f@redhat.com> Message-ID: <6887a4dc-928f-70bc-fa1d-36cd743ac6f5@gmail.com> On 4/5/19 10:48 AM, Andrew Dinn wrote: > Hi Peter, > > Regarding the static initializer ... there is an explanatory implNote > explaining the rationale for the static block in the class javadoc at > the top of the file. I agree this could be improved by explaining that > the block is executed and then its settings are overridden: > > * @implNote > * > * The JVM injects hardware-specific values into all the static fields > * of this class during JVM initialization. The static initialization > * block is executed when the class is initialized then JVM injection > * updates the fields with the correct constants. The static block > * is required to prevent the fields from being considered constant > * variables, so the field values will be not be compiled directly into > * any class that uses them. > > Regarding the field Javadoc ... I understand that an OpenJDK dev might > want a correct and complete model for what exactly happens during init > however that is rather a moot point as regards semantics of the value in > the Java code. The nett effect is as the javadoc states -- the value is > injected by the JVM and, per the text above, that value identifies the > relevant hardware/os config parameter. So, I'll stop at expanding the > class-level comment. > >> Just for the peace of mind of casual readers or perhaps someone that >> might later add a field to this class and try to initialize it in the >> static initializer, although I think this class is reserved for injected >> fields only... > Understood. I think the class-level comment already makes that latter > detail explicit and the revised version gives enough warning to devs. > > I hope the above changes is acceptable. It is precisely what I was thinking about. It's understood that the @implNote on fields is enough for the users of the UnsafeConstants class since the injection happens magically as "part of class initialization" for them. The only place where the timing of injection is observable from Java code is in the class initializer itself where the fields are set to default values and injection hasn't happened yet... Regards, Peter > regards, > > > Andrew Dinn > ----------- > Senior Principal Software Engineer > Red Hat UK Ltd > Registered in England and Wales under Company Registration No. 03798903 > Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From GROEGES at uk.ibm.com Fri Apr 5 13:01:41 2019 From: GROEGES at uk.ibm.com (Steve Groeger) Date: Fri, 5 Apr 2019 13:01:41 +0000 Subject: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException In-Reply-To: <1a9a27e6-d196-3fa1-fda4-9a3a80b327cc@oracle.com> References: <501ff931-c50e-ac82-6ac6-ae71a6da0ffa@oracle.com> <1a9a27e6-d196-3fa1-fda4-9a3a80b327cc@oracle.com> Message-ID: Hi Daniel, Thanks. I should have spotted that slight mistake. That is what comes from just cutting and pasting. Have created a new webrev anyway: http://cr.openjdk.java.net/~sgroeger/8222027/webrev.02/ I presume I need someone else to review this and also get a sponsor (so they can actually make the change) as I am not a committer (YET!!!) Do you know anyone that can do this for me? Thanks Steve Groeger IBM Runtime Technologies Hursley, Winchester Tel: (44) 1962 816911 Mobex: 279990 Mobile: 07718 517 129 Fax (44) 1962 816800 Lotus Notes: Steve Groeger/UK/IBM Internet: groeges at uk.ibm.com Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From: Daniel Fuchs To: Steve Groeger Cc: OpenJDK Core Libs Developers Date: 05/04/2019 13:51 Subject: Re: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException Hi Steve, On 05/04/2019 13:14, Steve Groeger wrote: > Hi Daniel, > > Thanks for the quick review. > I too didnt see why the test wanted to obtain the TestLogger from the > LogManager, but I left it doing that just in case there was a reason. > If you think this is not needed then I agree with your suggested > modifications. I have created a new webrev here: > _https://urldefense.proofpoint.com/v2/url?u=http-3A__cr.openjdk.java.net_-7Esgroeger_8222027_webrev.01_-5F&d=DwID-g&c=jf_iaSHvJObTbx-siA1ZOg&r=78GW2OHz7nNTH2dBkTx7-TKh2QCt3JD3zukzeUO8RpA&m=Df0w0-wNA_rWl-TkWAFLlG6aQu1TT5WHca1Uzlnx8G0&s=Fcqc74kaTxOKtJS9P_kQ-qQak7U377oypPD77yt38gM&e= Perfect! Maybe remove the trailing " for" in throw new AssertionError("wrong logger returned for"); Sorry - that was my mistake... No need for a new webrev. Reviewed. best regards, -- daniel > Hopefully I understood what you were saying and these modification are > OK. Please can you re-review these and let me know if OK. > > Thanks > Steve Groeger > IBM Runtime Technologies > Hursley, Winchester > Tel: (44) 1962 816911 Mobex: 279990 Mobile: 07718 517 129 > Fax (44) 1962 816800 > Lotus Notes: Steve Groeger/UK/IBM > Internet: groeges at uk.ibm.com > > Unless stated otherwise above: > IBM United Kingdom Limited - Registered in England and Wales with number > 741598. > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU > > > > From: Daniel Fuchs > To: Steve Groeger , OpenJDK Core Libs Developers > > Date: 05/04/2019 12:33 > Subject: Re: RFR: TEST_BUG: 8222027 - > java/util/logging/LogManager/TestLoggerNames.java generates intermittent > ClassCastException > ------------------------------------------------------------------------ > > > > Hi Steve, > > Good analysis! I believe we can make the fix even > more simpler by simply moving: > > TestLogger test = new TestLogger(..); > LogManager.getLogManager().addLogger(test); > > at the beginning of main. If we do that then we can get > rid of the new local variable 'tl' and of the > reachabilityFence() call. > > I see no real reason why the test wants to obtain > the TestLogger test from the LogManager. > > If you wanted to be extra cautious in preserving the original > test then you could also add: > > if (test != Logger.getLogger("com.foo.bar.zzz")) { > throw new AssertionError("wrong logger returned for"); > } > > in place of line 149... > > best regards, > > -- daniel > > On 05/04/2019 11:59, Steve Groeger wrote: > > Hi all, > > > > Please could I have a review for this bug: > > https://urldefense.proofpoint.com/v2/url?u=https-3A__bugs.openjdk.java.net_browse_JDK-2D8222027&d=DwID-g&c=jf_iaSHvJObTbx-siA1ZOg&r=78GW2OHz7nNTH2dBkTx7-TKh2QCt3JD3zukzeUO8RpA&m=Df0w0-wNA_rWl-TkWAFLlG6aQu1TT5WHca1Uzlnx8G0&s=ZA3MXC7DrYMf7UBacMB-BeS9MVxWoZvSIrcuzPjhW8o&e= > > > > The webrev is here: > > https://urldefense.proofpoint.com/v2/url?u=http-3A__cr.openjdk.java.net_-7Esgroeger_8222027_webrev.00_&d=DwID-g&c=jf_iaSHvJObTbx-siA1ZOg&r=78GW2OHz7nNTH2dBkTx7-TKh2QCt3JD3zukzeUO8RpA&m=Df0w0-wNA_rWl-TkWAFLlG6aQu1TT5WHca1Uzlnx8G0&s=aQ7Xz4DUgXgJDrV6Y-ZE0AiDjJtOugZv1StE-2kuff4&e= > > > > Thanks > > Steve Groeger > > IBM Runtime Technologies > > Hursley, Winchester > > Tel: (44) 1962 816911 Mobex: 279990 Mobile: 07718 517 129 > > Fax (44) 1962 816800 > > Lotus Notes: Steve Groeger/UK/IBM > > Internet: groeges at uk.ibm.com > > > > Unless stated otherwise above: > > IBM United Kingdom Limited - Registered in England and Wales with number > > 741598. > > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire > PO6 3AU > > Unless stated otherwise above: > > IBM United Kingdom Limited - Registered in England and Wales with number > > 741598. > > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire > PO6 3AU > > > > > > > > Unless stated otherwise above: > IBM United Kingdom Limited - Registered in England and Wales with number > 741598. > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From daniel.fuchs at oracle.com Fri Apr 5 13:31:52 2019 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 5 Apr 2019 14:31:52 +0100 Subject: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException In-Reply-To: References: <501ff931-c50e-ac82-6ac6-ae71a6da0ffa@oracle.com> <1a9a27e6-d196-3fa1-fda4-9a3a80b327cc@oracle.com> Message-ID: On 05/04/2019 14:01, Steve Groeger wrote: > Hi Daniel, > > Thanks. I should have spotted that slight mistake. That is what comes > from just cutting and pasting. > Have created a new webrev anyway: > _http://cr.openjdk.java.net/~sgroeger/8222027/webrev.02/_ > I presume I need someone else to review this and also get a sponsor (so > they can actually make the change) as I am not a committer (YET!!!) > Do you know anyone that can do this for me? If you don't have a sponsor at IBM I can sponsor it for you. You will need to make a proper changeset that can be hg imported. (simplest way is to hg commit the change in your local workspace with the proper commit comment [1] and call webrev again, then do hg rollback immediately after). BTW since this is a a test bug then the @bug tag doesn't need to be updated. Instead you should add a noreg-self label to the JBS issue, if it's not already there. [1] http://openjdk.java.net/guide/producingChangeset.html best regards, -- daniel From claes.redestad at oracle.com Fri Apr 5 13:44:26 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 5 Apr 2019 15:44:26 +0200 Subject: RFR: 8222029: Optimize Math.floorMod Message-ID: Hi, currently Math.floorMod is implemented as: return x - floorDiv(x, y) * y; This can be optimized as: int mod = x % y; // if the signs are different and modulo not zero, adjust result if ((mod ^ y) < 0 && mod != 0) { mod += y; } return mod; While the JIT does a reasonably good job at the current implementation, this ensures we only do a single integer division and no subsequent integer multiplications, speeding up execution by ~1.3x in interpreter (mainly from removing the floorDiv method call overhead) and ~1.1x with C1 and C2. Testing: tier1-2, all Math tests run locally, -prof perfasm verification on the provided microbenchmark. Thanks! /Claes From aph at redhat.com Fri Apr 5 15:41:58 2019 From: aph at redhat.com (Andrew Haley) Date: Fri, 5 Apr 2019 16:41:58 +0100 Subject: RFR: 8222029: Optimize Math.floorMod In-Reply-To: References: Message-ID: <407d708a-ab81-bf8a-63fb-d3d769cfe1c3@redhat.com> On 4/5/19 2:44 PM, Claes Redestad wrote: > Testing: tier1-2, all Math tests run locally, -prof perfasm verification > on the provided microbenchmark. Looks good. I've kicked the tyres on AArch64, and it looks like a useful optimization. The gains when the divisor is constant (a common case) are modest but worthwhile. -- Andrew Haley Java Platform Lead Engineer Red Hat UK Ltd. EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671 From stuart.marks at oracle.com Fri Apr 5 16:30:47 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Fri, 5 Apr 2019 09:30:47 -0700 Subject: RFR: 8221924: get(null) on single-entry unmodifiable Map returns null instead of throwing NPE In-Reply-To: <253385b4-86c4-edab-3b2d-f7e9991371c2@gmail.com> References: <253385b4-86c4-edab-3b2d-f7e9991371c2@gmail.com> Message-ID: On 4/5/19 12:04 AM, Peter Levart wrote: > Map1.get() should be much faster with this patch too, right? Heh. I suspect it is faster, since it no longer needs to create and entryset and the iterator over the entryset. Claes and I have been chatting a lot about micro-optimizations in this area, as you can see, and while he stumbled over this behavioral problem, neither of us thought to benchmark it. I guess, if it's incorrect, the performance doesn't matter. Fortunately in this case the result is both more consistent and faster, so we don't have to confront the "how much do we want to pay for correctness" tradeoff. s'marks From claes.redestad at oracle.com Fri Apr 5 17:21:00 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 5 Apr 2019 19:21:00 +0200 Subject: RFR: 8222029: Optimize Math.floorMod In-Reply-To: <407d708a-ab81-bf8a-63fb-d3d769cfe1c3@redhat.com> References: <407d708a-ab81-bf8a-63fb-d3d769cfe1c3@redhat.com> Message-ID: <5d2c75de-474c-4376-3587-cfee6100f920@oracle.com> On 2019-04-05 17:41, Andrew Haley wrote: > On 4/5/19 2:44 PM, Claes Redestad wrote: >> Testing: tier1-2, all Math tests run locally, -prof perfasm verification >> on the provided microbenchmark. > > Looks good. Thanks! > > I've kicked the tyres on AArch64, and it looks like a useful optimization. The > gains when the divisor is constant (a common case) are modest but worthwhile. > Thanks for trying it out and glad to hear it helps on AArch64 as well. /Claes From stuart.marks at oracle.com Fri Apr 5 22:04:59 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Fri, 5 Apr 2019 15:04:59 -0700 Subject: RFR: 8221924: get(null) on single-entry unmodifiable Map returns null instead of throwing NPE In-Reply-To: References: Message-ID: Hi all, Can I get a review of the CSR for this change? https://bugs.openjdk.java.net/browse/JDK-8222002 The CSR is mostly a restatement of the issue, somewhat more complete, along with an assessment of the compatibility risk (low but nonzero). Thanks, s'marks On 4/4/19 2:11 PM, Stuart Marks wrote: > Hi all, > > An unmodifiable map with one entry doesn't throw NPE from get(null). Instead, it > returns null. This makes it quite an outlier: > > Map.of().get(null) ==> NPE > Map.of().containsKey(null) ==> NPE > Map.of().containsValue(null) ==> NPE > > Map.of(1, 2).get(null) ==> returns null? *** > Map.of(1, 2).containsKey(null) ==> NPE > Map.of(1, 2).containsValue(null) ==> NPE > > Map.of(1, 2, 3, 4).get(null) ==> NPE > Map.of(1, 2, 3, 4).containsKey(null) ==> NPE > Map.of(1, 2, 3, 4).containsValue(null) ==> NPE > > It should be fixed to throw NPE like all the other cases. > > This is a tiny incompatible change, so I intend to file a CSR. Tier1, 2, and 3 > tests all pass though. > > I think this change should also be backported to 11. We're fairly early in the > 11 LTS lifetime, so it'd be good to fix this now. > > Bug: > > ????https://bugs.openjdk.java.net/browse/JDK-8221924 > > Webrev: > > ????http://cr.openjdk.java.net/~smarks/reviews/8221924/webrev.0/ > > Thanks, > > s'marks From ivan.gerasimov at oracle.com Sat Apr 6 05:43:57 2019 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Fri, 5 Apr 2019 22:43:57 -0700 Subject: Request for sponsor: JDK-8221430: StringBuffer(CharSequence) constructor truncates when -XX:-CompactStrings specified In-Reply-To: <61d962e5-4e52-c401-25be-4eb1e848e422@oracle.com> References: <08ffa0f7-4cbd-c946-2250-ddcb8bed612f@oracle.com> <64ea5dc1-990f-f772-d970-1b0b24f3dc9b@oracle.com> <5160cae7-d4d7-3edd-5045-e09c0a52ad71@oracle <257e94c4-2429-89a0-50df-ed020c0093d2@oracle.com> <61d962e5-4e52-c401-25be-4eb1e848e422@oracle.com> Message-ID: <7665bb39-b15a-0e5d-ce1d-f843f5c385fa@oracle.com> Hi Roger! On 4/1/19 8:06 AM, Roger Riggs wrote: > Hi Ivan, > > Thanks for running the micro benchmarks. > > This version has more code duplication than Andrew's original > proposal that calculated the coder only CharSequence and had > a single AbstractStringBuilder constructor for computing the size > and allocating the byte[]/ > > http://cr.openjdk.java.net/~aleonard/8221430/webrev.00/ > > I'd be curious to know the JMH tests for that version compared. > That variant appeared to be slightly slower, comparing to the latest variant: Here are fresh benchmarks for both variants (1) cr.openjdk.java.net/~aleonard/8221430/webrev.00 : Benchmark Mode Cnt Score Error Units StringBuilders.fromLatin1String avgt 18 15.217 ? 0.157 ns/op StringBuilders.fromLatin1StringBuilder avgt 18 19.169 ? 0.086 ns/op StringBuilders.fromUtf16String avgt 18 17.593 ? 0.180 ns/op StringBuilders.fromUtf16StringBuilder avgt 18 21.786 ? 0.158 ns/op (2) cr.openjdk.java.net/~igerasim/8221430/02/webrev : Benchmark Mode Cnt Score Error Units StringBuilders.fromLatin1String avgt 18 14.655 ? 0.133 ns/op StringBuilders.fromLatin1StringBuilder avgt 18 18.059 ? 0.161 ns/op StringBuilders.fromUtf16String avgt 18 16.675 ? 0.124 ns/op StringBuilders.fromUtf16StringBuilder avgt 18 20.761 ? 0.116 ns/op One reason might be that (2) avoids a redundant check for negative length of the String argument. > Another comment is whether the 'instanceof' code is the > best performer for checking if the argument is a String. > I might think that 'seq.getClass().equals(String.class)' is faster. > Interesting. I don't see examples of such pattern in JDK. Anyhow, I think that the case when a StringBuilder is constructed from a String down-cast to CharSequence should be rare in practice, so it is sensible to keep the code more ideomatic, i.e. use instanceof. > And in this most recent webrev that has separated the > AbstractStringBuilder > constructors for String from CharSequence, is it more likely that the > argument > will be an AbstractStringBuilder than a String so that comparison > should be done first. > Yes, it's a good point! I reordered the branches in the latest webrev. With kind regards, Ivan From Alan.Bateman at oracle.com Sat Apr 6 18:05:42 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Sat, 6 Apr 2019 19:05:42 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: <296e270c-0db1-1cdb-c4c3-147cbfd417ea@redhat.com> References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> <296e270c-0db1-1cdb-c4c3-147cbfd417ea@redhat.com> Message-ID: On 05/04/2019 11:50, Andrew Dinn wrote: > : > Ah ok, got it now. I think I was confused by a missing 'not' in your > original response. > > I have now removed the @throws for NPE from the MapMode constructor > javadoc as well as letting the call to length() perform the null check. > > new webrev: http://cr.openjdk.java.net/~adinn/8221397/webrev.00/ > JIRA: https://bugs.openjdk.java.net/browse/JDK-8221397 > This versions look, I assume you'll create the CSR and wait for it to be approved before pushing. -Alan From sergei.tsypanov at yandex.ru Sat Apr 6 19:54:54 2019 From: sergei.tsypanov at yandex.ru (=?utf-8?B?0KHQtdGA0LPQtdC5INCm0YvQv9Cw0L3QvtCy?=) Date: Sat, 06 Apr 2019 21:54:54 +0200 Subject: [PATCH] Some improvements for java.lang.Class In-Reply-To: <7147981554385366@myt6-27270b78ac4f.qloud-c.yandex.net> References: <2796501552936166@myt6-add70abb4f02.qloud-c.yandex.net> <352521553106953@myt5-184376c2d7f8.qloud-c.yandex.net> <1a181b47-e392-c1f7-1ecc-2cf1ab5cd4d2@gmail.com> <10151351553631340@myt6-fe24916a5562.qloud-c.yandex.net> <7DEC01F5-AD44-4E50-BBEE-F493AB63583B@oracle.com> <7147981554385366@myt6-27270b78ac4f.qloud-c.yandex.net> Message-ID: <23961631554580494@sas1-46c84f197234.qloud-c.yandex.net> It' seems messages sent from Yandex Mail mobile application are not delivered, so I repeat it from web app. --------------------------- Hello, Yes I?m willing to take this As I understand there is the code imported from 3rd party projects which shouldn?t be touched. I know only about jdk.internal.org.objectweb.* Are there any other similar places? Also what about the task to bind the changes to? I?m talking about this one and changes to java.lang.Class::methodToString. Sergei Tsypanov 22:03, 3 ?????? 2019 ?., Brian Goetz : > I agree that getting rid of the append(concatenation) is a good move regardless; that?s just wasteful movement. The rest of the patch seems harmless. > > As to applying the refactor more broadly, there?s a risk of recreating the ?append(concatenation)? problem, where the concatenation is hidden inside the call to repeat(). A loop over append() is likely to be more performant than append(s.repeat()), even those the latter is more abstract and harder to get wrong. > > If you?re willing to take the auto-refactor result and hand-edit it to eliminate the cases where we?d create new append(concat) situations, I?d be supportive of that as well. > >> ?On Mar 26, 2019, at 4:15 PM, ?????? ??????? wrote: >> >> ?Hello Peter, >> >> ?I was unaware of mentioned detail (thank you a lot for pointing that out, it made me read the whole JEP280 again) so I've rebenchmarked my changes compiled with -XDstringConcat=inline. >> >> ?1) as of Class::getTypeName for Object[] it turned out, that String::repeat performs slightly better: >> >> ?Benchmark Mode Cnt Score Error Units >> >> ?getTypeName_patched avgt 25 36,676 ? 3,559 ns/op >> ?getTypeName avgt 25 39,083 ? 1,737 ns/op >> >> ?getTypeName_patched:?gc.alloc.rate.norm avgt 25 152,000 ? 0,001 B/op >> ?getTypeName:?gc.alloc.rate.norm avgt 25 152,000 ? 0,001 B/op >> >> ?But for Object[][] situation is the opposite: >> >> ????????????????????????????????????????????????????????????Mode Cnt Score Error Units >> >> ?getTypeName_patched avgt 50 47,045 ? 0,455 ns/op >> ?getTypeName avgt 50 40,536 ? 0,196 ns/op >> >> ?getTypeName_patched:?gc.alloc.rate.norm avgt 50 176,000 ? 0,001 B/op >> ?getTypeName:?gc.alloc.rate.norm avgt 50 152,000 ? 0,001 B/op >> >> ?2) as of Class::methodToString patched version clearly wins: >> >> ?methodToString_1arg avgt 50 238,476 ? 1,641 ns/op >> ?methodToString_1arg_patched avgt 50 197,900 ? 5,824 ns/op >> >> ?methodToString_1arg:?gc.alloc.rate.norm avgt 50 1209,600 ? 6,401 B/op >> ?methodToString_1arg_patched:?gc.alloc.rate.norm avgt 50 936,000 ? 0,001 B/op >> >> ?methodToString_noArgs avgt 50 224,054 ? 1,840 ns/op >> ?methodToString_noArgs_patched avgt 50 78,195 ? 0,418 ns/op >> >> ?methodToString_noArgs:?gc.alloc.rate.norm avgt 50 1131,200 ? 7,839 B/op >> ?methodToString_noArgs_patched:?gc.alloc.rate.norm avgt 50 408,000 ? 0,001 B/op >> >> ?As Brian suggested I've separated the changes. The patch attached contains only the changes for Class::methodToString. They are obviously helpful as they rid concatenation as argument of StringBuilder::append call (obvious antipattern to me) and skip Stream creation for empty array. >> >> ?String::repeat obviously requires more investigation, it might turn out we don't need it in java.base in majority of use cases or in all of them. >> >> ?Regards, >> ?Sergei Tsypanov >> >> ?21.03.2019, 00:56, "Peter Levart" : >>> ?Hi Sergei, >>> >>> ?I don't know if you are aware that the new invokedynamic based >>> ?translation of string concatenation expressions introduced in JDK 9 >>> ?(http://openjdk.java.net/jeps/280) only applies to code outside >>> ?java.base module. java.base module is still compiled with old-style >>> ?StringBuilder based translation of string concatenation expressions >>> ?because of bootstraping issues. >>> >>> ?If your benchmarks bellow are compiled with option >>> ?-XDstringConcat=inline to disable JEP280 translation (as java.base >>> ?module is), then it's OK. Else you are not benchmarking the right >>> ?translation of the code as you intend to change the code in java.base >>> ?module. >>> >>> ?Regards, Peter >>> >>> ?On 3/20/19 7:35 PM, ?????? ??????? wrote: >>>> ??I had a brief conversation with Brian Goetz which has left off the mailing list for some reason. Here's the text: >>>> ??--------------------------- >>>> ??Brian: >>>> >>>> ??These enhancements seem reasonable; these are exactly the cases that String::repeat was intended for. (This is a ?is this a reasonable idea? review, not a code review.). >>>> ??Have you looked for other places where similar transformations could be done? >>>> >>>> ??--------------------------- >>>> ??Me: >>>> >>>> ??Hello, >>>> ??after I had realized that looped StringBuilder::append calls can sometimes be replaced with String::repeat I requested corresponding inspection in IDEA issue tracker. >>>> ??Using the inspection I?ve found 129 similar warnings in jdk13 repo. >>>> ??Some of them are very promising, e.g. BigDecimal:: toPlainString where currently we have >>>> >>>>> ??int trailingZeros = checkScaleNonZero((-(long)scale)); >>>>> ??StringBuilder buf; >>>>> ??if(intCompact!=INFLATED) { >>>>> ???????buf = new StringBuilder(20+trailingZeros); >>>>> ???????buf.append(intCompact); >>>>> ??} else { >>>>> ???????String str = intVal.toString(); >>>>> ???????buf = new StringBuilder(str.length()+trailingZeros); >>>>> ???????buf.append(str); >>>>> ??} >>>>> ??for (int i = 0; i < trailingZeros; i++) { >>>>> ???????buf.append('0'); >>>>> ??} >>>>> ??return buf.toString(); >>>> ??which in fact can be simplified to >>>> >>>>> ??int trailingZeros = checkScaleNonZero((-(long)scale)); >>>>> ??if(intCompact!=INFLATED) { >>>>> ???????return intCompact + "0".repeat(trailingZeros); >>>>> ??} else { >>>>> ???????return intVal.toString() + "0".repeat(trailingZeros); >>>>> ??} >>>> ??The second solution is not only shorter and more simple but it likely to be significantly faster and memory-saving. >>>> ??BTW, your reply to original message for some reason is missing from web-view. >>>> >>>> ??--------------------------- >>>> ??Brian: >>>> >>>> ??Cool. Note that replacing append() calls with repeat is not necessarily a win for anything other than code compactness; String::repeat will create a new string, which will then get appended to another StrinBuilder. So when used correctly (such as presized StringBuilders) appending in a loop is probably just as fast (look at the implementation of String::repeat.). >>>> >>>>> ??if(intCompact!=INFLATED) { >>>>> ???????return intCompact + "0".repeat(trailingZeros); >>>>> ??} else { >>>>> ???????return intVal.toString() + "0".repeat(trailingZeros); >>>>> ??} >>>> ??Which can be further simplified to >>>> >>>>> ??????((intCompact != INFLATED) ? intCompact : intVal.toString) + ?0?.repeat(trailingZeros); >>>> >>>> ??The second solution is not only shorter and more simple but it likely to be significantly faster and memory-saving. >>>> ??I like short and simple. I am questioning the ?faster and memory saving.? That should be validated. >>>> >>>> ??--------------------------- >>>> ??Me: >>>> >>>> ??I think optimizations provided by JEP 280 allow compiler to optimize String concatenation executed with '+' by using StringBuilder of exact size (when the size of all components is known, like in our case). >>>> >>>> ??I've checked this with benchmark >>>> >>>>> ??@State(Scope.Thread) >>>>> ??@BenchmarkMode(Mode.AverageTime) >>>>> ??@OutputTimeUnit(TimeUnit.NANOSECONDS) >>>>> ??@Fork(jvmArgsAppend = {"-Xms2g", "-Xmx2g"}) >>>>> ??public class ConcatBenchmark { >>>>> >>>>> ???????@Param({"1", "2", "5", "8"}) >>>>> ???????private int trailingZeros; >>>>> >>>>> ???????private final long intCompact = 1L; >>>>> >>>>> ???????@Benchmark >>>>> ???????public String stringBuilder() { >>>>> ???????????StringBuilder buf; >>>>> ???????????buf = new StringBuilder(20 + trailingZeros); >>>>> ???????????buf.append(intCompact); >>>>> ???????????for (int i = 0; i < trailingZeros; i++) { >>>>> ???????????????buf.append('0'); >>>>> ???????????} >>>>> ???????????return buf.toString(); >>>>> ???????} >>>>> ???????@Benchmark >>>>> ???????public String stringRepeat() { >>>>> ???????????return intCompact + "0".repeat(trailingZeros); >>>>> ???????} >>>>> ??} >>>> ??Results: >>>> ???????????????????????????????????????????trailingZeros Mode Cnt Score Error Units >>>> ??stringBuilder 1 avgt 15 17,683 ? 0,664 ns/op >>>> ??stringRepeat 1 avgt 15 9,052 ? 0,042 ns/op >>>> >>>> ??stringBuilder 2 avgt 15 19,053 ? 1,206 ns/op >>>> ??stringRepeat 2 avgt 15 15,864 ? 1,331 ns/op >>>> >>>> ??stringBuilder 5 avgt 15 25,839 ? 2,256 ns/op >>>> ??stringRepeat 5 avgt 15 19,290 ? 1,685 ns/op >>>> >>>> ??stringBuilder 8 avgt 15 26,488 ? 0,371 ns/op >>>> ??stringRepeat 8 avgt 15 19,420 ? 1,593 ns/op >>>> >>>> ??stringBuilder:?gc.alloc.rate.norm 1 avgt 15 88,000 ? 0,001 B/op >>>> ??stringRepeat:?gc.alloc.rate.norm 1 avgt 15 48,000 ? 0,001 B/op >>>> >>>> ??stringBuilder:?gc.alloc.rate.norm 2 avgt 15 88,000 ? 0,001 B/op >>>> ??stringRepeat:?gc.alloc.rate.norm 2 avgt 15 72,000 ? 0,001 B/op >>>> >>>> ??stringBuilder:?gc.alloc.rate.norm 5 avgt 15 96,000 ? 0,001 B/op >>>> ??stringRepeat:?gc.alloc.rate.norm 5 avgt 15 72,000 ? 0,001 B/op >>>> >>>> ??stringBuilder:?gc.alloc.rate.norm 8 avgt 15 104,000 ? 0,001 B/op >>>> ??stringRepeat:?gc.alloc.rate.norm 8 avgt 15 80,000 ? 0,001 B/op >>>> >>>> ??I think this is a useful optimization, so we should use String::repeat where possible. >>>> >>>> ??--------------------------- >>>> ??Brian: >>>> >>>> ??My recommendation is to split your patch into two. The first is the straightforward ?replace loop with repeat? refactoring, which can be mechanically generated by the IDE. Here, you should examine each site to ensure that the transform seems sensible given the context. The second can then be additional hand-refactoring opportunities exposed by the first. The benefit of splitting it this way is that reviewing the first is far easier when you can say all the changes are mechanical. >>>> >>>> ??(Somehow this fell off the list; feel free to bring it back.) >>>> >>>> ??18.03.2019, 21:13, "?????? ???????" : >>>>> ??Hi, >>>>> >>>>> ??I have an enhancement proposal for java.lang.Class.methodToString and java.lang.Class.getTypeName. >>>>> >>>>> ??First one is used when NoSuchMethodException is thrown from Class::getMethod which is in turn widely used in Spring Framework and often throws. >>>>> >>>>> ??In current implementation we have 2 major problems: >>>>> >>>>> ??- we create stream for the case when argTypes is not null but empty (which happens e. g. when Class::getMethod is called without vararg and throws) >>>>> ??- we have torn StringBuilder::append chain >>>>> >>>>> ??I?ve modified the method to skip creation of Stream for empty array and used separate StringBuilder for each case. Latter allowed to rid SB completely and use invokedynamic-based concatenation. >>>>> >>>>> ??I?ve compared both approaches for 2 cases: >>>>> >>>>> ??1) argTypes is empty >>>>> ??2) argTypes.length == 1 >>>>> >>>>> ??Benchmark Mode Cnt Score Error Units >>>>> >>>>> ??methodToString_noArgs avgt 25 170,986 ? 5,708 ns/op >>>>> ??methodToString_noArgs_patched avgt 25 26,883 ? 2,906 ns/op >>>>> >>>>> ??methodToString_1arg avgt 25 183,012 ? 0,701 ns/op >>>>> ??methodToString_1arg_patched avgt 25 112,784 ? 0,920 ns/op >>>>> >>>>> ??methodToString_noArgs:?gc.alloc.rate.norm avgt 25 881,600 ? 9,786 B/op >>>>> ??methodToString_noArgs_patched:?gc.alloc.rate.norm avgt 25 128,000 ? 0,001 B/op >>>>> >>>>> ??methodToString_1arg:?gc.alloc.rate.norm avgt 25 960,000 ? 0,001 B/op >>>>> ??methodToString_1arg_patched:?gc.alloc.rate.norm avgt 25 552,000 ? 0,001 B/op >>>>> >>>>> ??We have the same problem regarding misusage of StringBuilder in Class:: getTypeName: >>>>> >>>>> ??StringBuilder sb = new StringBuilder(); >>>>> ??sb.append(cl.getName()); >>>>> ??for (int i = 0; i < dimensions; i++) { >>>>> ???????sb.append("[]"); >>>>> ??} >>>>> ??return sb.toString(); >>>>> >>>>> ??I suggest to use String::repeat instead of the loop: this again allows to get rid of StringBuilder and replace mentioned code with >>>>> >>>>> ??return cl.getName() + "[]".repeat(dimensions); >>>>> >>>>> ??Here are benchmark results executed for type Object[].class: >>>>> >>>>> ?????????????????????????????????????????????Mode Cnt Score Error Units >>>>> ??getTypeName_patched avgt 25 16,037 ? 0,431 ns/op >>>>> ??getTypeName_patched:?gc.alloc.rate.norm avgt 25 64,000 ? 0,001 B/op >>>>> >>>>> ??getTypeName avgt 25 34,274 ? 1,432 ns/op >>>>> ??getTypeName:?gc.alloc.rate.norm avgt 25 152,000 ? 0,001 B/op >>>>> >>>>> ??Regards, >>>>> ??Sergei Tsypanov >> ? -- ?????????? ?? ?????????? ?????????? ??????.????? From mandy.chung at oracle.com Sat Apr 6 23:37:52 2019 From: mandy.chung at oracle.com (Mandy Chung) Date: Sun, 7 Apr 2019 07:37:52 +0800 Subject: (1-line) Review Request: 8222078: test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c build fails after 8221530 Message-ID: <01c65189-49fe-0c55-82a6-6f8c95725d69@oracle.com> A simple test fix.? The test causes the build failure. Thanks Mandy diff --git a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c --- a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c +++ b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c @@ -34,6 +34,7 @@ ?static jmethodID mid_Field_get; ?int getField(JNIEnv *env, char* declaringClass_name, char* field_name); +int checkAndClearIllegalAccessExceptionThrown(JNIEnv *env); ?int main(int argc, char** args) { ???? JavaVM *jvm; From Lance.Andersen at oracle.com Sun Apr 7 00:46:29 2019 From: Lance.Andersen at oracle.com (Lance Andersen) Date: Sat, 6 Apr 2019 20:46:29 -0400 Subject: (1-line) Review Request: 8222078: test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c build fails after 8221530 In-Reply-To: <01c65189-49fe-0c55-82a6-6f8c95725d69@oracle.com> References: <01c65189-49fe-0c55-82a6-6f8c95725d69@oracle.com> Message-ID: <0DFA381F-254E-43B7-A304-A914971E9F3E@oracle.com> +1 -- 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 Apr 6, 2019, at 7:37 PM, Mandy Chung wrote: > > A simple test fix. The test causes the build failure. > > Thanks > Mandy > > diff --git a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c > --- a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c > +++ b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c > @@ -34,6 +34,7 @@ > static jmethodID mid_Field_get; > > int getField(JNIEnv *env, char* declaringClass_name, char* field_name); > +int checkAndClearIllegalAccessExceptionThrown(JNIEnv *env); > > int main(int argc, char** args) { > JavaVM *jvm; > From javalists at cbfiddle.com Sun Apr 7 01:49:58 2019 From: javalists at cbfiddle.com (Alan Snyder) Date: Sat, 6 Apr 2019 18:49:58 -0700 Subject: jpackage on macOS Message-ID: I have just tried using the latest jpackage release on macOS, after successfully using a very old sandbox version from long ago. Two command line argument names had to be changed, but otherwise the usage appears to be the same for my simple case of building a bundled app. However, the bundled app does not run. Executing the ?main? executable from the terminal produces this output: Error: could not find libjava.dylib Error: Could not find Java SE Runtime Environment. The library exists in Contents/PlugIns/Java.runtime/Contents/Home/lib. From mik3hall at gmail.com Sun Apr 7 02:04:51 2019 From: mik3hall at gmail.com (Michael Hall) Date: Sat, 6 Apr 2019 21:04:51 -0500 Subject: jpackage on macOS In-Reply-To: References: Message-ID: <44A65F3B-B17F-4A18-9473-294CDD5C22AB@gmail.com> > On Apr 6, 2019, at 8:49 PM, Alan Snyder wrote: > > I have just tried using the latest jpackage release on macOS, after successfully using a very old sandbox version from long ago. > Two command line argument names had to be changed, but otherwise the usage appears to be the same for my simple case of building a bundled app. > However, the bundled app does not run. > Executing the ?main? executable from the terminal produces this output: > > Error: could not find libjava.dylib > Error: Could not find Java SE Runtime Environment. > > The library exists in Contents/PlugIns/Java.runtime/Contents/Home/lib. > What exactly are you entering to run the application? The full jpackage invocation parameters and output could be useful. From javalists at cbfiddle.com Sun Apr 7 02:34:38 2019 From: javalists at cbfiddle.com (Alan Snyder) Date: Sat, 6 Apr 2019 19:34:38 -0700 Subject: jpackage on macOS In-Reply-To: <44A65F3B-B17F-4A18-9473-294CDD5C22AB@gmail.com> References: <44A65F3B-B17F-4A18-9473-294CDD5C22AB@gmail.com> Message-ID: In preparing an answer to your questions, I think I have discovered the problem. I was building using an custom JDK image that I had modified slightly to work with the old packager. Using a released JDK 11, the bundled application starts fine. > On Apr 6, 2019, at 7:04 PM, Michael Hall wrote: > > > >> On Apr 6, 2019, at 8:49 PM, Alan Snyder wrote: >> >> I have just tried using the latest jpackage release on macOS, after successfully using a very old sandbox version from long ago. >> Two command line argument names had to be changed, but otherwise the usage appears to be the same for my simple case of building a bundled app. >> However, the bundled app does not run. >> Executing the ?main? executable from the terminal produces this output: >> >> Error: could not find libjava.dylib >> Error: Could not find Java SE Runtime Environment. >> >> The library exists in Contents/PlugIns/Java.runtime/Contents/Home/lib. >> > > What exactly are you entering to run the application? > > The full jpackage invocation parameters and output could be useful. > > > From mik3hall at gmail.com Sun Apr 7 02:36:27 2019 From: mik3hall at gmail.com (Michael Hall) Date: Sat, 6 Apr 2019 21:36:27 -0500 Subject: jpackage on macOS In-Reply-To: References: <44A65F3B-B17F-4A18-9473-294CDD5C22AB@gmail.com> Message-ID: > On Apr 6, 2019, at 9:34 PM, Alan Snyder wrote: > > In preparing an answer to your questions, I think I have discovered the problem. > > I was building using an custom JDK image that I had modified slightly to work with the old packager. > Using a released JDK 11, the bundled application starts fine. Glad you got it working. From david.holmes at oracle.com Sun Apr 7 02:47:02 2019 From: david.holmes at oracle.com (David Holmes) Date: Sun, 7 Apr 2019 12:47:02 +1000 Subject: (1-line) Review Request: 8222078: test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c build fails after 8221530 In-Reply-To: <01c65189-49fe-0c55-82a6-6f8c95725d69@oracle.com> References: <01c65189-49fe-0c55-82a6-6f8c95725d69@oracle.com> Message-ID: Looks good. Thanks, David On 7/04/2019 9:37 am, Mandy Chung wrote: > A simple test fix.? The test causes the build failure. > > Thanks > Mandy > > diff --git > a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c > b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c > --- a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c > +++ b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c > @@ -34,6 +34,7 @@ > ?static jmethodID mid_Field_get; > > ?int getField(JNIEnv *env, char* declaringClass_name, char* field_name); > +int checkAndClearIllegalAccessExceptionThrown(JNIEnv *env); > > ?int main(int argc, char** args) { > ???? JavaVM *jvm; > From mandy.chung at oracle.com Sun Apr 7 08:12:54 2019 From: mandy.chung at oracle.com (Mandy Chung) Date: Sun, 7 Apr 2019 16:12:54 +0800 Subject: (1-line) Review Request: 8222078: test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c build fails after 8221530 In-Reply-To: References: <01c65189-49fe-0c55-82a6-6f8c95725d69@oracle.com> Message-ID: It needs another fix for windows build: diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk --- a/make/test/JtregNativeJdk.gmk +++ b/make/test/JtregNativeJdk.gmk @@ -61,6 +61,7 @@ ?? BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := $(WIN_LIB_JAVA) ?? WIN_LIB_JLI := $(SUPPORT_OUTPUTDIR)/native/java.base/libjli/jli.lib ?? BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeJliLaunchTest := $(WIN_LIB_JLI) +? BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := jvm.lib ?else ?? BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava ?? BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava @@ -70,10 +71,9 @@ ???? BUILD_JDK_JTREG_LIBRARIES_LIBS_libInheritedChannel := -ljava -lsocket -lnsl ?? endif ?? BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeJliLaunchTest := -ljli +? BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := -ljvm ?endif -BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := -ljvm - ?ifeq ($(call isTargetOs, macosx), true) ?? BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libTestMainKeyWindow := -ObjC ?? BUILD_JDK_JTREG_LIBRARIES_LIBS_libTestMainKeyWindow := -framework JavaVM \ Mandy On 4/7/19 10:47 AM, David Holmes wrote: > Looks good. > > Thanks, > David > > On 7/04/2019 9:37 am, Mandy Chung wrote: >> A simple test fix.? The test causes the build failure. >> >> Thanks >> Mandy >> >> diff --git >> a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c >> b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c >> --- >> a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c >> +++ >> b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c >> @@ -34,6 +34,7 @@ >> ??static jmethodID mid_Field_get; >> >> ??int getField(JNIEnv *env, char* declaringClass_name, char* >> field_name); >> +int checkAndClearIllegalAccessExceptionThrown(JNIEnv *env); >> >> ??int main(int argc, char** args) { >> ????? JavaVM *jvm; >> From Alan.Bateman at oracle.com Sun Apr 7 08:49:26 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Sun, 7 Apr 2019 09:49:26 +0100 Subject: (1-line) Review Request: 8222078: test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c build fails after 8221530 In-Reply-To: References: <01c65189-49fe-0c55-82a6-6f8c95725d69@oracle.com> Message-ID: <4429661d-d91d-0e87-fcab-6475f134d1f8@oracle.com> On 07/04/2019 09:12, Mandy Chung wrote: > It needs another fix for windows build: > > diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk > --- a/make/test/JtregNativeJdk.gmk > +++ b/make/test/JtregNativeJdk.gmk > @@ -61,6 +61,7 @@ > ?? BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := > $(WIN_LIB_JAVA) > ?? WIN_LIB_JLI := $(SUPPORT_OUTPUTDIR)/native/java.base/libjli/jli.lib > ?? BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeJliLaunchTest := $(WIN_LIB_JLI) > +? BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := jvm.lib > ?else > ?? BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava > ?? BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava > @@ -70,10 +71,9 @@ > ???? BUILD_JDK_JTREG_LIBRARIES_LIBS_libInheritedChannel := -ljava > -lsocket -lnsl > ?? endif > ?? BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeJliLaunchTest := -ljli > +? BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := -ljvm > ?endif > > -BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := -ljvm > - > ?ifeq ($(call isTargetOs, macosx), true) > ?? BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libTestMainKeyWindow := -ObjC > ?? BUILD_JDK_JTREG_LIBRARIES_LIBS_libTestMainKeyWindow := -framework > JavaVM \ I think this looks okay and seems to work for me locally too. -Alan From david.holmes at oracle.com Sun Apr 7 09:12:13 2019 From: david.holmes at oracle.com (David Holmes) Date: Sun, 7 Apr 2019 19:12:13 +1000 Subject: (1-line) Review Request: 8222078: test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c build fails after 8221530 In-Reply-To: References: <01c65189-49fe-0c55-82a6-6f8c95725d69@oracle.com> Message-ID: <4a87d9e6-18d6-2545-1d9c-9d9de74e74e4@oracle.com> Looks good. Thanks, David On 7/04/2019 6:12 pm, Mandy Chung wrote: > It needs another fix for windows build: > > diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk > --- a/make/test/JtregNativeJdk.gmk > +++ b/make/test/JtregNativeJdk.gmk > @@ -61,6 +61,7 @@ > ?? BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := $(WIN_LIB_JAVA) > ?? WIN_LIB_JLI := $(SUPPORT_OUTPUTDIR)/native/java.base/libjli/jli.lib > ?? BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeJliLaunchTest := $(WIN_LIB_JLI) > +? BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := jvm.lib > ?else > ?? BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava > ?? BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava > @@ -70,10 +71,9 @@ > ???? BUILD_JDK_JTREG_LIBRARIES_LIBS_libInheritedChannel := -ljava > -lsocket -lnsl > ?? endif > ?? BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeJliLaunchTest := -ljli > +? BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := -ljvm > ?endif > > -BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := -ljvm > - > ?ifeq ($(call isTargetOs, macosx), true) > ?? BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libTestMainKeyWindow := -ObjC > ?? BUILD_JDK_JTREG_LIBRARIES_LIBS_libTestMainKeyWindow := -framework > JavaVM \ > > Mandy > > On 4/7/19 10:47 AM, David Holmes wrote: >> Looks good. >> >> Thanks, >> David >> >> On 7/04/2019 9:37 am, Mandy Chung wrote: >>> A simple test fix.? The test causes the build failure. >>> >>> Thanks >>> Mandy >>> >>> diff --git >>> a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c >>> >>> --- >>> a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c >>> +++ >>> b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c >>> @@ -34,6 +34,7 @@ >>> ??static jmethodID mid_Field_get; >>> >>> ??int getField(JNIEnv *env, char* declaringClass_name, char* >>> field_name); >>> +int checkAndClearIllegalAccessExceptionThrown(JNIEnv *env); >>> >>> ??int main(int argc, char** args) { >>> ????? JavaVM *jvm; >>> > From gnu.andrew at redhat.com Mon Apr 8 04:40:01 2019 From: gnu.andrew at redhat.com (Andrew John Hughes) Date: Mon, 8 Apr 2019 05:40:01 +0100 Subject: RFR: [8u] 8205432: Replace the placeholder Japanese era name Message-ID: Bug: https://bugs.openjdk.java.net/browse/JDK-8205432 Webrev: https://cr.openjdk.java.net/~andrew/openjdk8/8205432/webrev.01/ This is a relatively clean backport, with a few exceptions, mostly due to unneeded copyright changes or moved files: * 8u has FormatData_ja.java and JavaTimeSupplementary_ja.java in src/share/classes/sun/text/resources/ja/ rather than src/jdk.localedata/share/classes/sun/text/resources/ext/ * The XML files are in src/share/classes/sun/util/cldr/resources/21_0_1/common/main/ rather than src/jdk.localedata/share/classes/sun/util/cldr/resources/common/main/ * 8u doesn't have test/jdk/java/util/Calendar/ZoneOffsets.java (JDK-8031145 & JDK-8165296 look like potential future test backports) * The changes in src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java take place in src/share/lib/calendars.properties in 8u I compared both with the 11u version of this patch and the 8u version of JDK-8202088, as well as searching the code base for 'NewEra'. Thanks, -- Andrew :) Senior Free Java Software Engineer Red Hat, Inc. (http://www.redhat.com) PGP Key: ed25519/0xCFDA0F9B35964222 (hkp://keys.gnupg.net) Fingerprint = 5132 579D D154 0ED2 3E04 C5A0 CFDA 0F9B 3596 4222 https://keybase.io/gnu_andrew From aph at redhat.com Mon Apr 8 08:26:14 2019 From: aph at redhat.com (Andrew Haley) Date: Mon, 8 Apr 2019 09:26:14 +0100 Subject: RFR: [8u] 8205432: Replace the placeholder Japanese era name In-Reply-To: References: Message-ID: On 4/8/19 5:40 AM, Andrew John Hughes wrote: > Bug: https://bugs.openjdk.java.net/browse/JDK-8205432 > Webrev: https://cr.openjdk.java.net/~andrew/openjdk8/8205432/webrev.01/ OK, thanks. -- Andrew Haley Java Platform Lead Engineer Red Hat UK Ltd. EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671 From deepak.kejriwal at oracle.com Mon Apr 8 08:25:27 2019 From: deepak.kejriwal at oracle.com (Deepak Kejriwal) Date: Mon, 8 Apr 2019 01:25:27 -0700 (PDT) Subject: RFR: [8u] 8205432: Replace the placeholder Japanese era name In-Reply-To: References: Message-ID: Hi Andrew, Thanks for working on this. Please find below few minor comments:- 1>. For "src/share/classes/java/util/JapaneseImperialCalendar.java" and "src/share/classes/sun/util/calendar/Era.java" please changes the date time format to be consistent with existing defined eras:- * 4 Heisei 1989-01-08 midnight local time - * 5 NewEra 2019-05-01 midnight local time + * 5 Reiwa 2019-05-01T00:00:00 local time Please change "2019-05-01T00:00:00 local time" to "2019-05-01 midnight local time" 2>. For "test/java/time/test/java/time/chrono/TestJapaneseChronology.java" please align "JapaneseEra.of(3)" with existing defined eras in "Object[][] eraNameData()". Regards, Deepak -----Original Message----- From: Andrew John Hughes Sent: Monday, April 8, 2019 10:10 AM To: jdk8u-dev at openjdk.java.net; core-libs-dev at openjdk.java.net Subject: RFR: [8u] 8205432: Replace the placeholder Japanese era name Bug: https://bugs.openjdk.java.net/browse/JDK-8205432 Webrev: https://cr.openjdk.java.net/~andrew/openjdk8/8205432/webrev.01/ This is a relatively clean backport, with a few exceptions, mostly due to unneeded copyright changes or moved files: * 8u has FormatData_ja.java and JavaTimeSupplementary_ja.java in src/share/classes/sun/text/resources/ja/ rather than src/jdk.localedata/share/classes/sun/text/resources/ext/ * The XML files are in src/share/classes/sun/util/cldr/resources/21_0_1/common/main/ rather than src/jdk.localedata/share/classes/sun/util/cldr/resources/common/main/ * 8u doesn't have test/jdk/java/util/Calendar/ZoneOffsets.java (JDK-8031145 & JDK-8165296 look like potential future test backports) * The changes in src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java take place in src/share/lib/calendars.properties in 8u I compared both with the 11u version of this patch and the 8u version of JDK-8202088, as well as searching the code base for 'NewEra'. Thanks, -- Andrew :) Senior Free Java Software Engineer Red Hat, Inc. (http://www.redhat.com) PGP Key: ed25519/0xCFDA0F9B35964222 (hkp://keys.gnupg.net) Fingerprint = 5132 579D D154 0ED2 3E04 C5A0 CFDA 0F9B 3596 4222 https://keybase.io/gnu_andrew From claes.redestad at oracle.com Mon Apr 8 08:41:23 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 8 Apr 2019 10:41:23 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero Message-ID: Hi, by adding a bit to String that is true iff String.hash has been calculated as being 0, we can get rid of the corner case where such hash codes are recalculated on every call. Peter Levart came up with a elegant scheme for ensuring that we can keep using non-volatile stores without explicit fencing and still reap the benefits of this[1], and I've synced up the hotspot code that deals with the String.hash value to mirror that logic. Bug: https://bugs.openjdk.java.net/browse/JDK-8221836 Webrev: http://cr.openjdk.java.net/~redestad/8221836/open.01/ Since there exists small padding gaps in the current object layout of strings (on all VM bitness and compressed oops varieties), adding this boolean does not add any extra footprint per String instance. Testing: tier1-3, verified a speed-up in targeted microbenchmarks. Thanks! /Claes [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-April/059480.html From shade at redhat.com Mon Apr 8 08:56:11 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 8 Apr 2019 10:56:11 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: References: Message-ID: On 4/8/19 10:41 AM, Claes Redestad wrote: > by adding a bit to String that is true iff String.hash has been calculated as being 0, we can get > rid of the corner case where such hash > codes are recalculated on every call. > > Peter Levart came up with a elegant scheme for ensuring that we can keep > using non-volatile stores without explicit fencing and still reap the > benefits of this[1], and I've synced up the hotspot code that deals with > the String.hash value to mirror that logic. > > Bug:??? https://bugs.openjdk.java.net/browse/JDK-8221836 > Webrev: http://cr.openjdk.java.net/~redestad/8221836/open.01/ > > Since there exists small padding gaps in the current object layout of > strings (on all VM bitness and compressed oops varieties), adding this > boolean does not add any extra footprint per String instance. Regardless, I think this change does not carry its weight. Introducing special paths for handling something as obscure as zero hash code, which then raises questions about correctness (I had hard time convincing myself that code is concurrency-safe), seems rather odd to me. It is a sane engineering tradeoff to make code more maintainable with accepting performance hit in 2^(-32) of cases. -Aleksey From claes.redestad at oracle.com Mon Apr 8 09:25:11 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 8 Apr 2019 11:25:11 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: References: Message-ID: On 2019-04-08 10:56, Aleksey Shipilev wrote: > Regardless, I think this change does not carry its weight. Introducing special paths for handling > something as obscure as zero hash code, which then raises questions about correctness (I had hard > time convincing myself that code is concurrency-safe), seems rather odd to me. It is a sane > engineering tradeoff to make code more maintainable with accepting performance hit in 2^(-32) of cases. Sure, String::hashCode/hash_code locally becomes a bit more complex, but I view this as being a net improvement on the total amount of special handling we need to do for Strings and their hash codes. While the performance gain on most real world use cases is likely to be non-existent, there exists some past concerns with injecting zero hash Strings into poorly implemented caches. This patch adds some defense-in- depth to help avoid issues that could otherwise arise from use of Strings as key in some hashing data structures. /Claes From shade at redhat.com Mon Apr 8 09:35:53 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 8 Apr 2019 11:35:53 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: References: Message-ID: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> On 4/8/19 11:25 AM, Claes Redestad wrote: > On 2019-04-08 10:56, Aleksey Shipilev wrote: >> Regardless, I think this change does not carry its weight. Introducing special paths for handling >> something as obscure as zero hash code, which then raises questions about correctness (I had hard >> time convincing myself that code is concurrency-safe), seems rather odd to me. It is a sane >> engineering tradeoff to make code more maintainable with accepting performance hit in 2^(-32) of >> cases. > > Sure, String::hashCode/hash_code locally becomes a bit more complex, but > I view this as being a net improvement on the total amount of special > handling we need to do for Strings and their hash codes. I don't see it. The change *added* new handling for the flag in all those places we used to handle zero hash code, and then some. > While the performance gain on most real world use cases is likely to be > non-existent, there exists some past concerns with injecting zero hash > Strings into poorly implemented caches. This patch adds some defense-in- > depth to help avoid issues that could otherwise arise from use of > Strings as key in some hashing data structures. That does not make much sense to me: it is much easier to construct hashcode collisions rather than generating unique strings with zero hashcodes. Alternative hashing was there to mitigate that, and it would also handle zero hash attacks. -Aleksey From claes.redestad at oracle.com Mon Apr 8 09:42:54 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 8 Apr 2019 11:42:54 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> Message-ID: <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> On 2019-04-08 11:35, Aleksey Shipilev wrote: >> Sure, String::hashCode/hash_code locally becomes a bit more complex, but >> I view this as being a net improvement on the total amount of special >> handling we need to do for Strings and their hash codes. > I don't see it. The change *added* new handling for the flag in all those places we used to handle > zero hash code, and then some. There's a few simple boilerplate methods added and the logic of hash_code(string) is consolidated to mimic String::hashCode, but code at the real call-sites like stringDedupTable and stringTable is simplified. /Claes From adinn at redhat.com Mon Apr 8 09:52:43 2019 From: adinn at redhat.com (Andrew Dinn) Date: Mon, 8 Apr 2019 10:52:43 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> <296e270c-0db1-1cdb-c4c3-147cbfd417ea@redhat.com> Message-ID: On 06/04/2019 19:05, Alan Bateman wrote: > On 05/04/2019 11:50, Andrew Dinn wrote: >> : >> Ah ok, got it now. I think I was confused by a missing 'not' in your >> original response. >> >> I have now removed the @throws for NPE from the MapMode constructor >> javadoc as well as letting the call to length() perform the null check. >> >> new webrev: http://cr.openjdk.java.net/~adinn/8221397/webrev.00/ >> ?????? JIRA: https://bugs.openjdk.java.net/browse/JDK-8221397 >> > This versions look, I assume you'll create the CSR and wait for it to be > approved before pushing. I created the following CSR https://bugs.openjdk.java.net/browse/JDK-8222107 Apologies if I got anything wrong (first time I have done this :-). Do I need to solicit reviews or does this automatically get dispatched to the relevant component/sub-component leads? regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From adinn at redhat.com Mon Apr 8 10:15:29 2019 From: adinn at redhat.com (Andrew Dinn) Date: Mon, 8 Apr 2019 11:15:29 +0100 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> Message-ID: <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> On 08/04/2019 10:42, Claes Redestad wrote: > On 2019-04-08 11:35, Aleksey Shipilev wrote: >>> Sure, String::hashCode/hash_code locally becomes a bit more complex, but >>> I view this as being a net improvement on the total amount of special >>> handling we need to do for Strings and their hash codes. >> I don't see it. The change *added* new handling for the flag in all >> those places we used to handle >> zero hash code, and then some. > > There's a few simple boilerplate methods added and the logic of > hash_code(string) is consolidated to mimic String::hashCode, but code at > the real call-sites like stringDedupTable and stringTable is simplified. Aleksey, I'm definitely buying Claes argument on this point. Also, I think your other quibble suffers from "what-aboutism" -- the fact that there are other ways for perverse performance issues to manifest (hashcode collisions) doesn't mean that this gap should not be plugged. However, you also said in your opening criticism "I had hard time convincing myself that code is concurrency-safe" I think that is a more telling complaint. Can you elaborate on why you found it hard to convince yourself of this? (I know what I think is the issue and I don't view it as an /especially/ thorny problem). Claes, is there a reason why you named the argument to method hash_is_set 'string' when every other method uses the name 'java_string'? Is you 'j' key a tad sticky? regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From peter.levart at gmail.com Mon Apr 8 10:24:58 2019 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 8 Apr 2019 12:24:58 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: References: Message-ID: <3453bd0a-37e6-957e-f1ea-f86fe7a9ff17@gmail.com> I think the most benefit in this patch is the emptyString.hashCode() speedup. By holding a boolean flag in the String object itself, there is one less de-reference to be made on fast-path in case of empty string. Which shows in microbenchmark and would show even more if code iterated many different instances of empty strings that don't share the underlying array invoking .hashCode() on them. Which, I admit, is not a frequent case in practice, but hey, it is a speedup after all. Regards, Peter On 4/8/19 10:56 AM, Aleksey Shipilev wrote: > On 4/8/19 10:41 AM, Claes Redestad wrote: >> by adding a bit to String that is true iff String.hash has been calculated as being 0, we can get >> rid of the corner case where such hash >> codes are recalculated on every call. >> >> Peter Levart came up with a elegant scheme for ensuring that we can keep >> using non-volatile stores without explicit fencing and still reap the >> benefits of this[1], and I've synced up the hotspot code that deals with >> the String.hash value to mirror that logic. >> >> Bug:??? https://bugs.openjdk.java.net/browse/JDK-8221836 >> Webrev: http://cr.openjdk.java.net/~redestad/8221836/open.01/ >> >> Since there exists small padding gaps in the current object layout of >> strings (on all VM bitness and compressed oops varieties), adding this >> boolean does not add any extra footprint per String instance. > Regardless, I think this change does not carry its weight. Introducing special paths for handling > something as obscure as zero hash code, which then raises questions about correctness (I had hard > time convincing myself that code is concurrency-safe), seems rather odd to me. It is a sane > engineering tradeoff to make code more maintainable with accepting performance hit in 2^(-32) of cases. > > -Aleksey > From shade at redhat.com Mon Apr 8 10:28:03 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 8 Apr 2019 12:28:03 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> Message-ID: <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> On 4/8/19 12:15 PM, Andrew Dinn wrote: > On 08/04/2019 10:42, Claes Redestad wrote: >> On 2019-04-08 11:35, Aleksey Shipilev wrote: >>>> Sure, String::hashCode/hash_code locally becomes a bit more complex, but >>>> I view this as being a net improvement on the total amount of special >>>> handling we need to do for Strings and their hash codes. >>> I don't see it. The change *added* new handling for the flag in all >>> those places we used to handle >>> zero hash code, and then some. >> >> There's a few simple boilerplate methods added and the logic of >> hash_code(string) is consolidated to mimic String::hashCode, but code at >> the real call-sites like stringDedupTable and stringTable is simplified. Again, I don't see it. The same cleanup (moving hash computation code to java_lang_String::hash*) can be done without introducing the flag? > Aleksey, I'm definitely buying Claes argument on this point. Also, I > think your other quibble suffers from "what-aboutism" -- the fact that > there are other ways for perverse performance issues to manifest > (hashcode collisions) doesn't mean that this gap should not be plugged. Read carefully: I said that alternative hashing that is there to mitigate hashcode collisions *also* takes care of zero hashcode attacks. So if we do care about obscure zero hashcode attack, we can piggyback on the already implemented mechanism that is there to mitigate the much broader attack. > However, you also said in your opening criticism > > "I had hard time convincing myself that code is concurrency-safe" > > I think that is a more telling complaint. Can you elaborate on why you > found it hard to convince yourself of this? (I know what I think is the Because the whole thing in current code is "benign data race" on hash field. Pulling in another field into race needs careful consideration if it breaks the benignity. It apparently does not, but the cognitive complexity involved in reading that code makes the minuscule benefit much more questionable. -Aleksey From claes.redestad at oracle.com Mon Apr 8 10:59:11 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 8 Apr 2019 12:59:11 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> Message-ID: On 2019-04-08 12:15, Andrew Dinn wrote: > Claes, is there a reason why you named the argument to method > hash_is_set 'string' when every other method uses the name > 'java_string'? Is you 'j' key a tad sticky? I took the cue from set_hash which uses the 'string' naming, but yes, you're right to point out naming of arguments in this API is now a bit inconsistent. /Claes From claes.redestad at oracle.com Mon Apr 8 11:00:54 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 8 Apr 2019 13:00:54 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> Message-ID: <99cbd4e8-ab41-97ba-1a68-fff63f033e66@oracle.com> On 2019-04-08 12:28, Aleksey Shipilev wrote: > Because the whole thing in current code is "benign data race" on hash field. Pulling in another > field into race needs careful consideration if it breaks the benignity. It apparently does not, but > the cognitive complexity involved in reading that code makes the minuscule benefit much more > questionable. Can some carefully worded comments in the vicinity ease your concern? /Claes From shade at redhat.com Mon Apr 8 11:12:39 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 8 Apr 2019 13:12:39 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <99cbd4e8-ab41-97ba-1a68-fff63f033e66@oracle.com> References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> <99cbd4e8-ab41-97ba-1a68-fff63f033e66@oracle.com> Message-ID: On 4/8/19 1:00 PM, Claes Redestad wrote: > On 2019-04-08 12:28, Aleksey Shipilev wrote: >> Because the whole thing in current code is "benign data race" on hash field. Pulling in another >> field into race needs careful consideration if it breaks the benignity. It apparently does not, but >> the cognitive complexity involved in reading that code makes the minuscule benefit much more >> questionable. > > Can some carefully worded comments in the vicinity ease your concern? No. I am against deviating from the benign data race template, for either current or future changes, without the clearly overwhelming benefit of doing so. We have enough bugs as it is to risk exposing more bugs for the cases where the benefit is non-compelling. Therefore, my concern would be alleviated if we don't do this change at all. -Aleksey From GROEGES at uk.ibm.com Mon Apr 8 11:21:56 2019 From: GROEGES at uk.ibm.com (Steve Groeger) Date: Mon, 8 Apr 2019 12:21:56 +0100 Subject: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException In-Reply-To: References: <501ff931-c50e-ac82-6ac6-ae71a6da0ffa@oracle.com> <1a9a27e6-d196-3fa1-fda4-9a3a80b327cc@oracle.com> Message-ID: Hi Daniel, Thanks for agreeing to sponsor this update. Have created a new webrev [1] according to the instructions you pointed me at. Would be grateful if you could re-review and then do whatever is needed to get this into the code. [1] http://cr.openjdk.java.net/~sgroeger/8222027/webrev.03/ Once this is contributed to jdk repository, could this also be contributed back to jdk11u. Thanks Steve Groeger IBM Runtime Technologies Hursley, Winchester Tel: (44) 1962 816911 Mobex: 279990 Mobile: 07718 517 129 Fax (44) 1962 816800 Lotus Notes: Steve Groeger/UK/IBM Internet: groeges at uk.ibm.com Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From: Daniel Fuchs To: Steve Groeger Cc: OpenJDK Core Libs Developers Date: 05/04/2019 14:33 Subject: Re: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException On 05/04/2019 14:01, Steve Groeger wrote: > Hi Daniel, > > Thanks. I should have spotted that slight mistake. That is what comes > from just cutting and pasting. > Have created a new webrev anyway: > _https://urldefense.proofpoint.com/v2/url?u=http-3A__cr.openjdk.java.net_-7Esgroeger_8222027_webrev.02_-5F&d=DwIC-g&c=jf_iaSHvJObTbx-siA1ZOg&r=78GW2OHz7nNTH2dBkTx7-TKh2QCt3JD3zukzeUO8RpA&m=qRBq_TynpHvQNvdfqbB7xtbvHge-g3BD_lQQ56j9110&s=xjkl3b-FfGR3bIdqBiOjwMHlW9cHN8xVX0fCH-m7T3M&e= > I presume I need someone else to review this and also get a sponsor (so > they can actually make the change) as I am not a committer (YET!!!) > Do you know anyone that can do this for me? If you don't have a sponsor at IBM I can sponsor it for you. You will need to make a proper changeset that can be hg imported. (simplest way is to hg commit the change in your local workspace with the proper commit comment [1] and call webrev again, then do hg rollback immediately after). BTW since this is a a test bug then the @bug tag doesn't need to be updated. Instead you should add a noreg-self label to the JBS issue, if it's not already there. [1] https://urldefense.proofpoint.com/v2/url?u=http-3A__openjdk.java.net_guide_producingChangeset.html&d=DwIC-g&c=jf_iaSHvJObTbx-siA1ZOg&r=78GW2OHz7nNTH2dBkTx7-TKh2QCt3JD3zukzeUO8RpA&m=qRBq_TynpHvQNvdfqbB7xtbvHge-g3BD_lQQ56j9110&s=eQWzg0PXYNpTeqADJ8MBzKvMhlQ5fbacEcmWkB7a5cc&e= best regards, -- daniel Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From peter.levart at gmail.com Mon Apr 8 11:28:20 2019 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 8 Apr 2019 13:28:20 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> Message-ID: <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> On 4/8/19 12:28 PM, Aleksey Shipilev wrote: >> However, you also said in your opening criticism >> >> "I had hard time convincing myself that code is concurrency-safe" >> >> I think that is a more telling complaint. Can you elaborate on why you >> found it hard to convince yourself of this? (I know what I think is the > Because the whole thing in current code is "benign data race" on hash field. Pulling in another > field into race needs careful consideration if it breaks the benignity. It apparently does not, but > the cognitive complexity involved in reading that code makes the minuscule benefit much more > questionable. > > -Aleksey > Hi Aleksey, The reasoning is very similar as with just one field. With one field (hash) the thread sees either the default value (0) or a non-zero value calculated either by this thread sometime before or by a concurrent thread that has already stored it. Regardless of ordering, the thread either uses the non-zero value or (re)calculates it (again). The value calculation is deterministic and uses immutable published state (the array), so it always calculates the same value for the same object. Idempotence is guaranteed. The same reasoning can be extended to a general case where there are many fields used for caching of a calculated state from some immutable published state. The constraint is that the calculation must be deterministic and must also deterministically choose which of the many fields used for caching is to be modified. Only one field may be modified, never more than one. The thread therefore sees either the default values of all fields or the default values of all but one field which has been set by either this thread sometime before or by a concurrent thread. Regardless of ordering, the thread either uses the state combined from the default values of all fields but one and a non-default value of a single field or (re)calculates the non-default value of the single field. The value calculation is deterministic, uses immutable published state and deterministically chooses the field to modify, so it always calculates the same "next" state for the object. Idempotence is guaranteed. Regards, Peter From shade at redhat.com Mon Apr 8 11:40:43 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 8 Apr 2019 13:40:43 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> Message-ID: On 4/8/19 1:28 PM, Peter Levart wrote: > On 4/8/19 12:28 PM, Aleksey Shipilev wrote: >>> However, you also said in your opening criticism >>> >>> "I had hard time convincing myself that code is concurrency-safe" >>> >>> I think that is a more telling complaint. Can you elaborate on why you >>> found it hard to convince yourself of this? (I know what I think is the >> Because the whole thing in current code is "benign data race" on hash field. Pulling in another >> field into race needs careful consideration if it breaks the benignity. It apparently does not, but >> the cognitive complexity involved in reading that code makes the minuscule benefit much more >> questionable. > > The reasoning is very similar as with just one field. With one field (hash) the thread sees either > the default value (0) or a non-zero value calculated either by this thread sometime before or by a > concurrent thread that has already stored it. Regardless of ordering, the thread either uses the > non-zero value or (re)calculates it (again). The value calculation is deterministic and uses > immutable published state (the array), so it always calculates the same value for the same object. > Idempotence is guaranteed. > > The same reasoning can be extended to a general case where there are many fields used for caching of > a calculated state from some immutable published state. The constraint is that the calculation must > be deterministic and must also deterministically choose which of the many fields used for caching is > to be modified. Only one field may be modified, never more than one. The thread therefore sees > either the default values of all fields or the default values of all but one field which has been > set by either this thread sometime before or by a concurrent thread. Regardless of ordering, the > thread either uses the state combined from the default values of all fields but one and a > non-default value of a single field or (re)calculates the non-default value of the single field. The > value calculation is deterministic, uses immutable published state and deterministically chooses the > field to modify, so it always calculates the same "next" state for the object. Idempotence is > guaranteed. Thank you, the mere existence of this wall of text solidifies my argument: the need to invoke the argument like that is exactly the cognitive complexity I've been talking about, and it speaks about maintainability/risk cost, while benefits are still around the machine epsilon. Let's just draw the line on micro-optimizations, okay? This one is interesting experiment in itself, and it certainly passes the "hold my beer" curiosity threshold, but it does not pass the "should we actually do this" bar for me. -Aleksey From andy.herrick at oracle.com Mon Apr 8 11:41:37 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Mon, 8 Apr 2019 07:41:37 -0400 Subject: RFR: JDK-8221749: Error messages Message-ID: <6b91294f-445c-bf88-2a8c-c65f7add48a7@oracle.com> Please review the jpackage fix for bug [1] at [2]. This is a fix for the JDK-8200758-branch branch of the open sandbox repository (jpackage). [1] http://cr.openjdk.java.net/~herrick/8221749/ [2] https://bugs.openjdk.java.net/browse/JDK-8221749/ /Andy From daniel.fuchs at oracle.com Mon Apr 8 11:53:32 2019 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Mon, 8 Apr 2019 12:53:32 +0100 Subject: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException In-Reply-To: References: <501ff931-c50e-ac82-6ac6-ae71a6da0ffa@oracle.com> <1a9a27e6-d196-3fa1-fda4-9a3a80b327cc@oracle.com> Message-ID: Hi Steve, On 08/04/2019 12:21, Steve Groeger wrote: > Hi Daniel, > > Thanks for agreeing to sponsor this update. > Have created a new webrev [1] according to the instructions you pointed > me at. > Would be grateful if you could re-review and then do whatever is needed > to get this into the code. > > [1] _http://cr.openjdk.java.net/~sgroeger/8222027/webrev.03/_ If you look at http://cr.openjdk.java.net/~sgroeger/8222027/webrev.03/jdk.changeset you will see that your OpenJDK user name already appears in the changeset (line 2) - so you don't need the Contributed-by line. The changeset, when pushed, will already appear has being authored by `sgroeger`. The contributor line is only needed when the contributor is not an OpenJDK author yet, or when there are several contributors. Could you please remove that line and regenerate the changeset? I'll then be able to import it in my local repo - verifies that our test system is happy with it (I don't expect any issue there), and push it for you. > Once this is contributed to jdk repository, could this also be > contributed back to jdk11u. You will need to negotiate that with the OpenJDK 12 and OpenJDK 11 maintainers - and follow the rules for the updates projects there: http://openjdk.java.net/projects/jdk-updates/ Since this is a test bug that should apply cleanly I don't think that should be an issue. But you will need to find a sponsor for those. best regards, -- daniel > > Thanks > Steve Groeger > IBM Runtime Technologies > Hursley, Winchester > Tel: (44) 1962 816911 ?Mobex: 279990 ?Mobile: 07718 517 129 > Fax (44) 1962 816800 > Lotus Notes: Steve Groeger/UK/IBM > Internet: groeges at uk.ibm.com From shade at redhat.com Mon Apr 8 11:54:55 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 8 Apr 2019 13:54:55 +0200 Subject: RFR (XS) 8222111: exeCallerAccessTest.c fails to build: control reaches end of non-void function Message-ID: <20e9e5e3-ea1b-da85-fc44-50a92e627a75@redhat.com> Bug: https://bugs.openjdk.java.net/browse/JDK-8222111 Fix: diff -r 0d7fb7f07134 test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c --- a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c Mon Apr 08 06:56:37 2019 +0100 +++ b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c Mon Apr 08 13:53:51 2019 +0200 @@ -94,4 +94,5 @@ (*jvm)->DestroyJavaVM(jvm); + return 0; } Testing: local Linux x86_64 builds (gcc 4.8.5, 6.3.0, 7.3.0), jdk-submit (running) -- Thanks, -Aleksey From Alan.Bateman at oracle.com Mon Apr 8 12:08:19 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 8 Apr 2019 13:08:19 +0100 Subject: RFR (XS) 8222111: exeCallerAccessTest.c fails to build: control reaches end of non-void function In-Reply-To: <20e9e5e3-ea1b-da85-fc44-50a92e627a75@redhat.com> References: <20e9e5e3-ea1b-da85-fc44-50a92e627a75@redhat.com> Message-ID: On 08/04/2019 12:54, Aleksey Shipilev wrote: > Bug: > https://bugs.openjdk.java.net/browse/JDK-8222111 > > Fix: > > diff -r 0d7fb7f07134 test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c > --- a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c Mon Apr 08 06:56:37 > 2019 +0100 > +++ b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c Mon Apr 08 13:53:51 > 2019 +0200 > @@ -94,4 +94,5 @@ > > (*jvm)->DestroyJavaVM(jvm); > + return 0; > } > This test seems to having trouble bedding in. I don't know which gcc version it falls foul of the above but the patch looks okay to me. -Alan From peter.levart at gmail.com Mon Apr 8 12:44:31 2019 From: peter.levart at gmail.com (Peter Levart) Date: Mon, 8 Apr 2019 14:44:31 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> Message-ID: On 4/8/19 1:40 PM, Aleksey Shipilev wrote: > On 4/8/19 1:28 PM, Peter Levart wrote: >> The reasoning is very similar as with just one field. With one field (hash) the thread sees either >> the default value (0) or a non-zero value calculated either by this thread sometime before or by a >> concurrent thread that has already stored it. Regardless of ordering, the thread either uses the >> non-zero value or (re)calculates it (again). The value calculation is deterministic and uses >> immutable published state (the array), so it always calculates the same value for the same object. >> Idempotence is guaranteed. >> >> The same reasoning can be extended to a general case where there are many fields used for caching of >> a calculated state from some immutable published state. The constraint is that the calculation must >> be deterministic and must also deterministically choose which of the many fields used for caching is >> to be modified. Only one field may be modified, never more than one. The thread therefore sees >> either the default values of all fields or the default values of all but one field which has been >> set by either this thread sometime before or by a concurrent thread. Regardless of ordering, the >> thread either uses the state combined from the default values of all fields but one and a >> non-default value of a single field or (re)calculates the non-default value of the single field. The >> value calculation is deterministic, uses immutable published state and deterministically chooses the >> field to modify, so it always calculates the same "next" state for the object. Idempotence is >> guaranteed. > Thank you, the mere existence of this wall of text solidifies my argument: the need to invoke the > argument like that is exactly the cognitive complexity I've been talking about, and it speaks about > maintainability/risk cost, while benefits are still around the machine epsilon. I tried to write the two descriptions side by side to show that the 2nd is not more complex than the 1st. It's just using longer "nouns". The sentences are otherwise equivalent and there's additional text that describes the "nouns". I could have done a better job though... So here's 2nd try: The String hash code caching (as it is written today) is an example of a benign data race that can be described as caching of lazily calculated state from immutable published state, both modeled in the same object. Data race is benign if: - the published state which is used as input of the calculation is immutable - the calculation is deterministic - threads observe the cached calculated state of the object to be updated just once atomically. Meaning that there are only two different observable states of object: "initial" state where the calculated cached data is not set and "updated" state where the the calculated cached data is set. Java fields up to 32 bits wide (+ reference fields regardless of width) exhibit atomic updates. So if the update of the object state (transition from "initial" to "updated" state) is performed by a write of a deterministically calculated value to a single deterministically chosen field of no more than 32 bits (or a reference field), the whole object state is observed to change atomically and the data race is benign. Current and proposed caching differ only in the number of fields used for caching the calculated state, but both adhere to the above rules. So the reasoning stays the same as with current code. It only takes a little to realize that it's all about a single field that is updated while the presence of other fields (zero or more) don't change the picture since they are constant for the whole lifetime of object. If you're afraid that a future maintainer of that code would not realize that, then a simple comment put into String.hashCode method and java_lang_String::set_hash C++ metohd that would say something like the following: // only a single field may be modified so that the Object state is updated atomically ...is surely going to help him/her keep the String free from bugs... Regards, Peter From david.holmes at oracle.com Mon Apr 8 13:08:52 2019 From: david.holmes at oracle.com (David Holmes) Date: Mon, 8 Apr 2019 23:08:52 +1000 Subject: RFR (XS) 8222111: exeCallerAccessTest.c fails to build: control reaches end of non-void function In-Reply-To: References: <20e9e5e3-ea1b-da85-fc44-50a92e627a75@redhat.com> Message-ID: +1 Strange that an old gcc complains but the newer ones that add more and more warnings each time, let this slip through :( Arguably all the exit(-1) in the main method should just be return -1 instead - but that's a different matter. Thanks, David On 8/04/2019 10:08 pm, Alan Bateman wrote: > On 08/04/2019 12:54, Aleksey Shipilev wrote: >> Bug: >> ?? https://bugs.openjdk.java.net/browse/JDK-8222111 >> >> Fix: >> >> diff -r 0d7fb7f07134 >> test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c >> --- >> a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c >> Mon Apr 08 06:56:37 >> 2019 +0100 >> +++ >> b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c >> Mon Apr 08 13:53:51 >> 2019 +0200 >> @@ -94,4 +94,5 @@ >> >> ????? (*jvm)->DestroyJavaVM(jvm); >> +??? return 0; >> ? } >> > This test seems to having trouble bedding in. I don't know which gcc > version it falls foul of the above but the patch looks okay to me. > > -Alan From shade at redhat.com Mon Apr 8 13:23:44 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 8 Apr 2019 15:23:44 +0200 Subject: RFR (XS) 8222111: exeCallerAccessTest.c fails to build: control reaches end of non-void function In-Reply-To: References: <20e9e5e3-ea1b-da85-fc44-50a92e627a75@redhat.com> Message-ID: On 4/8/19 3:08 PM, David Holmes wrote: > +1 Thanks, I am going to push this under triviality rule. > Strange that an old gcc complains but the newer ones that add more and more warnings each time, let > this slip through :( Yeah, compilers :/ > Arguably all the exit(-1) in the main method should just be return -1 instead - but that's a > different matter. Yes. I submitted https://bugs.openjdk.java.net/browse/JDK-8222120 for other cases that (surprisingly) do not break the build (yet?). -Aleksey From shade at redhat.com Mon Apr 8 13:40:41 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 8 Apr 2019 15:40:41 +0200 Subject: RFR (XS) 8222111: exeCallerAccessTest.c fails to build: control reaches end of non-void function In-Reply-To: References: <20e9e5e3-ea1b-da85-fc44-50a92e627a75@redhat.com> Message-ID: On 4/8/19 3:23 PM, Aleksey Shipilev wrote: > On 4/8/19 3:08 PM, David Holmes wrote: >> +1 > > Thanks, I am going to push this under triviality rule. jdk-submit cleared the change. Pushed. -Aleksey From Alan.Bateman at oracle.com Mon Apr 8 13:59:20 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 8 Apr 2019 14:59:20 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> <296e270c-0db1-1cdb-c4c3-147cbfd417ea@redhat.com> Message-ID: <1de0a2d6-ab0a-4e02-9216-75a2e545bc87@oracle.com> On 08/04/2019 10:52, Andrew Dinn wrote: > : > I created the following CSR > > https://bugs.openjdk.java.net/browse/JDK-8222107 > > Apologies if I got anything wrong (first time I have done this :-). > > Do I need to solicit reviews or does this automatically get dispatched > to the relevant component/sub-component leads? Once you have a Reviewer then you can finalize it. One thing that we haven't discussed is equality. If someone invokes FileChannel.map with a map mode created with new MapMode("READ_WRITE") then it will throw UOE as it's not (reference) equal to MapMode.READ_WRITE. It's implied by the javadoc "One of the constants ..." but now that it is extensible then we may need a statement in the javadoc - do you want me to suggest something? -Alan From adinn at redhat.com Mon Apr 8 14:05:29 2019 From: adinn at redhat.com (Andrew Dinn) Date: Mon, 8 Apr 2019 15:05:29 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: <1de0a2d6-ab0a-4e02-9216-75a2e545bc87@oracle.com> References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> <296e270c-0db1-1cdb-c4c3-147cbfd417ea@redhat.com> <1de0a2d6-ab0a-4e02-9216-75a2e545bc87@oracle.com> Message-ID: On 08/04/2019 14:59, Alan Bateman wrote: > On 08/04/2019 10:52, Andrew Dinn wrote: >> : >> I created the following CSR >> >> ?? https://bugs.openjdk.java.net/browse/JDK-8222107 >> >> Apologies if I got anything wrong (first time I have done this :-). >> >> Do I need to solicit reviews or does this automatically get dispatched >> to the relevant component/sub-component leads? > Once you have a Reviewer then you can finalize it. Ok, reviews for the above CSR are officially requested ... > One thing that we haven't discussed is equality. If someone invokes > FileChannel.map with a map mode created with new MapMode("READ_WRITE") > then it will throw UOE as it's not (reference) equal to > MapMode.READ_WRITE. It's implied by the javadoc "One of the constants > ..." but now that it is extensible then we may need a statement in the > javadoc - do you want me to suggest something? Hmm, yes that's an interesting point. Of course, I'll take whatever suggestions you are willing to throw this way :-) regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From GROEGES at uk.ibm.com Mon Apr 8 14:13:54 2019 From: GROEGES at uk.ibm.com (Steve Groeger) Date: Mon, 8 Apr 2019 15:13:54 +0100 Subject: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException In-Reply-To: References: <501ff931-c50e-ac82-6ac6-ae71a6da0ffa@oracle.com> <1a9a27e6-d196-3fa1-fda4-9a3a80b327cc@oracle.com> Message-ID: Hi Daniel, Thanks, have created a new webrev [1] Once it is merged I will then work on getting it back-ported to jdk11u. Thanks for all your assistance in getting this done. [1] http://cr.openjdk.java.net/~sgroeger/8222027/webrev.04/ Thanks Steve Groeger IBM Runtime Technologies Hursley, Winchester Tel: (44) 1962 816911 Mobex: 279990 Mobile: 07718 517 129 Fax (44) 1962 816800 Lotus Notes: Steve Groeger/UK/IBM Internet: groeges at uk.ibm.com Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From: Daniel Fuchs To: Steve Groeger Cc: OpenJDK Core Libs Developers Date: 08/04/2019 12:53 Subject: Re: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException Hi Steve, On 08/04/2019 12:21, Steve Groeger wrote: > Hi Daniel, > > Thanks for agreeing to sponsor this update. > Have created a new webrev [1] according to the instructions you pointed > me at. > Would be grateful if you could re-review and then do whatever is needed > to get this into the code. > > [1] _https://urldefense.proofpoint.com/v2/url?u=http-3A__cr.openjdk.java.net_-7Esgroeger_8222027_webrev.03_-5F&d=DwID-g&c=jf_iaSHvJObTbx-siA1ZOg&r=78GW2OHz7nNTH2dBkTx7-TKh2QCt3JD3zukzeUO8RpA&m=41IZgAR3sbHm4Hguv8daLthkNQet2Z01z67syH-9YRQ&s=lly5Dkb_dCxGkoo7yv2lrqeeUTngOBJOPgC1zpq-Vz8&e= If you look at https://urldefense.proofpoint.com/v2/url?u=http-3A__cr.openjdk.java.net_-7Esgroeger_8222027_webrev.03_jdk.changeset&d=DwID-g&c=jf_iaSHvJObTbx-siA1ZOg&r=78GW2OHz7nNTH2dBkTx7-TKh2QCt3JD3zukzeUO8RpA&m=41IZgAR3sbHm4Hguv8daLthkNQet2Z01z67syH-9YRQ&s=QZGivAQl3ESAhnQfkj2g98WbRTcHhZ9xHvsBVZa6K1g&e= you will see that your OpenJDK user name already appears in the changeset (line 2) - so you don't need the Contributed-by line. The changeset, when pushed, will already appear has being authored by `sgroeger`. The contributor line is only needed when the contributor is not an OpenJDK author yet, or when there are several contributors. Could you please remove that line and regenerate the changeset? I'll then be able to import it in my local repo - verifies that our test system is happy with it (I don't expect any issue there), and push it for you. > Once this is contributed to jdk repository, could this also be > contributed back to jdk11u. You will need to negotiate that with the OpenJDK 12 and OpenJDK 11 maintainers - and follow the rules for the updates projects there: https://urldefense.proofpoint.com/v2/url?u=http-3A__openjdk.java.net_projects_jdk-2Dupdates_&d=DwID-g&c=jf_iaSHvJObTbx-siA1ZOg&r=78GW2OHz7nNTH2dBkTx7-TKh2QCt3JD3zukzeUO8RpA&m=41IZgAR3sbHm4Hguv8daLthkNQet2Z01z67syH-9YRQ&s=G2UKtWyGya28sjIe7qXTC0MnM7GO4Jw9AxQP-X86vNk&e= Since this is a test bug that should apply cleanly I don't think that should be an issue. But you will need to find a sponsor for those. best regards, -- daniel > > Thanks > Steve Groeger > IBM Runtime Technologies > Hursley, Winchester > Tel: (44) 1962 816911 Mobex: 279990 Mobile: 07718 517 129 > Fax (44) 1962 816800 > Lotus Notes: Steve Groeger/UK/IBM > Internet: groeges at uk.ibm.com Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From shade at redhat.com Mon Apr 8 14:55:35 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 8 Apr 2019 16:55:35 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> Message-ID: <9d272e1d-7c49-017c-7313-57636b103003@redhat.com> On 4/8/19 2:44 PM, Peter Levart wrote: > If you're afraid that a future maintainer of that code would not realize that, then a simple comment > put into String.hashCode method and java_lang_String::set_hash C++ metohd that would say something > like the following: > > // only a single field may be modified so that the Object state is updated atomically > > ...is surely going to help him/her keep the String free from bugs... (sighs) Famous last words! Let me try again myself. Benign data race is already creepy enough in its original form. You have to come up with the overwhelming reason to complicate it even further. Why introduce this complexity to begin with? That's my argument. The complication of this code gives us almost nothing in return, why make the change? Without the compelling reason to do it, all this is just a runaway "hold my beer" micro-optimization exercise, which is fun and instructional, but should not be pushed to the actual JDK. In other words, just because we *can* it does not follow that we *should*. -Aleksey From adinn at redhat.com Mon Apr 8 15:10:51 2019 From: adinn at redhat.com (Andrew Dinn) Date: Mon, 8 Apr 2019 16:10:51 +0100 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <9d272e1d-7c49-017c-7313-57636b103003@redhat.com> References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> <9d272e1d-7c49-017c-7313-57636b103003@redhat.com> Message-ID: <0d75c78f-c255-147f-ed80-af940ce7b509@redhat.com> On 08/04/2019 15:55, Aleksey Shipilev wrote: > Why introduce this complexity to begin with? That's my argument. The complication of this code gives > us almost nothing in return, why make the change? Without the compelling reason to do it, all this > is just a runaway "hold my beer" micro-optimization exercise, which is fun and instructional, but > should not be pushed to the actual JDK. In other words, just because we *can* it does not follow > that we *should*. I think that is a good argument. The vast majority of apps are not going to see any performance hit from the relatively rare occurrence of zero hashes. Those rare apps which see a lot of them will still only see a marginal performance hit. n.b. I say marginal because I believe that an app which sees enough zero hashes for the effect not to be marginal (i.e.it is not doing much else) is probably not an app but a Trojan horse of a (micro?) benchmark masquerading as an app (timeo Danaos et lecti marcae ferentes -- pardon my Latin and don't ask what those notches on the couch might mean ;-). So, I agree with Aleksey that adding a potential maintenance headache for this little gain is not the right trade-off. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From claes.redestad at oracle.com Mon Apr 8 15:24:57 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 8 Apr 2019 17:24:57 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <3453bd0a-37e6-957e-f1ea-f86fe7a9ff17@gmail.com> References: <3453bd0a-37e6-957e-f1ea-f86fe7a9ff17@gmail.com> Message-ID: <06bf9a51-7ed2-9b01-994c-f08832e3cf46@oracle.com> Right, this and possibly reducing latency when running with String deduplication enabled might be the more tangible benefits. Removing a cause for spurious performance degradations is nice, but mainly theoretical. There's likely a pre-existing negative interaction between string dedup and String archiving that would need to be resolved either way. I've simplified the patch somewhat and folded set_hash/hash into hash_code (since direct manipulation of the hash field should be avoided), along with a comment to try and explain and caution about the data race: http://cr.openjdk.java.net/~redestad/8221836/open.02/ Thanks! /Claes On 2019-04-08 12:24, Peter Levart wrote: > I think the most benefit in this patch is the emptyString.hashCode() > speedup. By holding a boolean flag in the String object itself, there is > one less de-reference to be made on fast-path in case of empty string. > Which shows in microbenchmark and would show even more if code iterated > many different instances of empty strings that don't share the > underlying array invoking .hashCode() on them. Which, I admit, is not a > frequent case in practice, but hey, it is a speedup after all. > > Regards, Peter From ivan.gerasimov at oracle.com Mon Apr 8 16:12:36 2019 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Mon, 8 Apr 2019 09:12:36 -0700 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: References: Message-ID: Hi Claes! Would it make sense to preset hashIsZero = true in the empty string constructor? The current code avoids calculating the hashCode for an empty string, and the new code doesn't seem to do that because hashIsZero = false by default for each newly constructed copy of the empty string. With kind regards, Ivan On 4/8/19 1:41 AM, Claes Redestad wrote: > Hi, > > by adding a bit to String that is true iff String.hash has been > calculated as being 0, we can get rid of the corner case where such hash > codes are recalculated on every call. > > Peter Levart came up with a elegant scheme for ensuring that we can keep > using non-volatile stores without explicit fencing and still reap the > benefits of this[1], and I've synced up the hotspot code that deals with > the String.hash value to mirror that logic. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8221836 > Webrev: http://cr.openjdk.java.net/~redestad/8221836/open.01/ > > Since there exists small padding gaps in the current object layout of > strings (on all VM bitness and compressed oops varieties), adding this > boolean does not add any extra footprint per String instance. > > Testing: tier1-3, verified a speed-up in targeted microbenchmarks. > > Thanks! > > /Claes > > [1] > http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-April/059480.html > -- With kind regards, Ivan Gerasimov From claes.redestad at oracle.com Mon Apr 8 16:26:51 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 8 Apr 2019 18:26:51 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: References: Message-ID: Hi Ivan, not sure that would be an optimization, since you'd trade a conditional write for an unconditional one. The computation itself for the empty string has trivial cost. /Claes On 2019-04-08 18:12, Ivan Gerasimov wrote: > Hi Claes! > > Would it make sense to preset hashIsZero = true in the empty string > constructor? > > The current code avoids calculating the hashCode for an empty string, > and the new code doesn't seem to do that because hashIsZero = false by > default for each newly constructed copy of the empty string. > > With kind regards, > Ivan From daniel.fuchs at oracle.com Mon Apr 8 16:57:38 2019 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Mon, 8 Apr 2019 17:57:38 +0100 Subject: RFR: TEST_BUG: 8222027 - java/util/logging/LogManager/TestLoggerNames.java generates intermittent ClassCastException In-Reply-To: References: <501ff931-c50e-ac82-6ac6-ae71a6da0ffa@oracle.com> <1a9a27e6-d196-3fa1-fda4-9a3a80b327cc@oracle.com> Message-ID: <14b3c862-a744-28a8-d40c-652fdc5dadc2@oracle.com> Thanks Steve, I just pushed it: http://hg.openjdk.java.net/jdk/jdk/rev/e5713cefcf41 best regards, -- daniel On 08/04/2019 15:13, Steve Groeger wrote: > Hi Daniel, > > Thanks, have created a new webrev [1] > Once it is merged I will then work on getting it back-ported to jdk11u. > Thanks for all your assistance in getting this done. > > [1] _http://cr.openjdk.java.net/~sgroeger/8222027/webrev.04/_ > From claes.redestad at oracle.com Mon Apr 8 21:19:22 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 8 Apr 2019 23:19:22 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <0d75c78f-c255-147f-ed80-af940ce7b509@redhat.com> References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> <9d272e1d-7c49-017c-7313-57636b103003@redhat.com> <0d75c78f-c255-147f-ed80-af940ce7b509@redhat.com> Message-ID: On 2019-04-08 17:10, Andrew Dinn wrote: > On 08/04/2019 15:55, Aleksey Shipilev wrote: >> Why introduce this complexity to begin with? That's my argument. The complication of this code gives >> us almost nothing in return, why make the change? Without the compelling reason to do it, all this >> is just a runaway "hold my beer" micro-optimization exercise, which is fun and instructional, but >> should not be pushed to the actual JDK. In other words, just because we *can* it does not follow >> that we *should*. > I think that is a good argument. The vast majority of apps are not going > to see any performance hit from the relatively rare occurrence of zero > hashes. Those rare apps which see a lot of them will still only see a > marginal performance hit. > > n.b. I say marginal because I believe that an app which sees enough zero > hashes for the effect not to be marginal (i.e.it is not doing much else) > is probably not an app but a Trojan horse of a (micro?) benchmark > masquerading as an app (timeo Danaos et lecti marcae ferentes -- pardon > my Latin and don't ask what those notches on the couch might mean ;-). > > So, I agree with Aleksey that adding a potential maintenance headache > for this little gain is not the right trade-off. First, I disagree strongly that this patch adds significant complexity (especially after recent simplifications[1]) or that it risks increasing maintenance headache down the line. Secondly, I think the gain w.r.t. defense-in-depth is very real. Sure, we have alt-hashing and similar counter-measures in various JDK collection libraries, but that is unlikely to help every API or library ever invented out there. Third... well, the other performance gains are of course nice-to- have - improvements to "".hashCode() and allowing String deduplication to not have to filter out such Strings - but I agree that they are likely mostly theoretical for anything real-world. If this change then exposes a bug in some unexpected place elsewhere (I can only guess what dangers lurks out there... unforeseen interaction with a weaker memory model? some wonky JIT reordering?) then that might even be for the better in the end. If/when that happens, we can opt to back this out (or not) while addressing whatever issue we've unearthed. /Claes [1] http://cr.openjdk.java.net/~redestad/8221836/open.02/ From john.r.rose at oracle.com Mon Apr 8 21:31:40 2019 From: john.r.rose at oracle.com (John Rose) Date: Mon, 8 Apr 2019 14:31:40 -0700 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <06bf9a51-7ed2-9b01-994c-f08832e3cf46@oracle.com> References: <3453bd0a-37e6-957e-f1ea-f86fe7a9ff17@gmail.com> <06bf9a51-7ed2-9b01-994c-f08832e3cf46@oracle.com> Message-ID: <0A870E14-A24E-4C67-9D93-BC6A9FE4EB50@oracle.com> I agree that this is a good change, and you can use me as a reviewer. I disagree with Aleksey; it's a new technique but not complex to document or understand. The two state components are independent in their action; there is no race between their state changes. Meanwhile, there are two reasons I want the change: 1. Less risk of spurious updates to COW memory segments in shared archives. 2. No risk of hashcode recomputation for the 2^-32 case. This might seem laughable, until you remember that it's exactly those cases that DOS attackers like to create. Both are defense in depth, against performance potholes and intentional attacks. If we spent as much time documenting this change as we spent complaining about its supposed uselessness, we'd be done. ? John On Apr 8, 2019, at 8:24 AM, Claes Redestad wrote: > > Right, this and possibly reducing latency when running with String > deduplication enabled might be the more tangible benefits. Removing > a cause for spurious performance degradations is nice, but mainly > theoretical. There's likely a pre-existing negative interaction > between string dedup and String archiving that would need to be > resolved either way. > > I've simplified the patch somewhat and folded set_hash/hash into > hash_code (since direct manipulation of the hash field should be > avoided), along with a comment to try and explain and caution about the > data race: > > http://cr.openjdk.java.net/~redestad/8221836/open.02/ > > Thanks! > > /Claes > > On 2019-04-08 12:24, Peter Levart wrote: >> I think the most benefit in this patch is the emptyString.hashCode() speedup. By holding a boolean flag in the String object itself, there is one less de-reference to be made on fast-path in case of empty string. Which shows in microbenchmark and would show even more if code iterated many different instances of empty strings that don't share the underlying array invoking .hashCode() on them. Which, I admit, is not a frequent case in practice, but hey, it is a speedup after all. >> Regards, Peter From alexander.matveev at oracle.com Mon Apr 8 21:41:47 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Mon, 8 Apr 2019 14:41:47 -0700 Subject: RFR: JDK-8221749: Error messages In-Reply-To: <6b91294f-445c-bf88-2a8c-c65f7add48a7@oracle.com> References: <6b91294f-445c-bf88-2a8c-c65f7add48a7@oracle.com> Message-ID: <0a4eff35-f3a8-5388-d740-850be5e9874c@oracle.com> Hi Andy, Looks good. Also, many messages (including added in this review) in MainResources.properties do have "." at the end and some don't. I think we should cleanup it and add "." if needed. Thanks, Alexander On 4/8/2019 4:41 AM, Andy Herrick wrote: > Please review the jpackage fix for bug [1] at [2]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > [1] http://cr.openjdk.java.net/~herrick/8221749/ > > [2] https://bugs.openjdk.java.net/browse/JDK-8221749/ > > /Andy From claes.redestad at oracle.com Mon Apr 8 21:42:34 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 8 Apr 2019 23:42:34 +0200 Subject: RFR: 8222144: Lazily create JRT code source URLs for LoadedModules Message-ID: Hi, currently we eagerly convert code source URIs to URLs to avoid recursive bootstrap issues with overrideable URL handlers. The JRT scheme handler is not overrideable, however, and also commonly used for all system modules. Creating these URLs lazily is a reasonable startup optimization since most applications will only ever load from a small fraction of the resolved system modules. Bug: https://bugs.openjdk.java.net/browse/JDK-8222144 Webrev: http://cr.openjdk.java.net/~redestad/8222144/open.00/ Testing: tier1-2, improvements on all metrics on small startup tests Thanks! /Claes From andy.herrick at oracle.com Mon Apr 8 22:05:01 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Mon, 8 Apr 2019 18:05:01 -0400 Subject: RFR: JDK-8221749: Error messages In-Reply-To: <0a4eff35-f3a8-5388-d740-850be5e9874c@oracle.com> References: <6b91294f-445c-bf88-2a8c-c65f7add48a7@oracle.com> <0a4eff35-f3a8-5388-d740-850be5e9874c@oracle.com> Message-ID: <2ba2aaa4-cf02-6da8-69bd-70e3ff011921@oracle.com> On 4/8/2019 5:41 PM, Alexander Matveev wrote: > Hi Andy, > > Looks good. > > Also, many messages (including added in this review) in > MainResources.properties do have "." at the end and some don't. I > think we should cleanup it and add "." if needed. Yes - some messages are not full sentences, but most are.? Those that are should end in a period. I will address that in the next clean-up change. /ANdy > > Thanks, > Alexander > > On 4/8/2019 4:41 AM, Andy Herrick wrote: >> Please review the jpackage fix for bug [1] at [2]. >> >> This is a fix for the JDK-8200758-branch branch of the open sandbox >> repository (jpackage). >> >> [1] http://cr.openjdk.java.net/~herrick/8221749/ >> >> [2] https://bugs.openjdk.java.net/browse/JDK-8221749/ >> >> /Andy > From joe.darcy at oracle.com Mon Apr 8 23:35:46 2019 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Mon, 08 Apr 2019 16:35:46 -0700 Subject: RFR: 8222029: Optimize Math.floorMod In-Reply-To: <5d2c75de-474c-4376-3587-cfee6100f920@oracle.com> References: <407d708a-ab81-bf8a-63fb-d3d769cfe1c3@redhat.com> <5d2c75de-474c-4376-3587-cfee6100f920@oracle.com> Message-ID: <5CABDAD2.9000609@oracle.com> Should any additional cases be added to test/jdk/java/lang/Math/DivModTests.java to cover the new implementation? Thanks, -Joe On 4/5/2019 10:21 AM, Claes Redestad wrote: > > > On 2019-04-05 17:41, Andrew Haley wrote: >> On 4/5/19 2:44 PM, Claes Redestad wrote: >>> Testing: tier1-2, all Math tests run locally, -prof perfasm >>> verification >>> on the provided microbenchmark. >> >> Looks good. > > Thanks! > >> >> I've kicked the tyres on AArch64, and it looks like a useful >> optimization. The >> gains when the divisor is constant (a common case) are modest but >> worthwhile. >> > > Thanks for trying it out and glad to hear it helps on AArch64 as well. > > /Claes From vicente.romero at oracle.com Tue Apr 9 00:39:39 2019 From: vicente.romero at oracle.com (Vicente Romero) Date: Mon, 8 Apr 2019 20:39:39 -0400 Subject: [PATCH] Some improvements for java.lang.Class In-Reply-To: <23961631554580494@sas1-46c84f197234.qloud-c.yandex.net> References: <2796501552936166@myt6-add70abb4f02.qloud-c.yandex.net> <352521553106953@myt5-184376c2d7f8.qloud-c.yandex.net> <1a181b47-e392-c1f7-1ecc-2cf1ab5cd4d2@gmail.com> <10151351553631340@myt6-fe24916a5562.qloud-c.yandex.net> <7DEC01F5-AD44-4E50-BBEE-F493AB63583B@oracle.com> <7147981554385366@myt6-27270b78ac4f.qloud-c.yandex.net> <23961631554580494@sas1-46c84f197234.qloud-c.yandex.net> Message-ID: Hi Sergei, I have created issue [1] to track your enhancement. Please cc me in your next mails I will be helping you to do the paperwork. Talking about that did you sign the OCA, [2]? Thanks, Vicente [1] https://bugs.openjdk.java.net/browse/JDK-8222151 [2] https://www.oracle.com/technetwork/community/oca-486395.html From mandy.chung at oracle.com Tue Apr 9 02:16:14 2019 From: mandy.chung at oracle.com (Mandy Chung) Date: Tue, 9 Apr 2019 10:16:14 +0800 Subject: RFR (XS) 8222111: exeCallerAccessTest.c fails to build: control reaches end of non-void function In-Reply-To: References: <20e9e5e3-ea1b-da85-fc44-50a92e627a75@redhat.com> Message-ID: <526df24a-ca83-bb0c-ca8d-4c0e1e942c08@oracle.com> The patch looks good (the return statement is missing).? Thanks for fixing it. Mandy P.S. Sorry for the belated review. Good to see this pushed.? I'm OOO. On 4/8/19 9:23 PM, Aleksey Shipilev wrote: > On 4/8/19 3:08 PM, David Holmes wrote: >> +1 > Thanks, I am going to push this under triviality rule. > >> Strange that an old gcc complains but the newer ones that add more and more warnings each time, let >> this slip through :( > Yeah, compilers :/ > >> Arguably all the exit(-1) in the main method should just be return -1 instead - but that's a >> different matter. > Yes. I submitted https://bugs.openjdk.java.net/browse/JDK-8222120 for other cases that > (surprisingly) do not break the build (yet?). > > -Aleksey > From gnu.andrew at redhat.com Tue Apr 9 03:26:52 2019 From: gnu.andrew at redhat.com (Andrew John Hughes) Date: Tue, 9 Apr 2019 04:26:52 +0100 Subject: RFR: [8u] 8205432: Replace the placeholder Japanese era name In-Reply-To: References: Message-ID: <1732312a-2e9b-59bb-6619-06500830e22d@redhat.com> On 08/04/2019 09:25, Deepak Kejriwal wrote: > Hi Andrew, > > Thanks for working on this. Please find below few minor comments:- > > 1>. For "src/share/classes/java/util/JapaneseImperialCalendar.java" and "src/share/classes/sun/util/calendar/Era.java" please changes the date time format to be consistent with existing defined eras:- > * 4 Heisei 1989-01-08 midnight local time > - * 5 NewEra 2019-05-01 midnight local time > + * 5 Reiwa 2019-05-01T00:00:00 local time > > Please change "2019-05-01T00:00:00 local time" to "2019-05-01 midnight local time" > The change in style is a cleanup that is part of JDK-8048123 [0]. I think we're better bringing over those cleanups than making Reiwa use the bad format, so I've incorporated those parts of [1] into the revised webrev. > 2>. For "test/java/time/test/java/time/chrono/TestJapaneseChronology.java" please align "JapaneseEra.of(3)" with existing defined eras in "Object[][] eraNameData()". > I've fixed this too, but note that this comes from the original patch in 11 and up. So it actually needs fixing there too. Revised webrev: https://cr.openjdk.java.net/~andrew/openjdk8/8205432/webrev.02/ > > Regards, > Deepak > [0] https://mail.openjdk.java.net/pipermail/i18n-dev/2014-July/001438.html [1] https://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/91ea77c474b9 -- Andrew :) Senior Free Java Software Engineer Red Hat, Inc. (http://www.redhat.com) PGP Key: ed25519/0xCFDA0F9B35964222 (hkp://keys.gnupg.net) Fingerprint = 5132 579D D154 0ED2 3E04 C5A0 CFDA 0F9B 3596 4222 https://keybase.io/gnu_andrew From amaembo at gmail.com Tue Apr 9 04:26:00 2019 From: amaembo at gmail.com (Tagir Valeev) Date: Tue, 9 Apr 2019 11:26:00 +0700 Subject: [PATCH] Some improvements for java.lang.Class In-Reply-To: <352521553106953@myt5-184376c2d7f8.qloud-c.yandex.net> References: <2796501552936166@myt6-add70abb4f02.qloud-c.yandex.net> <352521553106953@myt5-184376c2d7f8.qloud-c.yandex.net> Message-ID: Hello! As an author of the IDE inspection in question I should mention that there's slight difference between for(int i=0; i= 0. So totally mechanical replacement should work fine, but may produce some amount of unnecessary Math.max and deciding whether to keep or remove them requires thinking. With best regards, Tagir Valeev. On Thu, Mar 21, 2019 at 1:37 AM ?????? ??????? wrote: > > I had a brief conversation with Brian Goetz which has left off the mailing list for some reason. Here's the text: > --------------------------- > Brian: > > These enhancements seem reasonable; these are exactly the cases that String::repeat was intended for. (This is a ?is this a reasonable idea? review, not a code review.). > Have you looked for other places where similar transformations could be done? > > --------------------------- > Me: > > Hello, > after I had realized that looped StringBuilder::append calls can sometimes be replaced with String::repeat I requested corresponding inspection in IDEA issue tracker. > Using the inspection I?ve found 129 similar warnings in jdk13 repo. > Some of them are very promising, e.g. BigDecimal:: toPlainString where currently we have > > > int trailingZeros = checkScaleNonZero((-(long)scale)); > > StringBuilder buf; > > if(intCompact!=INFLATED) { > > buf = new StringBuilder(20+trailingZeros); > > buf.append(intCompact); > > } else { > > String str = intVal.toString(); > > buf = new StringBuilder(str.length()+trailingZeros); > > buf.append(str); > > } > > for (int i = 0; i < trailingZeros; i++) { > > buf.append('0'); > > } > > return buf.toString(); > > which in fact can be simplified to > > > int trailingZeros = checkScaleNonZero((-(long)scale)); > > if(intCompact!=INFLATED) { > > return intCompact + "0".repeat(trailingZeros); > > } else { > > return intVal.toString() + "0".repeat(trailingZeros); > > } > > The second solution is not only shorter and more simple but it likely to be significantly faster and memory-saving. > BTW, your reply to original message for some reason is missing from web-view. > > --------------------------- > Brian: > > Cool. Note that replacing append() calls with repeat is not necessarily a win for anything other than code compactness; String::repeat will create a new string, which will then get appended to another StrinBuilder. So when used correctly (such as presized StringBuilders) appending in a loop is probably just as fast (look at the implementation of String::repeat.). > > > if(intCompact!=INFLATED) { > > return intCompact + "0".repeat(trailingZeros); > > } else { > > return intVal.toString() + "0".repeat(trailingZeros); > > } > > Which can be further simplified to > > > ((intCompact != INFLATED) ? intCompact : intVal.toString) + ?0?.repeat(trailingZeros); > > The second solution is not only shorter and more simple but it likely to be significantly faster and memory-saving. > I like short and simple. I am questioning the ?faster and memory saving.? That should be validated. > > --------------------------- > Me: > > I think optimizations provided by JEP 280 allow compiler to optimize String concatenation executed with '+' by using StringBuilder of exact size (when the size of all components is known, like in our case). > > I've checked this with benchmark > > > @State(Scope.Thread) > > @BenchmarkMode(Mode.AverageTime) > > @OutputTimeUnit(TimeUnit.NANOSECONDS) > > @Fork(jvmArgsAppend = {"-Xms2g", "-Xmx2g"}) > > public class ConcatBenchmark { > > > > @Param({"1", "2", "5", "8"}) > > private int trailingZeros; > > > > private final long intCompact = 1L; > > > > @Benchmark > > public String stringBuilder() { > > StringBuilder buf; > > buf = new StringBuilder(20 + trailingZeros); > > buf.append(intCompact); > > for (int i = 0; i < trailingZeros; i++) { > > buf.append('0'); > > } > > return buf.toString(); > > } > > @Benchmark > > public String stringRepeat() { > > return intCompact + "0".repeat(trailingZeros); > > } > > } > > Results: > trailingZeros Mode Cnt Score Error Units > stringBuilder 1 avgt 15 17,683 ? 0,664 ns/op > stringRepeat 1 avgt 15 9,052 ? 0,042 ns/op > > stringBuilder 2 avgt 15 19,053 ? 1,206 ns/op > stringRepeat 2 avgt 15 15,864 ? 1,331 ns/op > > stringBuilder 5 avgt 15 25,839 ? 2,256 ns/op > stringRepeat 5 avgt 15 19,290 ? 1,685 ns/op > > stringBuilder 8 avgt 15 26,488 ? 0,371 ns/op > stringRepeat 8 avgt 15 19,420 ? 1,593 ns/op > > stringBuilder:?gc.alloc.rate.norm 1 avgt 15 88,000 ? 0,001 B/op > stringRepeat:?gc.alloc.rate.norm 1 avgt 15 48,000 ? 0,001 B/op > > stringBuilder:?gc.alloc.rate.norm 2 avgt 15 88,000 ? 0,001 B/op > stringRepeat:?gc.alloc.rate.norm 2 avgt 15 72,000 ? 0,001 B/op > > stringBuilder:?gc.alloc.rate.norm 5 avgt 15 96,000 ? 0,001 B/op > stringRepeat:?gc.alloc.rate.norm 5 avgt 15 72,000 ? 0,001 B/op > > stringBuilder:?gc.alloc.rate.norm 8 avgt 15 104,000 ? 0,001 B/op > stringRepeat:?gc.alloc.rate.norm 8 avgt 15 80,000 ? 0,001 B/op > > > I think this is a useful optimization, so we should use String::repeat where possible. > > --------------------------- > Brian: > > My recommendation is to split your patch into two. The first is the straightforward ?replace loop with repeat? refactoring, which can be mechanically generated by the IDE. Here, you should examine each site to ensure that the transform seems sensible given the context. The second can then be additional hand-refactoring opportunities exposed by the first. The benefit of splitting it this way is that reviewing the first is far easier when you can say all the changes are mechanical. > > (Somehow this fell off the list; feel free to bring it back.) > > > 18.03.2019, 21:13, "?????? ???????" : > > Hi, > > > > I have an enhancement proposal for java.lang.Class.methodToString and java.lang.Class.getTypeName. > > > > First one is used when NoSuchMethodException is thrown from Class::getMethod which is in turn widely used in Spring Framework and often throws. > > > > In current implementation we have 2 major problems: > > > > - we create stream for the case when argTypes is not null but empty (which happens e. g. when Class::getMethod is called without vararg and throws) > > - we have torn StringBuilder::append chain > > > > I?ve modified the method to skip creation of Stream for empty array and used separate StringBuilder for each case. Latter allowed to rid SB completely and use invokedynamic-based concatenation. > > > > I?ve compared both approaches for 2 cases: > > > > 1) argTypes is empty > > 2) argTypes.length == 1 > > > > Benchmark Mode Cnt Score Error Units > > > > methodToString_noArgs avgt 25 170,986 ? 5,708 ns/op > > methodToString_noArgs_patched avgt 25 26,883 ? 2,906 ns/op > > > > methodToString_1arg avgt 25 183,012 ? 0,701 ns/op > > methodToString_1arg_patched avgt 25 112,784 ? 0,920 ns/op > > > > methodToString_noArgs:?gc.alloc.rate.norm avgt 25 881,600 ? 9,786 B/op > > methodToString_noArgs_patched:?gc.alloc.rate.norm avgt 25 128,000 ? 0,001 B/op > > > > methodToString_1arg:?gc.alloc.rate.norm avgt 25 960,000 ? 0,001 B/op > > methodToString_1arg_patched:?gc.alloc.rate.norm avgt 25 552,000 ? 0,001 B/op > > > > We have the same problem regarding misusage of StringBuilder in Class:: getTypeName: > > > > StringBuilder sb = new StringBuilder(); > > sb.append(cl.getName()); > > for (int i = 0; i < dimensions; i++) { > > sb.append("[]"); > > } > > return sb.toString(); > > > > I suggest to use String::repeat instead of the loop: this again allows to get rid of StringBuilder and replace mentioned code with > > > > return cl.getName() + "[]".repeat(dimensions); > > > > Here are benchmark results executed for type Object[].class: > > > > Mode Cnt Score Error Units > > getTypeName_patched avgt 25 16,037 ? 0,431 ns/op > > getTypeName_patched:?gc.alloc.rate.norm avgt 25 64,000 ? 0,001 B/op > > > > getTypeName avgt 25 34,274 ? 1,432 ns/op > > getTypeName:?gc.alloc.rate.norm avgt 25 152,000 ? 0,001 B/op > > > > Regards, > > Sergei Tsypanov From Alan.Bateman at oracle.com Tue Apr 9 06:42:29 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 9 Apr 2019 07:42:29 +0100 Subject: RFR: 8222144: Lazily create JRT code source URLs for LoadedModules In-Reply-To: References: Message-ID: On 08/04/2019 22:42, Claes Redestad wrote: > Hi, > > currently we eagerly convert code source URIs to URLs to avoid recursive > bootstrap issues with overrideable URL handlers. The JRT scheme handler > is not overrideable, however, and also commonly used for all system > modules. Creating these URLs lazily is a reasonable startup > optimization since most applications will only ever load from a small > fraction of the resolved system modules. > > Bug:??? https://bugs.openjdk.java.net/browse/JDK-8222144 > Webrev: http://cr.openjdk.java.net/~redestad/8222144/open.00/ This looks good, a minor nit is that L127 can be if (uri != null && "jrt".equals(...)). We could extend it to "file" too because that scheme can't be overridden either. At some point we need to clean up the "may be null" comment as all modules in the boot layer have a location. Also the set of schemes is limited to jrt, file and jar so we are guaranteed to have a protocol handler (if MalformedURLException or IAE is thrown then something is broken elsewhere). -Alan From shade at redhat.com Tue Apr 9 08:11:51 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Tue, 9 Apr 2019 10:11:51 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <0A870E14-A24E-4C67-9D93-BC6A9FE4EB50@oracle.com> References: <3453bd0a-37e6-957e-f1ea-f86fe7a9ff17@gmail.com> <06bf9a51-7ed2-9b01-994c-f08832e3cf46@oracle.com> <0A870E14-A24E-4C67-9D93-BC6A9FE4EB50@oracle.com> Message-ID: <5392bd57-d2b1-0cc5-fbd0-7c1993c31729@redhat.com> On 4/8/19 11:31 PM, John Rose wrote: > I agree that this is a good change, and you can use me as a reviewer. Which opens up the process question: are you acting as Project Lead here to resolve the disagreement between Reviewers (the only accepting Reviewer being yourself)? (There are ways for me to yield: for example, accept this patch provisionally, if Claes and/or accepting reviewers agree that any follow-up issue with it triggers the immediate backout, and future attempts to introduce it are rejected given the observed non-trivial cost. This seems like a no-brainer for those who argue there is little risk in doing this.) > I disagree with Aleksey; it's a new technique but not complex > to document or understand. The two state components are > independent in their action; there is no race between their > state changes. Yes, I am a firm believer that concurrency hacks need justifications, regardless of how simple they appear at the moment. Call me paranoid, but I know enough about (Java) concurrency to be paranoid. For tiny benefits, you need to demonstrate the non-existent cost to tip the cost/benefit balance over the acceptance threshold. But even the benefits are questionable: > Meanwhile, there are two reasons I want the change: > > 1. Less risk of spurious updates to COW memory segments in > shared archives. There is no risk for current code either. How come adding the new writable field provides "less risk of updates", anyway? With one field we can track the object state in an obvious manner. Spreading that state over two fields makes it less risky how exactly? > 2. No risk of hashcode recomputation for the 2^-32 case. > This might seem laughable, until you remember that it's exactly > those cases that DOS attackers like to create. Alt-hashing covers this obscure case in the course of mitigating much easier and much broader attack on String hashcode. We don't get to wave in every single hack into class libraries under "security" justification, especially when the mitigation already exists. -Aleksey From adinn at redhat.com Tue Apr 9 08:20:31 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 9 Apr 2019 09:20:31 +0100 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> <9d272e1d-7c49-017c-7313-57636b103003@redhat.com> <0d75c78f-c255-147f-ed80-af940ce7b509@redhat.com> Message-ID: <1bfa62d2-fa96-da46-63c0-7e4cf4cf40fd@redhat.com> On 08/04/2019 22:19, Claes Redestad wrote: > First, I disagree strongly that this patch adds significant complexity > (especially after recent simplifications[1]) or that it risks increasing > maintenance headache down the line. It all depends what you mean by significant. It definitely adds complexity. If there are other benefits than the rather questionable one of avoiding infrequent zero hashes they may well justify that complexity. > Secondly, I think the gain w.r.t. defense-in-depth is very real. Sure, > we have alt-hashing and similar counter-measures in various JDK > collection libraries, but that is unlikely to help every API or library > ever invented out there. This is a better argument. > Third... well, the other performance gains are of course nice-to- > have - improvements to "".hashCode() and allowing String deduplication > to not have to filter out such Strings - but I agree that they are > likely mostly theoretical for anything real-world. Ok, so the argument is DID then? I'll buy that. > If this change then exposes a bug in some unexpected place elsewhere > (I can only guess what dangers lurks out there... unforeseen interaction > with a weaker memory model? some wonky JIT reordering?) then that might > even be for the better in the end. If/when that happens, we can opt to > back this out (or not) while addressing whatever issue we've unearthed. I don't believe Aleksey is suggesting that some hidden memory ordering or JIT transformation bug may come to bite us. As I understand it the problem he is concerned with is subsequent injection of such a bug i.e. some developer 1) not recognising that the code as it stands only works in the presence of these re-ordering possibilities by careful design and 2) mistakenly changing the code so that those possibilities are no longer bypassed. I agree that is a real concern. If the patch is to go in -- and I concede there is an acceptable argument for that -- then it needs commenting to help avoid this happening. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From adinn at redhat.com Tue Apr 9 08:36:17 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 9 Apr 2019 09:36:17 +0100 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <5392bd57-d2b1-0cc5-fbd0-7c1993c31729@redhat.com> References: <3453bd0a-37e6-957e-f1ea-f86fe7a9ff17@gmail.com> <06bf9a51-7ed2-9b01-994c-f08832e3cf46@oracle.com> <0A870E14-A24E-4C67-9D93-BC6A9FE4EB50@oracle.com> <5392bd57-d2b1-0cc5-fbd0-7c1993c31729@redhat.com> Message-ID: <6304c50d-bb9e-6a80-ba1d-462bc04c7f21@redhat.com> On 09/04/2019 09:11, Aleksey Shipilev wrote: > On 4/8/19 11:31 PM, John Rose wrote: >> I agree that this is a good change, and you can use me as a reviewer. > > Which opens up the process question: are you acting as Project Lead here to resolve the disagreement > between Reviewers (the only accepting Reviewer being yourself)? > > (There are ways for me to yield: for example, accept this patch provisionally, if Claes and/or > accepting reviewers agree that any follow-up issue with it triggers the immediate backout, and > future attempts to introduce it are rejected given the observed non-trivial cost. This seems like a > no-brainer for those who argue there is little risk in doing this.) Hmm, well, ... I just posted a reply to Claes accepting this patch on DID grounds, /assuming/ the code is suitably commented. However, I think your extra provision here is thoroughly reasonable. I'd even be happy to extend it with a promise that you can claim 'I told you so' on list if this ever happens (in CAPS, if you must :-). regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From claes.redestad at oracle.com Tue Apr 9 08:42:16 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 9 Apr 2019 10:42:16 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <1bfa62d2-fa96-da46-63c0-7e4cf4cf40fd@redhat.com> References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> <9d272e1d-7c49-017c-7313-57636b103003@redhat.com> <0d75c78f-c255-147f-ed80-af940ce7b509@redhat.com> <1bfa62d2-fa96-da46-63c0-7e4cf4cf40fd@redhat.com> Message-ID: Hi Andrew, On 2019-04-09 10:20, Andrew Dinn wrote: > If the patch is to go in -- and I concede there is an acceptable argument for that -- then it > needs commenting to help avoid this happening. open.02 already adds what I believed to be sufficient commenting, have you taken this into consideration? http://cr.openjdk.java.net/~redestad/8221836/open.02/src/java.base/share/classes/java/lang/String.java.udiff.html /Claes From peter.levart at gmail.com Tue Apr 9 08:53:32 2019 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 9 Apr 2019 10:53:32 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <5392bd57-d2b1-0cc5-fbd0-7c1993c31729@redhat.com> References: <3453bd0a-37e6-957e-f1ea-f86fe7a9ff17@gmail.com> <06bf9a51-7ed2-9b01-994c-f08832e3cf46@oracle.com> <0A870E14-A24E-4C67-9D93-BC6A9FE4EB50@oracle.com> <5392bd57-d2b1-0cc5-fbd0-7c1993c31729@redhat.com> Message-ID: <803a506d-c427-c8c0-5c56-730de7edd919@gmail.com> Hi Aleksey, On 4/9/19 10:11 AM, Aleksey Shipilev wrote: >> 2. No risk of hashcode recomputation for the 2^-32 case. >> This might seem laughable, until you remember that it's exactly >> those cases that DOS attackers like to create. > Alt-hashing covers this obscure case in the course of mitigating much easier and much broader attack > on String hashcode. We don't get to wave in every single hack into class libraries under "security" > justification, especially when the mitigation already exists. > > -Aleksey > Which alt-hashing are you talking about? The one which was removed from Java code of String in transition from JDK 7 -> JDK 8 ? AFAIK, there's no alt-caching for pure java code for Strings any more (there's something for internal JVM use). It was dropped when (Concurrent)HashMap got tree-ification. Regards, Peter From peter.levart at gmail.com Tue Apr 9 09:04:36 2019 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 9 Apr 2019 11:04:36 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> <9d272e1d-7c49-017c-7313-57636b103003@redhat.com> <0d75c78f-c255-147f-ed80-af940ce7b509@redhat.com> <1bfa62d2-fa96-da46-63c0-7e4cf4cf40fd@redhat.com> Message-ID: <543624a9-70df-3588-68f0-9246789c74a9@gmail.com> On 4/9/19 10:42 AM, Claes Redestad wrote: > Hi Andrew, > > On 2019-04-09 10:20, Andrew Dinn wrote: >> If the patch is to go in -- and I concede there is an acceptable >> argument for that -- then it >> needs commenting to help avoid this happening. > > open.02 already adds what I believed to be sufficient commenting, have > you taken this into consideration? > > http://cr.openjdk.java.net/~redestad/8221836/open.02/src/java.base/share/classes/java/lang/String.java.udiff.html > > > /Claes Perhaps you could add the same comment to the C++ java_lang_String::hash_code(oop java_string) method too? Regards, Peter From adinn at redhat.com Tue Apr 9 09:05:39 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 9 Apr 2019 10:05:39 +0100 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> <9d272e1d-7c49-017c-7313-57636b103003@redhat.com> <0d75c78f-c255-147f-ed80-af940ce7b509@redhat.com> <1bfa62d2-fa96-da46-63c0-7e4cf4cf40fd@redhat.com> Message-ID: <183620f8-831f-8754-d3db-b7c3c1328b21@redhat.com> On 09/04/2019 09:42, Claes Redestad wrote: > Hi Andrew, > > On 2019-04-09 10:20, Andrew Dinn wrote: >> If the patch is to go in -- and I concede there is an acceptable >> argument for that -- then it >> needs commenting to help avoid this happening. > > open.02 already adds what I believed to be sufficient commenting, have > you taken this into consideration? public int hashCode() { + // The hash or hashIsZero fields are subject to a benign data race, + // making it crucial to ensure that any observable result of the + // calculation in this method stays correct under any possible read of + // these fields. One necessary restriction to allow this to be correct + // without explicit memory fences or similar concurrency primitives is + // that we can ever only write to one of these two fields for a given + // String instance. int h = hash; It would probably also be good if you extended the comment to document the status quo i.e. as Peter noted that the assigned values are computed deterministically from immutable state. Perhaps this: public int hashCode() { + // The hash or hashIsZero fields are subject to a benign data race, + // making it crucial to ensure that any observable result of the + // calculation in this method stays correct under any possible read of + // these fields. One necessary restriction to allow this to be correct + // without explicit memory fences or similar concurrency primitives is + // that we can ever only write to one of these two fields for a given + // String instance. Clearly the assigned values must also be computed + // deterministically from immutable state. int h = hash; regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From adinn at redhat.com Tue Apr 9 09:09:08 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 9 Apr 2019 10:09:08 +0100 Subject: RFR: 8222107 (CSR) Support implementation-defined Map Modes Message-ID: Could I please get a review for the following CSR. It relates to the change proposed in JDK-8221397 which enables FileChannel implementation-specific extensions to enum MapMode. https://bugs.openjdk.java.net/browse/JDK-8222107 Thanks. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From shade at redhat.com Tue Apr 9 09:14:13 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Tue, 9 Apr 2019 11:14:13 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <803a506d-c427-c8c0-5c56-730de7edd919@gmail.com> References: <3453bd0a-37e6-957e-f1ea-f86fe7a9ff17@gmail.com> <06bf9a51-7ed2-9b01-994c-f08832e3cf46@oracle.com> <0A870E14-A24E-4C67-9D93-BC6A9FE4EB50@oracle.com> <5392bd57-d2b1-0cc5-fbd0-7c1993c31729@redhat.com> <803a506d-c427-c8c0-5c56-730de7edd919@gmail.com> Message-ID: <411e41fe-cea3-9ef2-78de-99d4f46cdfa4@redhat.com> On 4/9/19 10:53 AM, Peter Levart wrote: > On 4/9/19 10:11 AM, Aleksey Shipilev wrote: >>> 2. No risk of hashcode recomputation for the 2^-32 case. >>> This might seem laughable, until you remember that it's exactly >>> those cases that DOS attackers like to create. >> Alt-hashing covers this obscure case in the course of mitigating much easier and much broader attack >> on String hashcode. We don't get to wave in every single hack into class libraries under "security" >> justification, especially when the mitigation already exists. > > Which alt-hashing are you talking about? The one which was removed from Java code of String in > transition from JDK 7 -> JDK 8 ? > > AFAIK, there's no alt-caching for pure java code for Strings any more (there's something for > internal JVM use). It was dropped when (Concurrent)HashMap got tree-ification. Oh snap, I misremember things. Okay, so treefication mitigates the attack on colliding hashcodes by going the String.compare route, and thus resolving the O(n^2) algorithmic attack. I still don't see zero hashcode presents a similar same attack surface: computing the hashcode for the incoming string would take the same time, regardless of what hashcode value it produces. Although I can see the defense-in-depth argument more clearly now, I am still on the fence it warrants a fix. -Aleksey From claes.redestad at oracle.com Tue Apr 9 09:28:42 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 9 Apr 2019 11:28:42 +0200 Subject: RFR: 8222144: Lazily create JRT code source URLs for LoadedModules In-Reply-To: References: Message-ID: <4853e2cb-9559-2cfd-98a4-fd76fecbfd08@oracle.com> Hi Alan, On 2019-04-09 08:42, Alan Bateman wrote: > On 08/04/2019 22:42, Claes Redestad wrote: >> Hi, >> >> currently we eagerly convert code source URIs to URLs to avoid recursive >> bootstrap issues with overrideable URL handlers. The JRT scheme handler >> is not overrideable, however, and also commonly used for all system >> modules. Creating these URLs lazily is a reasonable startup >> optimization since most applications will only ever load from a small >> fraction of the resolved system modules. >> >> Bug:??? https://bugs.openjdk.java.net/browse/JDK-8222144 >> Webrev: http://cr.openjdk.java.net/~redestad/8222144/open.00/ > This looks good, a minor nit is that L127 can be if (uri != null && > "jrt".equals(...)). Thanks! And done. > We could extend it to "file" too because that scheme > can't be overridden either. We agreed offline that this is not worthwhile: in the context of loaded modules, "file" is used only for exploded modules, where loading will trigger file system scanning etc, drowning out any micro-optimizations like this. So it wouldn't help much in those cases, and adds minute overhead to the common case where most/all modules are "jrt" Thanks! /Claes > > At some point we need to clean up the "may be null" comment as all > modules in the boot layer have a location. Also the set of schemes is > limited to jrt, file and jar so we are guaranteed to have a protocol > handler (if MalformedURLException or IAE is thrown then something is > broken elsewhere). > > -Alan From sgehwolf at redhat.com Tue Apr 9 09:33:31 2019 From: sgehwolf at redhat.com (Severin Gehwolf) Date: Tue, 09 Apr 2019 11:33:31 +0200 Subject: [PING?] RFR: 8217338: [Containers] Improve systemd slice memory limit support In-Reply-To: <254f53446176175689373b346c11aabc26d9b4b0.camel@redhat.com> References: <4a1ae4e0e3efd68818bfe868349972aa878de60b.camel@redhat.com> <9a911da4b2a4a8eff42c7c2f1a19c06f6521da8d.camel@redhat.com> <226CB44C-7B3A-42E8-8385-4E85168DBA4E@oracle.com> <254f53446176175689373b346c11aabc26d9b4b0.camel@redhat.com> Message-ID: Hi, Could I get another reviewer for this, please? Bob Vandette already reviewed it. Thank you! Cheers, Severin On Tue, 2019-04-02 at 13:48 +0200, Severin Gehwolf wrote: > Could I get a second review, please? > > Thanks, > Severin > > On Thu, 2019-03-28 at 11:37 -0400, Bob Vandette wrote: > > Sorry for the delay. The update looks good. > > > > Bob. > > > > > > > On Mar 25, 2019, at 1:30 PM, Severin Gehwolf wrote: > > > > > > On Fri, 2019-03-22 at 14:25 -0400, Bob Vandette wrote: > > > > Could you maybe combine subsystem_file_contents with subsystem_file_line_contents > > > > by adding an additional argument? > > > > > > Done: http://cr.openjdk.java.net/~sgehwolf/webrevs/JDK-8217338/05/webrev/ > > > > > > Thanks, > > > Severin > > > From christoph.langer at sap.com Tue Apr 9 09:55:58 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Tue, 9 Apr 2019 09:55:58 +0000 Subject: RFR (S): 8221979: Cleanups for building Windows resources Message-ID: Hi, during work on JDK-8221880 I spotted some opportunity for cleanup in Windows resource files and their handling in the build. The naming of variables used for customizing resource properties in the build system should be aligned between hotspot and JDK. This should be carefully reviewed by the build team (Erik). Maybe there are conflicts with some Oracle internal usage of variables... Furthermore some minor stuff: There are some indentation issues in the rc files. src/jdk.accessibility/windows/native/common/AccessBridgeStatusWindow.RC uses RC in capital letters as suffix, which is different to all other .rc files used. Bug: https://bugs.openjdk.java.net/browse/JDK-8221979 Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8221979.0/ Thanks Christoph From adinn at redhat.com Tue Apr 9 10:42:46 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 9 Apr 2019 11:42:46 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range Message-ID: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> Could I please get reviews for the following patch which overloads MappedByteBuffer.force to accept a start offset and length. JIRA: https://bugs.openjdk.java.net/browse/JDK-8221696 webrev: http://cr.openjdk.java.net/~adinn/8221696/webrev.00 This new API method was conceived as a preliminary change for JEP 352 to allow selective writeback of NVRAM-backed buffers. However, it has been implemented to provide a similar capability for file-mapped byte buffers. The old brute-force API method, force(), continues to operate as before for file-mapped byte buffers. One detail that is worth highlighting is that for file-backed buffers the start address passed to the native method force0 is rounded down to a page boundary. This is needed for Unix implementations to ensure that the underlying msync system call does not throw an exception. I am not sure whether Windows imposes this same restriction. If not then it might be better to perform the rounding in the native code. Advice would be welcome. Testing: I have only tested the new functionality on Linux. Assistance testing this on other OSes would be appreciated. [n.b. it should be enough to build with the patch and run $ make test TEST=test/jdk/java/nio/channels/FileChannel/MapTest.java" ] Updated MapTest.java: passes on Linux Submit Test: in progress regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From daniel.fuchs at oracle.com Tue Apr 9 11:28:06 2019 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Tue, 9 Apr 2019 12:28:06 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> Message-ID: <658eb7f1-e5e4-77f7-6795-65c59f99d8f3@oracle.com> Hi Andrew, On 09/04/2019 11:42, Andrew Dinn wrote: > One detail that is worth highlighting is that for file-backed buffers > the start address passed to the native method force0 is rounded down to > a page boundary. This is needed for Unix implementations to ensure that > the underlying msync system call does not throw an exception. Maybe this should be highlighted in the API documentation too, possibly as a non-normative implementation detail - stating that an implementation is free to do this (e.g. in an @implNote). My reading of your current proposed specification is that `from` is 234 * The offset to the first byte in the buffer region that 235 * is to be written back to storage and well - if I'm not mistaken then it appears the implementation can write some bytes before `from`, and that would be observable if you compared the file before and after calling force, isn't it? best regards, -- daniel > JIRA: https://bugs.openjdk.java.net/browse/JDK-8221696 > webrev: http://cr.openjdk.java.net/~adinn/8221696/webrev.00 From andy.herrick at oracle.com Tue Apr 9 11:45:17 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Tue, 9 Apr 2019 07:45:17 -0400 Subject: RFR: JDK-8221749: Error messages In-Reply-To: <2ba2aaa4-cf02-6da8-69bd-70e3ff011921@oracle.com> References: <6b91294f-445c-bf88-2a8c-c65f7add48a7@oracle.com> <0a4eff35-f3a8-5388-d740-850be5e9874c@oracle.com> <2ba2aaa4-cf02-6da8-69bd-70e3ff011921@oracle.com> Message-ID: <9763c0fa-3ab1-f162-8ab9-c9e35513b9ec@oracle.com> On 4/8/2019 6:05 PM, Andy Herrick wrote: > > On 4/8/2019 5:41 PM, Alexander Matveev wrote: >> Hi Andy, >> >> Looks good. >> >> Also, many messages (including added in this review) in >> MainResources.properties do have "." at the end and some don't. I >> think we should cleanup it and add "." if needed. > Yes - some messages are not full sentences, but most are.? Those that > are should end in a period. > I will address that in the next clean-up change. > /Andy Instead of addressing in the next cleanup change, I am revising this webrev (see webrev.02 at [1])? adding period to end of sentences and other simple cleanups. /Andy >> >> Thanks, >> Alexander >> >> On 4/8/2019 4:41 AM, Andy Herrick wrote: >>> Please review the jpackage fix for bug [1] at [2]. >>> >>> This is a fix for the JDK-8200758-branch branch of the open sandbox >>> repository (jpackage). >>> >>> [1] http://cr.openjdk.java.net/~herrick/8221749/ >>> >>> [2] https://bugs.openjdk.java.net/browse/JDK-8221749/ >>> >>> /Andy >> > From claes.redestad at oracle.com Tue Apr 9 12:21:05 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 9 Apr 2019 14:21:05 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <183620f8-831f-8754-d3db-b7c3c1328b21@redhat.com> References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> <9d272e1d-7c49-017c-7313-57636b103003@redhat.com> <0d75c78f-c255-147f-ed80-af940ce7b509@redhat.com> <1bfa62d2-fa96-da46-63c0-7e4cf4cf40fd@redhat.com> <183620f8-831f-8754-d3db-b7c3c1328b21@redhat.com> Message-ID: <9b67c12d-8109-e3f7-1d82-b6aecd2ffb39@oracle.com> On 2019-04-09 11:05, Andrew Dinn wrote: > It would probably also be good if you extended the comment to document > the status quo i.e. as Peter noted that the assigned values are computed > deterministically from immutable state. How about this: http://cr.openjdk.java.net/~redestad/8221836/open.03/ Thanks! /Claes From claes.redestad at oracle.com Tue Apr 9 12:32:01 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 9 Apr 2019 14:32:01 +0200 Subject: RFR: 8222029: Optimize Math.floorMod In-Reply-To: <5CABDAD2.9000609@oracle.com> References: <407d708a-ab81-bf8a-63fb-d3d769cfe1c3@redhat.com> <5d2c75de-474c-4376-3587-cfee6100f920@oracle.com> <5CABDAD2.9000609@oracle.com> Message-ID: I think those tests cover all interesting corner cases, so the only way I see it can be improved is to make it more exhaustive (say generate a large random sample of tests every run). Do you feel that is needed? /Claes On 2019-04-09 01:35, Joseph D. Darcy wrote: > Should any additional cases be added to > test/jdk/java/lang/Math/DivModTests.java to cover the new implementation? > > Thanks, > > -Joe > > On 4/5/2019 10:21 AM, Claes Redestad wrote: >> >> >> On 2019-04-05 17:41, Andrew Haley wrote: >>> On 4/5/19 2:44 PM, Claes Redestad wrote: >>>> Testing: tier1-2, all Math tests run locally, -prof perfasm >>>> verification >>>> on the provided microbenchmark. >>> >>> Looks good. >> >> Thanks! >> >>> >>> I've kicked the tyres on AArch64, and it looks like a useful >>> optimization. The >>> gains when the divisor is constant (a common case) are modest but >>> worthwhile. >>> >> >> Thanks for trying it out and glad to hear it helps on AArch64 as well. >> >> /Claes > From adinn at redhat.com Tue Apr 9 12:37:52 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 9 Apr 2019 13:37:52 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <658eb7f1-e5e4-77f7-6795-65c59f99d8f3@oracle.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <658eb7f1-e5e4-77f7-6795-65c59f99d8f3@oracle.com> Message-ID: <952b0d73-f123-bfd7-1e05-1e2eacf3ccfc@redhat.com> Hi Daniel, Thanks for looking at this. On 09/04/2019 12:28, Daniel Fuchs wrote: > Hi Andrew, > > On 09/04/2019 11:42, Andrew Dinn wrote: >> One detail that is worth highlighting is that for file-backed buffers >> the start address passed to the native method force0 is rounded down to >> a page boundary. This is needed for Unix implementations to ensure that >> the underlying msync system call does not throw an exception. > > Maybe this should be highlighted in the API documentation too, > possibly as a non-normative implementation detail - stating > that an implementation is free to do this (e.g. in an > @implNote). > > My reading of your current proposed specification is that > `from` is > ?234????? *??????? The offset to the first byte in the buffer region that > ?235????? *??????? is to be written back to storage > > and well - if I'm not mistaken then it appears the implementation > can write some bytes before `from`, and that would be observable > if you compared the file before and after calling force, isn't it? There is no implication in the current documentation that a call to force will /only/ write back bytes in the affected region. However, I agree that it should be stated explicitly that this may happen. I am not sure that this needs to be mentioned in an implNote. It is of the nature of most memory-mapped storage devices that writeback has a minimum granularity well above byte level. Would you be ok with a correspondingly general caveat? For example, what if I changed the second paragraph in the commment to: *

        If the file mapped into this buffer resides on a local * storage device then when this method returns it is guaranteed * that all changes made to the selected region of the buffer since * it was created, or since this method was last invoked, will have * been written to that device. The force operation is free to * write bytes that lie outside the specified region, for example * to ensure that data blocks of some device-specific granularity * are transferred in their entirety. * regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From Alan.Bateman at oracle.com Tue Apr 9 12:47:56 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 9 Apr 2019 13:47:56 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> <296e270c-0db1-1cdb-c4c3-147cbfd417ea@redhat.com> <1de0a2d6-ab0a-4e02-9216-75a2e545bc87@oracle.com> Message-ID: <298ca076-64be-0a6c-cd77-ced66e5468c0@oracle.com> On 08/04/2019 15:05, Andrew Dinn wrote: > : > Hmm, yes that's an interesting point. Of course, I'll take whatever > suggestions you are willing to throw this way :-) > What would you think about not promoting the constructor to public? The original motivation for that was to be able to create additional map modes in jdk.internal.misc.ExtendedMapMode but we can use shared secrets or other skullduggery to do that. The advantage is that we avoid creating expectation in the API that developers can create their own map modes. The rest of the solution doesn't change, it's just eliminating the ability to create modes beyond the standard and extended modes. -Alan From adinn at redhat.com Tue Apr 9 12:55:19 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 9 Apr 2019 13:55:19 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: <298ca076-64be-0a6c-cd77-ced66e5468c0@oracle.com> References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> <296e270c-0db1-1cdb-c4c3-147cbfd417ea@redhat.com> <1de0a2d6-ab0a-4e02-9216-75a2e545bc87@oracle.com> <298ca076-64be-0a6c-cd77-ced66e5468c0@oracle.com> Message-ID: <5c285408-e790-013e-4766-67aeac629fc0@redhat.com> On 09/04/2019 13:47, Alan Bateman wrote: > On 08/04/2019 15:05, Andrew Dinn wrote: >> : >> Hmm, yes that's an interesting point. Of course, I'll take whatever >> suggestions you are willing to throw this way :-) >> > What would you think about not promoting the constructor to public? The > original motivation for that was to be able to create additional map > modes in jdk.internal.misc.ExtendedMapMode but we can use shared secrets > or other skullduggery to do that. The advantage is that we avoid > creating expectation in the API that developers can create their own map > modes. The rest of the solution doesn't change, it's just eliminating > the ability to create modes beyond the standard and extended modes. I'm happy to skulldig if you provide the advice on how to do it (an Idiot's Guide to Trepanning?). It definitely sounds better to expose this in a controlled way rather than via a general API. Can I assume this will remove the need for a CSR? regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From aph at redhat.com Tue Apr 9 12:58:46 2019 From: aph at redhat.com (Andrew Haley) Date: Tue, 9 Apr 2019 13:58:46 +0100 Subject: RFR: [8u] 8205432: Replace the placeholder Japanese era name In-Reply-To: <1732312a-2e9b-59bb-6619-06500830e22d@redhat.com> References: <1732312a-2e9b-59bb-6619-06500830e22d@redhat.com> Message-ID: <48241cb3-f0ef-04a3-225a-1387803c79fb@redhat.com> On 4/9/19 4:26 AM, Andrew John Hughes wrote: > I've fixed this too, but note that this comes from the original patch in > 11 and up. So it actually needs fixing there too. > > Revised webrev: > https://cr.openjdk.java.net/~andrew/openjdk8/8205432/webrev.02/ OK. -- Andrew Haley Java Platform Lead Engineer Red Hat UK Ltd. EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671 From adinn at redhat.com Tue Apr 9 13:03:15 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 9 Apr 2019 14:03:15 +0100 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: <9b67c12d-8109-e3f7-1d82-b6aecd2ffb39@oracle.com> References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> <9d272e1d-7c49-017c-7313-57636b103003@redhat.com> <0d75c78f-c255-147f-ed80-af940ce7b509@redhat.com> <1bfa62d2-fa96-da46-63c0-7e4cf4cf40fd@redhat.com> <183620f8-831f-8754-d3db-b7c3c1328b21@redhat.com> <9b67c12d-8109-e3f7-1d82-b6aecd2ffb39@oracle.com> Message-ID: On 09/04/2019 13:21, Claes Redestad wrote: > On 2019-04-09 11:05, Andrew Dinn wrote: >> It would probably also be good if you extended the comment to document >> the status quo i.e. as Peter noted that the assigned values are computed >> deterministically from immutable state. > > How about this: > http://cr.openjdk.java.net/~redestad/8221836/open.03/ Yes, that looks fine. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From Alan.Bateman at oracle.com Tue Apr 9 13:03:10 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 9 Apr 2019 14:03:10 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: <5c285408-e790-013e-4766-67aeac629fc0@redhat.com> References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> <296e270c-0db1-1cdb-c4c3-147cbfd417ea@redhat.com> <1de0a2d6-ab0a-4e02-9216-75a2e545bc87@oracle.com> <298ca076-64be-0a6c-cd77-ced66e5468c0@oracle.com> <5c285408-e790-013e-4766-67aeac629fc0@redhat.com> Message-ID: On 09/04/2019 13:55, Andrew Dinn wrote: > : > I'm happy to skulldig if you provide the advice on how to do it (an > Idiot's Guide to Trepanning?). It definitely sounds better to expose > this in a controlled way rather than via a general API. > > Can I assume this will remove the need for a CSR? > The CSR is still needed because of the change to the FileChannel.map API (that part is easy of course). -Alan From erik.joelsson at oracle.com Tue Apr 9 13:22:00 2019 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Tue, 9 Apr 2019 06:22:00 -0700 Subject: RFR (S): 8221979: Cleanups for building Windows resources In-Reply-To: References: Message-ID: Hello, Looks ok to me. I assume you have inspected all affected files and made sure all attributes are the same pre and post this change? /Erik On 2019-04-09 02:55, Langer, Christoph wrote: > Hi, > > during work on JDK-8221880 I spotted some opportunity for cleanup in Windows resource files and their handling in the build. > > The naming of variables used for customizing resource properties in the build system should be aligned between hotspot and JDK. This should be carefully reviewed by the build team (Erik). Maybe there are conflicts with some Oracle internal usage of variables... > > Furthermore some minor stuff: > There are some indentation issues in the rc files. > src/jdk.accessibility/windows/native/common/AccessBridgeStatusWindow.RC uses RC in capital letters as suffix, which is different to all other .rc files used. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8221979 > Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8221979.0/ > > Thanks > Christoph > From daniel.fuchs at oracle.com Tue Apr 9 15:04:19 2019 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Tue, 9 Apr 2019 16:04:19 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <952b0d73-f123-bfd7-1e05-1e2eacf3ccfc@redhat.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <658eb7f1-e5e4-77f7-6795-65c59f99d8f3@oracle.com> <952b0d73-f123-bfd7-1e05-1e2eacf3ccfc@redhat.com> Message-ID: Hi Andrew, On 09/04/2019 13:37, Andrew Dinn wrote: > I am not sure that this needs to be mentioned in an implNote. It is of > the nature of most memory-mapped storage devices that writeback has a > minimum granularity well above byte level. Would you be ok with a > correspondingly general caveat? > > For example, what if I changed the second paragraph in the commment to: > > *

        If the file mapped into this buffer resides on a local > * storage device then when this method returns it is guaranteed > * that all changes made to the selected region of the buffer since > * it was created, or since this method was last invoked, will have > * been written to that device. The force operation is free to > * write bytes that lie outside the specified region, for example > * to ensure that data blocks of some device-specific granularity > * are transferred in their entirety. > * > That reads fine, thanks! BTW: I haven't really looked at the implementation, I'm leaving that to the experts of the field :-) best regards, -- daniel From adinn at redhat.com Tue Apr 9 15:11:09 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 9 Apr 2019 16:11:09 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <658eb7f1-e5e4-77f7-6795-65c59f99d8f3@oracle.com> <952b0d73-f123-bfd7-1e05-1e2eacf3ccfc@redhat.com> Message-ID: <45c3d862-8b2f-fa56-05e7-206bc3f4f43c@redhat.com> On 09/04/2019 16:04, Daniel Fuchs wrote: > . . . > That reads fine, thanks! Good. Thanks for reviewing this. > BTW: I haven't really looked at the implementation, I'm leaving that to > the experts of the field :-) No problem. I await their expert judgement. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From hohensee at amazon.com Tue Apr 9 15:53:29 2019 From: hohensee at amazon.com (Hohensee, Paul) Date: Tue, 9 Apr 2019 15:53:29 +0000 Subject: [8u] 8205432: Replace the placeholder Japanese era name Message-ID: <12F0D3AE-3F14-492E-8CD1-1611D70262D2@amazon.com> +1. Paul ?On 4/8/19, 8:28 PM, "core-libs-dev on behalf of Andrew John Hughes" wrote: On 08/04/2019 09:25, Deepak Kejriwal wrote: > Hi Andrew, > > Thanks for working on this. Please find below few minor comments:- > > 1>. For "src/share/classes/java/util/JapaneseImperialCalendar.java" and "src/share/classes/sun/util/calendar/Era.java" please changes the date time format to be consistent with existing defined eras:- > * 4 Heisei 1989-01-08 midnight local time > - * 5 NewEra 2019-05-01 midnight local time > + * 5 Reiwa 2019-05-01T00:00:00 local time > > Please change "2019-05-01T00:00:00 local time" to "2019-05-01 midnight local time" > The change in style is a cleanup that is part of JDK-8048123 [0]. I think we're better bringing over those cleanups than making Reiwa use the bad format, so I've incorporated those parts of [1] into the revised webrev. > 2>. For "test/java/time/test/java/time/chrono/TestJapaneseChronology.java" please align "JapaneseEra.of(3)" with existing defined eras in "Object[][] eraNameData()". > I've fixed this too, but note that this comes from the original patch in 11 and up. So it actually needs fixing there too. Revised webrev: https://cr.openjdk.java.net/~andrew/openjdk8/8205432/webrev.02/ > > Regards, > Deepak > [0] https://mail.openjdk.java.net/pipermail/i18n-dev/2014-July/001438.html [1] https://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/91ea77c474b9 -- Andrew :) Senior Free Java Software Engineer Red Hat, Inc. (http://www.redhat.com) PGP Key: ed25519/0xCFDA0F9B35964222 (hkp://keys.gnupg.net) Fingerprint = 5132 579D D154 0ED2 3E04 C5A0 CFDA 0F9B 3596 4222 https://keybase.io/gnu_andrew From adinn at redhat.com Tue Apr 9 16:02:02 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 9 Apr 2019 17:02:02 +0100 Subject: RFR: 8222107 (CSR) Support implementation-defined Map Modes In-Reply-To: References: Message-ID: <87c489e8-9ad2-e9ec-11d6-e4fb06190871@redhat.com> On 09/04/2019 10:09, Andrew Dinn wrote: > Could I please get a review for the following CSR. It relates to the > change proposed in JDK-8221397 which enables FileChannel > implementation-specific extensions to enum MapMode. > > https://bugs.openjdk.java.net/browse/JDK-8222107 I have updated this CSR to fully detail all the javadoc changes required in FileChannel.impl. Following Alan Bateman's latest review of the implementation patch there is no need to make the MapMode constructor public. So the only changes required for this CSR are to javadoc. Reviews would be welcome. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From adinn at redhat.com Tue Apr 9 16:02:17 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 9 Apr 2019 17:02:17 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: <298ca076-64be-0a6c-cd77-ced66e5468c0@oracle.com> References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> <296e270c-0db1-1cdb-c4c3-147cbfd417ea@redhat.com> <1de0a2d6-ab0a-4e02-9216-75a2e545bc87@oracle.com> <298ca076-64be-0a6c-cd77-ced66e5468c0@oracle.com> Message-ID: <27be3165-74f7-6d55-2d1e-57d5afd00c8d@redhat.com> In response to Alan's suggestion (included below) I have reverted the constructor for MapMode to private and will use behind the scenes access to construct the extended enum values. This change removes the need to modify the test in MapTest.java (no new API to exercise). It still requires javadoc changes in FileChannel.map and implementation changes in FileChannelImpl.java. Reveiews for the udpated webrev would be welcome. I'll post a separate request for review of the CSR changes. JIRA: https://bugs.openjdk.java.net/browse/JDK-8221397 new webrev: http://cr.openjdk.java.net/~adinn/8221397/webrev.03 Testing: Submit repo: in progress regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander On 09/04/2019 13:47, Alan Bateman wrote: > What would you think about not promoting the constructor to public? The > original motivation for that was to be able to create additional map > modes in jdk.internal.misc.ExtendedMapMode but we can use shared secrets > or other skullduggery to do that. The advantage is that we avoid > creating expectation in the API that developers can create their own map > modes. The rest of the solution doesn't change, it's just eliminating > the ability to create modes beyond the standard and extended modes. From joe.darcy at oracle.com Tue Apr 9 16:02:53 2019 From: joe.darcy at oracle.com (Joe Darcy) Date: Tue, 9 Apr 2019 09:02:53 -0700 Subject: RFR: 8222029: Optimize Math.floorMod In-Reply-To: References: <407d708a-ab81-bf8a-63fb-d3d769cfe1c3@redhat.com> <5d2c75de-474c-4376-3587-cfee6100f920@oracle.com> <5CABDAD2.9000609@oracle.com> Message-ID: <6931ef30-5c99-5d10-a208-c752f82172cd@oracle.com> Basically I'm inquiring about whether the existing tests provide at least as good code coverage on the new implementation as the old one. As it is a relatively simple method, perhaps it there is full coverage before and after. However, at times changing the implementation requires updates to the tests to includes different cases to check and I wanted to make sure that was looked at here. Thanks, -Joe On 4/9/2019 5:32 AM, Claes Redestad wrote: > I think those tests cover all interesting corner cases, so the only way > I see it can be improved is to make it more exhaustive (say generate a > large random sample of tests every run). Do you feel that is needed? > > /Claes > > On 2019-04-09 01:35, Joseph D. Darcy wrote: >> Should any additional cases be added to >> test/jdk/java/lang/Math/DivModTests.java to cover the new >> implementation? >> >> Thanks, >> >> -Joe >> >> On 4/5/2019 10:21 AM, Claes Redestad wrote: >>> >>> >>> On 2019-04-05 17:41, Andrew Haley wrote: >>>> On 4/5/19 2:44 PM, Claes Redestad wrote: >>>>> Testing: tier1-2, all Math tests run locally, -prof perfasm >>>>> verification >>>>> on the provided microbenchmark. >>>> >>>> Looks good. >>> >>> Thanks! >>> >>>> >>>> I've kicked the tyres on AArch64, and it looks like a useful >>>> optimization. The >>>> gains when the divisor is constant (a common case) are modest but >>>> worthwhile. >>>> >>> >>> Thanks for trying it out and glad to hear it helps on AArch64 as well. >>> >>> /Claes >> From andrew_m_leonard at uk.ibm.com Tue Apr 9 16:05:48 2019 From: andrew_m_leonard at uk.ibm.com (Andrew Leonard) Date: Tue, 9 Apr 2019 17:05:48 +0100 Subject: Request for sponsor: JDK-8221430: StringBuffer(CharSequence) constructor truncates when -XX:-CompactStrings specified In-Reply-To: <7665bb39-b15a-0e5d-ce1d-f843f5c385fa@oracle.com> References: <08ffa0f7-4cbd-c946-2250-ddcb8bed612f@oracle.com> <64ea5dc1-990f-f772-d970-1b0b24f3dc9b@oracle.com> <5160cae7-d4d7-3edd-5045-e09c0a52ad71@oracle <7665bb39-b15a-0e5d-ce1d-f843f5c385fa@oracle.com> Message-ID: Hi Ivan, Your micro benchmarks look good, that's something I need to learn how to execute. Do we think this is a good resolution now? Thanks Andrew Andrew Leonard Java Runtimes Development IBM Hursley IBM United Kingdom Ltd Phone internal: 245913, external: 01962 815913 internet email: andrew_m_leonard at uk.ibm.com From: Ivan Gerasimov To: Roger Riggs , Andrew Leonard Cc: core-libs-dev at openjdk.java.net Date: 06/04/2019 06:44 Subject: Re: Request for sponsor: JDK-8221430: StringBuffer(CharSequence) constructor truncates when -XX:-CompactStrings specified Hi Roger! On 4/1/19 8:06 AM, Roger Riggs wrote: > Hi Ivan, > > Thanks for running the micro benchmarks. > > This version has more code duplication than Andrew's original > proposal that calculated the coder only CharSequence and had > a single AbstractStringBuilder constructor for computing the size > and allocating the byte[]/ > > https://urldefense.proofpoint.com/v2/url?u=http-3A__cr.openjdk.java.net_-7Ealeonard_8221430_webrev.00_&d=DwID-g&c=jf_iaSHvJObTbx-siA1ZOg&r=NaV8Iy8Ld-vjpXZFDdTbgGlRTghGHnwM75wUPd5_NUQ&m=lU-ZYHX0l887TMjoIm22uyMKp50PG-LsAObnBAzW3ok&s=AGr15BRTPigyz4orFzK02RdhWl8vCSu18KYA0ydASrw&e= > > I'd be curious to know the JMH tests for that version compared. > That variant appeared to be slightly slower, comparing to the latest variant: Here are fresh benchmarks for both variants (1) cr.openjdk.java.net/~aleonard/8221430/webrev.00 : Benchmark Mode Cnt Score Error Units StringBuilders.fromLatin1String avgt 18 15.217 ? 0.157 ns/op StringBuilders.fromLatin1StringBuilder avgt 18 19.169 ? 0.086 ns/op StringBuilders.fromUtf16String avgt 18 17.593 ? 0.180 ns/op StringBuilders.fromUtf16StringBuilder avgt 18 21.786 ? 0.158 ns/op (2) cr.openjdk.java.net/~igerasim/8221430/02/webrev : Benchmark Mode Cnt Score Error Units StringBuilders.fromLatin1String avgt 18 14.655 ? 0.133 ns/op StringBuilders.fromLatin1StringBuilder avgt 18 18.059 ? 0.161 ns/op StringBuilders.fromUtf16String avgt 18 16.675 ? 0.124 ns/op StringBuilders.fromUtf16StringBuilder avgt 18 20.761 ? 0.116 ns/op One reason might be that (2) avoids a redundant check for negative length of the String argument. > Another comment is whether the 'instanceof' code is the > best performer for checking if the argument is a String. > I might think that 'seq.getClass().equals(String.class)' is faster. > Interesting. I don't see examples of such pattern in JDK. Anyhow, I think that the case when a StringBuilder is constructed from a String down-cast to CharSequence should be rare in practice, so it is sensible to keep the code more ideomatic, i.e. use instanceof. > And in this most recent webrev that has separated the > AbstractStringBuilder > constructors for String from CharSequence, is it more likely that the > argument > will be an AbstractStringBuilder than a String so that comparison > should be done first. > Yes, it's a good point! I reordered the branches in the latest webrev. With kind regards, Ivan Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From andy.herrick at oracle.com Tue Apr 9 16:33:00 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Tue, 9 Apr 2019 12:33:00 -0400 Subject: RFR: JDK-8221641: Follow up code clean up for JDK-8221582 Message-ID: <7ba9de28-eeb2-8fc2-878e-7a4f5c3b893b@oracle.com> Please review the jpackage fix for bug [1] at [2]. This is a fix for the JDK-8200758-branch branch of the open sandbox repository (jpackage). [1] https://bugs.openjdk.java.net/browse/JDK-8221641 [2] http://cr.openjdk.java.net/~herrick/8221641/ /Andy From Alan.Bateman at oracle.com Tue Apr 9 16:49:22 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 9 Apr 2019 17:49:22 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: <27be3165-74f7-6d55-2d1e-57d5afd00c8d@redhat.com> References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> <296e270c-0db1-1cdb-c4c3-147cbfd417ea@redhat.com> <1de0a2d6-ab0a-4e02-9216-75a2e545bc87@oracle.com> <298ca076-64be-0a6c-cd77-ced66e5468c0@oracle.com> <27be3165-74f7-6d55-2d1e-57d5afd00c8d@redhat.com> Message-ID: <2026d6f7-3133-c6b9-ea50-18984d624810@oracle.com> On 09/04/2019 17:02, Andrew Dinn wrote: > In response to Alan's suggestion (included below) I have reverted the > constructor for MapMode to private and will use behind the scenes access > to construct the extended enum values. > > This change removes the need to modify the test in MapTest.java (no new > API to exercise). > > It still requires javadoc changes in FileChannel.map and implementation > changes in FileChannelImpl.java. Reveiews for the udpated webrev would > be welcome. I'll post a separate request for review of the CSR changes. > > JIRA: https://bugs.openjdk.java.net/browse/JDK-8221397 > new webrev: http://cr.openjdk.java.net/~adinn/8221397/webrev.03 > I think this looks fine. I've added myself as Reviewer to the CSR too. -Alan From Roger.Riggs at oracle.com Tue Apr 9 17:02:35 2019 From: Roger.Riggs at oracle.com (Roger Riggs) Date: Tue, 9 Apr 2019 13:02:35 -0400 Subject: Request for sponsor: JDK-8221430: StringBuffer(CharSequence) constructor truncates when -XX:-CompactStrings specified In-Reply-To: <7665bb39-b15a-0e5d-ce1d-f843f5c385fa@oracle.com> References: <08ffa0f7-4cbd-c946-2250-ddcb8bed612f@oracle.com> <64ea5dc1-990f-f772-d970-1b0b24f3dc9b@oracle.com> <5160cae7-d4d7-3edd-5045-e09c0a52ad71@oracle <257e94c4-2429-89a0-50df-ed020c0093d2@oracle.com> <61d962e5-4e52-c401-25be-4eb1e848e422@oracle.com> <7665bb39-b15a-0e5d-ce1d-f843f5c385fa@oracle.com> Message-ID: Hi Ivan, The JMH number look fine.? thanks for comparing. > And in this most recent webrev that has separated the > AbstractStringBuilder > constructors for String from CharSequence, is it more likely that > the argument > will be an AbstractStringBuilder than a String so that comparison > should be done first. > Yes, it's a good point!? I reordered the branches in the latest webrev. I don't see the order changed in the webrev for AbstractStringBuilder. 131-133. ?? http://cr.openjdk.java.net/~igerasim/8221430/02/webrev/index.html Otherwise, looks fine. Thanks, Roger On 04/06/2019 01:43 AM, Ivan Gerasimov wrote: > Hi Roger! > > On 4/1/19 8:06 AM, Roger Riggs wrote: >> Hi Ivan, >> >> Thanks for running the micro benchmarks. >> >> This version has more code duplication than Andrew's original >> proposal that calculated the coder only CharSequence and had >> a single AbstractStringBuilder constructor for computing the size >> and allocating the byte[]/ >> >> http://cr.openjdk.java.net/~aleonard/8221430/webrev.00/ >> >> I'd be curious to know the JMH tests for that version compared. >> > That variant appeared to be slightly slower, comparing to the latest > variant: > > Here are fresh benchmarks for both variants > > (1) cr.openjdk.java.net/~aleonard/8221430/webrev.00 : > Benchmark?????????????????????????????? Mode? Cnt?? Score Error Units > StringBuilders.fromLatin1String???????? avgt?? 18? 15.217 ? 0.157 ns/op > StringBuilders.fromLatin1StringBuilder? avgt?? 18? 19.169 ? 0.086 ns/op > StringBuilders.fromUtf16String????????? avgt?? 18? 17.593 ? 0.180 ns/op > StringBuilders.fromUtf16StringBuilder?? avgt?? 18? 21.786 ? 0.158 ns/op > > (2) cr.openjdk.java.net/~igerasim/8221430/02/webrev : > Benchmark?????????????????????????????? Mode? Cnt?? Score Error Units > StringBuilders.fromLatin1String???????? avgt?? 18? 14.655 ? 0.133 ns/op > StringBuilders.fromLatin1StringBuilder? avgt?? 18? 18.059 ? 0.161 ns/op > StringBuilders.fromUtf16String????????? avgt?? 18? 16.675 ? 0.124 ns/op > StringBuilders.fromUtf16StringBuilder?? avgt?? 18? 20.761 ? 0.116 ns/op > > One reason might be that (2) avoids a redundant check for negative > length of the String argument. > >> Another comment is whether the 'instanceof' code is the >> best performer for checking if the argument is a String. >> I might think that 'seq.getClass().equals(String.class)' is faster. >> > Interesting.? I don't see examples of such pattern in JDK. > Anyhow, I think that the case when a StringBuilder is constructed from > a String down-cast to CharSequence should be rare in practice, so it > is sensible to keep the code more ideomatic, i.e. use instanceof. > >> And in this most recent webrev that has separated the >> AbstractStringBuilder >> constructors for String from CharSequence, is it more likely that the >> argument >> will be an AbstractStringBuilder than a String so that comparison >> should be done first. >> > Yes, it's a good point!? I reordered the branches in the latest webrev. > > With kind regards, > Ivan > From hohensee at amazon.com Tue Apr 9 17:18:20 2019 From: hohensee at amazon.com (Hohensee, Paul) Date: Tue, 9 Apr 2019 17:18:20 +0000 Subject: [8u] 8205432: Replace the placeholder Japanese era name In-Reply-To: <12F0D3AE-3F14-492E-8CD1-1611D70262D2@amazon.com> References: <12F0D3AE-3F14-492E-8CD1-1611D70262D2@amazon.com> Message-ID: <22BEE3A9-5368-4538-AC0C-4C90E9B42B3B@amazon.com> I meant the current webrev https://cr.openjdk.java.net/~andrew/openjdk8/8205432/webrev.02/ is fine. Just backport what's in tip and fix whatever's wrong later as another backport or backports. Paul ?On 4/9/19, 8:56 AM, "core-libs-dev on behalf of Hohensee, Paul" wrote: +1. Paul On 4/8/19, 8:28 PM, "core-libs-dev on behalf of Andrew John Hughes" wrote: On 08/04/2019 09:25, Deepak Kejriwal wrote: > Hi Andrew, > > Thanks for working on this. Please find below few minor comments:- > > 1>. For "src/share/classes/java/util/JapaneseImperialCalendar.java" and "src/share/classes/sun/util/calendar/Era.java" please changes the date time format to be consistent with existing defined eras:- > * 4 Heisei 1989-01-08 midnight local time > - * 5 NewEra 2019-05-01 midnight local time > + * 5 Reiwa 2019-05-01T00:00:00 local time > > Please change "2019-05-01T00:00:00 local time" to "2019-05-01 midnight local time" > The change in style is a cleanup that is part of JDK-8048123 [0]. I think we're better bringing over those cleanups than making Reiwa use the bad format, so I've incorporated those parts of [1] into the revised webrev. > 2>. For "test/java/time/test/java/time/chrono/TestJapaneseChronology.java" please align "JapaneseEra.of(3)" with existing defined eras in "Object[][] eraNameData()". > I've fixed this too, but note that this comes from the original patch in 11 and up. So it actually needs fixing there too. Revised webrev: https://cr.openjdk.java.net/~andrew/openjdk8/8205432/webrev.02/ > > Regards, > Deepak > [0] https://mail.openjdk.java.net/pipermail/i18n-dev/2014-July/001438.html [1] https://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/91ea77c474b9 -- Andrew :) Senior Free Java Software Engineer Red Hat, Inc. (http://www.redhat.com) PGP Key: ed25519/0xCFDA0F9B35964222 (hkp://keys.gnupg.net) Fingerprint = 5132 579D D154 0ED2 3E04 C5A0 CFDA 0F9B 3596 4222 https://keybase.io/gnu_andrew From gnu.andrew at redhat.com Tue Apr 9 17:26:36 2019 From: gnu.andrew at redhat.com (Andrew John Hughes) Date: Tue, 9 Apr 2019 18:26:36 +0100 Subject: [8u] 8205432: Replace the placeholder Japanese era name In-Reply-To: <22BEE3A9-5368-4538-AC0C-4C90E9B42B3B@amazon.com> References: <12F0D3AE-3F14-492E-8CD1-1611D70262D2@amazon.com> <22BEE3A9-5368-4538-AC0C-4C90E9B42B3B@amazon.com> Message-ID: On 09/04/2019 18:18, Hohensee, Paul wrote: > I meant the current webrev > > https://cr.openjdk.java.net/~andrew/openjdk8/8205432/webrev.02/ > > is fine. Just backport what's in tip and fix whatever's wrong later as another backport or backports. > > Paul Thanks. I've pushed based on the review of yourself & aph: https://hg.openjdk.java.net/jdk8u/jdk8u-dev/jdk/rev/ee55428fe158 I can't credit Deepak anyway, as he's not a reviewer, but his suggestions have been incorporated in this latest webrev. -- Andrew :) Senior Free Java Software Engineer Red Hat, Inc. (http://www.redhat.com) PGP Key: ed25519/0xCFDA0F9B35964222 (hkp://keys.gnupg.net) Fingerprint = 5132 579D D154 0ED2 3E04 C5A0 CFDA 0F9B 3596 4222 https://keybase.io/gnu_andrew From ivan.gerasimov at oracle.com Tue Apr 9 17:45:37 2019 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 9 Apr 2019 10:45:37 -0700 Subject: Request for sponsor: JDK-8221430: StringBuffer(CharSequence) constructor truncates when -XX:-CompactStrings specified In-Reply-To: References: <08ffa0f7-4cbd-c946-2250-ddcb8bed612f@oracle.com> <64ea5dc1-990f-f772-d970-1b0b24f3dc9b@oracle.com> <5160cae7-d4d7-3edd-5045-e09c0a52ad71@oracle <257e94c4-2429-89a0-50df-ed020c0093d2@oracle.com> <61d962e5-4e52-c401-25be-4eb1e848e422@oracle.com> <7665bb39-b15a-0e5d-ce1d-f843f5c385fa@oracle.com> Message-ID: Thanks Roger and Andrew! On 4/9/19 10:02 AM, Roger Riggs wrote: > Hi Ivan, > > The JMH number look fine. thanks for comparing. > >> And in this most recent webrev that has separated the >> AbstractStringBuilder >> constructors for String from CharSequence, is it more likely that >> the argument >> will be an AbstractStringBuilder than a String so that comparison >> should be done first. >> > Yes, it's a good point! I reordered the branches in the latest > webrev. > > I don't see the order changed in the webrev for AbstractStringBuilder. > 131-133. > http://cr.openjdk.java.net/~igerasim/8221430/02/webrev/index.html > Ah, yes, I only changed it in the local copy, but didn't update the webrev. With kind regards, Ivan > Otherwise, looks fine. > > Thanks, Roger > > > On 04/06/2019 01:43 AM, Ivan Gerasimov wrote: >> Hi Roger! >> >> On 4/1/19 8:06 AM, Roger Riggs wrote: >>> Hi Ivan, >>> >>> Thanks for running the micro benchmarks. >>> >>> This version has more code duplication than Andrew's original >>> proposal that calculated the coder only CharSequence and had >>> a single AbstractStringBuilder constructor for computing the size >>> and allocating the byte[]/ >>> >>> http://cr.openjdk.java.net/~aleonard/8221430/webrev.00/ >>> >>> I'd be curious to know the JMH tests for that version compared. >>> >> That variant appeared to be slightly slower, comparing to the latest >> variant: >> >> Here are fresh benchmarks for both variants >> >> (1) cr.openjdk.java.net/~aleonard/8221430/webrev.00 : >> Benchmark Mode Cnt Score Error Units >> StringBuilders.fromLatin1String avgt 18 15.217 ? 0.157 ns/op >> StringBuilders.fromLatin1StringBuilder avgt 18 19.169 ? 0.086 ns/op >> StringBuilders.fromUtf16String avgt 18 17.593 ? 0.180 ns/op >> StringBuilders.fromUtf16StringBuilder avgt 18 21.786 ? 0.158 ns/op >> >> (2) cr.openjdk.java.net/~igerasim/8221430/02/webrev : >> Benchmark Mode Cnt Score Error Units >> StringBuilders.fromLatin1String avgt 18 14.655 ? 0.133 ns/op >> StringBuilders.fromLatin1StringBuilder avgt 18 18.059 ? 0.161 ns/op >> StringBuilders.fromUtf16String avgt 18 16.675 ? 0.124 ns/op >> StringBuilders.fromUtf16StringBuilder avgt 18 20.761 ? 0.116 ns/op >> >> One reason might be that (2) avoids a redundant check for negative >> length of the String argument. >> >>> Another comment is whether the 'instanceof' code is the >>> best performer for checking if the argument is a String. >>> I might think that 'seq.getClass().equals(String.class)' is faster. >>> >> Interesting. I don't see examples of such pattern in JDK. >> Anyhow, I think that the case when a StringBuilder is constructed >> from a String down-cast to CharSequence should be rare in practice, >> so it is sensible to keep the code more ideomatic, i.e. use instanceof. >> >>> And in this most recent webrev that has separated the >>> AbstractStringBuilder >>> constructors for String from CharSequence, is it more likely that >>> the argument >>> will be an AbstractStringBuilder than a String so that comparison >>> should be done first. >>> >> Yes, it's a good point! I reordered the branches in the latest webrev. >> >> With kind regards, >> Ivan >> > -- With kind regards, Ivan Gerasimov From ivan.gerasimov at oracle.com Tue Apr 9 17:48:43 2019 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 9 Apr 2019 10:48:43 -0700 Subject: Request for sponsor: JDK-8221430: StringBuffer(CharSequence) constructor truncates when -XX:-CompactStrings specified In-Reply-To: References: <08ffa0f7-4cbd-c946-2250-ddcb8bed612f@oracle.com> <64ea5dc1-990f-f772-d970-1b0b24f3dc9b@oracle.com> <5160cae7-d4d7-3edd-5045-e09c0a52ad71@oracle <7665bb39-b15a-0e5d-ce1d-f843f5c385fa@oracle.com> Message-ID: <3c63c54c-ff51-b76f-eea0-fa55d681acbc@oracle.com> Hi Andrew! On 4/9/19 9:05 AM, Andrew Leonard wrote: > Hi Ivan, > Your micro benchmarks look good, that's something I need to learn how > to execute. Here's how I ran them from the command line: make test TEST="micro:java.lang.StringBuilders.from" MICRO="FORK=3;WARMUP_ITER=4;ITER=6;WARMUP_TIME=4;TIME=4" > > Do we think this is a good resolution now? Yes. I'll go ahead and push it shortly. With kind regards, Ivan > Thanks > Andrew > > Andrew Leonard > Java Runtimes Development > IBM Hursley > IBM United Kingdom Ltd > Phone internal: 245913, external: 01962 815913 > internet email: andrew_m_leonard at uk.ibm.com > > > > > From: Ivan Gerasimov > To: Roger Riggs , Andrew Leonard > > Cc: core-libs-dev at openjdk.java.net > Date: 06/04/2019 06:44 > Subject: Re: Request for sponsor: JDK-8221430: > StringBuffer(CharSequence) constructor truncates when > -XX:-CompactStrings specified > ------------------------------------------------------------------------ > > > > Hi Roger! > > On 4/1/19 8:06 AM, Roger Riggs wrote: > > Hi Ivan, > > > > Thanks for running the micro benchmarks. > > > > This version has more code duplication than Andrew's original > > proposal that calculated the coder only CharSequence and had > > a single AbstractStringBuilder constructor for computing the size > > and allocating the byte[]/ > > > > http://cr.openjdk.java.net/~aleonard/8221430/webrev.00/ > > > > > I'd be curious to know the JMH tests for that version compared. > > > That variant appeared to be slightly slower, comparing to the latest > variant: > > Here are fresh benchmarks for both variants > > (1) cr.openjdk.java.net/~aleonard/8221430/webrev.00 : > Benchmark Mode Cnt Score Error Units > StringBuilders.fromLatin1String avgt 18 15.217 ? 0.157 ns/op > StringBuilders.fromLatin1StringBuilder avgt 18 19.169 ? 0.086 ns/op > StringBuilders.fromUtf16String avgt 18 17.593 ? 0.180 ns/op > StringBuilders.fromUtf16StringBuilder avgt 18 21.786 ? 0.158 ns/op > > (2) cr.openjdk.java.net/~igerasim/8221430/02/webrev : > Benchmark Mode Cnt Score Error Units > StringBuilders.fromLatin1String avgt 18 14.655 ? 0.133 ns/op > StringBuilders.fromLatin1StringBuilder avgt 18 18.059 ? 0.161 ns/op > StringBuilders.fromUtf16String avgt 18 16.675 ? 0.124 ns/op > StringBuilders.fromUtf16StringBuilder avgt 18 20.761 ? 0.116 ns/op > > One reason might be that (2) avoids a redundant check for negative > length of the String argument. > > > Another comment is whether the 'instanceof' code is the > > best performer for checking if the argument is a String. > > I might think that 'seq.getClass().equals(String.class)' is faster. > > > Interesting. I don't see examples of such pattern in JDK. > Anyhow, I think that the case when a StringBuilder is constructed from a > String down-cast to CharSequence should be rare in practice, so it is > sensible to keep the code more ideomatic, i.e. use instanceof. > > > And in this most recent webrev that has separated the > > AbstractStringBuilder > > constructors for String from CharSequence, is it more likely that the > > argument > > will be an AbstractStringBuilder than a String so that comparison > > should be done first. > > > Yes, it's a good point! I reordered the branches in the latest webrev. > > With kind regards, > Ivan > > > > > > Unless stated otherwise above: > IBM United Kingdom Limited - Registered in England and Wales with > number 741598. > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU -- With kind regards, Ivan Gerasimov From Alan.Bateman at oracle.com Tue Apr 9 17:59:30 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 9 Apr 2019 18:59:30 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> Message-ID: <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> On 09/04/2019 11:42, Andrew Dinn wrote: > Could I please get reviews for the following patch which overloads > MappedByteBuffer.force to accept a start offset and length. > > JIRA: https://bugs.openjdk.java.net/browse/JDK-8221696 > webrev: http://cr.openjdk.java.net/~adinn/8221696/webrev.00 > > This new API method was conceived as a preliminary change for JEP 352 to > allow selective writeback of NVRAM-backed buffers. However, it has been > implemented to provide a similar capability for file-mapped byte > buffers. There are a couple of implementation details to discuss but I'll stick to the API/javadoc for now so that you can create the CSR. We discussed the method signature, parameter types, and the semantics in previous mails so I think they are all okay (meaning the first parameter is the index in the buffer of the first byte to write back and not an offset from the position). One nit is that the existing absolute methods name the parameter "index" and I think we should do the same here. In the first sentence it might be better to say "a region" rather "some region". You could expand this paragraph with a second sentence, something like "The region starts at the given {@code index} in this buffer and is {@code length} bytes". A suggestion for the description for the index and length parameters is copy the wording/style from the existing absolute methods, e.g. @param index The index of the first byte of the regsion; must be non-negative and less than limit() @param length The length of the region in bytes; must be non-negative and no larger than limit() - index @throws IndexOutOfBoundException If the preconditions on the index and length do not hold. -Alan From brian.burkhalter at oracle.com Tue Apr 9 18:15:02 2019 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Tue, 9 Apr 2019 11:15:02 -0700 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> Message-ID: <32C928B7-C744-425F-8F9B-A02CD3AFBCE1@oracle.com> > On Apr 9, 2019, at 10:59 AM, Alan Bateman wrote: > > There are a couple of implementation details to discuss I was wondering whether this topic has any synergy / overlap with this prior thread [1] the principal sticking point of which was IIRC forcing / loading a slice of a MBB. Brian http://mail.openjdk.java.net/pipermail/nio-dev/2019-February/005871.html From aph at redhat.com Tue Apr 9 18:30:09 2019 From: aph at redhat.com (Andrew Haley) Date: Tue, 9 Apr 2019 19:30:09 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> Message-ID: <81b955f9-b493-cc70-3bd1-c9b8c074739b@redhat.com> On 4/9/19 11:42 AM, Andrew Dinn wrote: > This new API method was conceived as a preliminary change for JEP 352 to > allow selective writeback of NVRAM-backed buffers. However, it has been > implemented to provide a similar capability for file-mapped byte > buffers. The old brute-force API method, force(), continues to operate > as before for file-mapped byte buffers. > > One detail that is worth highlighting is that for file-backed buffers > the start address passed to the native method force0 is rounded down to > a page boundary. This is needed for Unix implementations to ensure that > the underlying msync system call does not throw an exception. Is it actually necessary to use a system call to do this? I would have thought that NVRAM allowed a finer granularity than a whole page, too. -- Andrew Haley Java Platform Lead Engineer Red Hat UK Ltd. EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671 From claes.redestad at oracle.com Tue Apr 9 19:06:38 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 9 Apr 2019 21:06:38 +0200 Subject: RFR: 8222029: Optimize Math.floorMod In-Reply-To: <6931ef30-5c99-5d10-a208-c752f82172cd@oracle.com> References: <407d708a-ab81-bf8a-63fb-d3d769cfe1c3@redhat.com> <5d2c75de-474c-4376-3587-cfee6100f920@oracle.com> <5CABDAD2.9000609@oracle.com> <6931ef30-5c99-5d10-a208-c752f82172cd@oracle.com> Message-ID: <89da91ca-2cae-07a4-6474-937d9ee9a7eb@oracle.com> In my cursory analysis of the test the interesting corner cases are covered and I have no reason to believe we'd see spurious errors elsewhere. I ran an adhoc semi-exhaustive test comparing results of the new version with the old and got an all-pass. /Claes On 2019-04-09 18:02, Joe Darcy wrote: > Basically I'm inquiring about whether the existing tests provide at > least as good code coverage on the new implementation as the old one. As > it is a relatively simple method, perhaps it there is full coverage > before and after. However, at times changing the implementation requires > updates to the tests to includes different cases to check and I wanted > to make sure that was looked at here. > > Thanks, > > -Joe > > On 4/9/2019 5:32 AM, Claes Redestad wrote: >> I think those tests cover all interesting corner cases, so the only way >> I see it can be improved is to make it more exhaustive (say generate a >> large random sample of tests every run). Do you feel that is needed? >> >> /Claes >> >> On 2019-04-09 01:35, Joseph D. Darcy wrote: >>> Should any additional cases be added to >>> test/jdk/java/lang/Math/DivModTests.java to cover the new >>> implementation? >>> >>> Thanks, >>> >>> -Joe >>> >>> On 4/5/2019 10:21 AM, Claes Redestad wrote: >>>> >>>> >>>> On 2019-04-05 17:41, Andrew Haley wrote: >>>>> On 4/5/19 2:44 PM, Claes Redestad wrote: >>>>>> Testing: tier1-2, all Math tests run locally, -prof perfasm >>>>>> verification >>>>>> on the provided microbenchmark. >>>>> >>>>> Looks good. >>>> >>>> Thanks! >>>> >>>>> >>>>> I've kicked the tyres on AArch64, and it looks like a useful >>>>> optimization. The >>>>> gains when the divisor is constant (a common case) are modest but >>>>> worthwhile. >>>>> >>>> >>>> Thanks for trying it out and glad to hear it helps on AArch64 as well. >>>> >>>> /Claes >>> From alexander.matveev at oracle.com Tue Apr 9 19:22:24 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Tue, 9 Apr 2019 12:22:24 -0700 Subject: RFR: JDK-8221749: Error messages In-Reply-To: <9763c0fa-3ab1-f162-8ab9-c9e35513b9ec@oracle.com> References: <6b91294f-445c-bf88-2a8c-c65f7add48a7@oracle.com> <0a4eff35-f3a8-5388-d740-850be5e9874c@oracle.com> <2ba2aaa4-cf02-6da8-69bd-70e3ff011921@oracle.com> <9763c0fa-3ab1-f162-8ab9-c9e35513b9ec@oracle.com> Message-ID: <07e04127-1466-1fac-a7a4-9beb0f9fc6f0@oracle.com> Hi Andy, webrev.02 looks good. Thanks, Alexander On 4/9/2019 4:45 AM, Andy Herrick wrote: > > On 4/8/2019 6:05 PM, Andy Herrick wrote: >> >> On 4/8/2019 5:41 PM, Alexander Matveev wrote: >>> Hi Andy, >>> >>> Looks good. >>> >>> Also, many messages (including added in this review) in >>> MainResources.properties do have "." at the end and some don't. I >>> think we should cleanup it and add "." if needed. >> Yes - some messages are not full sentences, but most are.? Those that >> are should end in a period. >> I will address that in the next clean-up change. >> /Andy > > Instead of addressing in the next cleanup change, I am revising this > webrev (see webrev.02 at [1])? adding period to end of sentences and > other simple cleanups. > > /Andy >>> >>> Thanks, >>> Alexander >>> >>> On 4/8/2019 4:41 AM, Andy Herrick wrote: >>>> Please review the jpackage fix for bug [1] at [2]. >>>> >>>> This is a fix for the JDK-8200758-branch branch of the open sandbox >>>> repository (jpackage). >>>> >>>> [1] http://cr.openjdk.java.net/~herrick/8221749/ >>>> >>>> [2] https://bugs.openjdk.java.net/browse/JDK-8221749/ >>>> >>>> /Andy >>> >> > From alexander.matveev at oracle.com Tue Apr 9 19:41:38 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Tue, 9 Apr 2019 12:41:38 -0700 Subject: RFR: JDK-8221641: Follow up code clean up for JDK-8221582 In-Reply-To: <7ba9de28-eeb2-8fc2-878e-7a4f5c3b893b@oracle.com> References: <7ba9de28-eeb2-8fc2-878e-7a4f5c3b893b@oracle.com> Message-ID: Hi Andy, Looks good. Thanks, Alexander On 4/9/2019 9:33 AM, Andy Herrick wrote: > Please review the jpackage fix for bug [1] at [2]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > [1] https://bugs.openjdk.java.net/browse/JDK-8221641 > > [2] http://cr.openjdk.java.net/~herrick/8221641/ > > /Andy > From adinn at redhat.com Wed Apr 10 08:34:10 2019 From: adinn at redhat.com (Andrew Dinn) Date: Wed, 10 Apr 2019 09:34:10 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: <2026d6f7-3133-c6b9-ea50-18984d624810@oracle.com> References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> <296e270c-0db1-1cdb-c4c3-147cbfd417ea@redhat.com> <1de0a2d6-ab0a-4e02-9216-75a2e545bc87@oracle.com> <298ca076-64be-0a6c-cd77-ced66e5468c0@oracle.com> <27be3165-74f7-6d55-2d1e-57d5afd00c8d@redhat.com> <2026d6f7-3133-c6b9-ea50-18984d624810@oracle.com> Message-ID: <98be0420-303e-3b4a-ed83-dc75996fa0a1@redhat.com> On 09/04/2019 17:49, Alan Bateman wrote: > On 09/04/2019 17:02, Andrew Dinn wrote: >> In response to Alan's suggestion (included below) I have reverted the >> constructor for MapMode to private and will use behind the scenes access >> to construct the extended enum values. >> >> This change removes the need to modify the test in MapTest.java (no new >> API to exercise). >> >> It still requires javadoc changes in FileChannel.map and implementation >> changes in FileChannelImpl.java. Reveiews for the udpated webrev would >> be welcome. I'll post a separate request for review of the CSR changes. >> >> JIRA:?????? https://bugs.openjdk.java.net/browse/JDK-8221397 >> new webrev: http://cr.openjdk.java.net/~adinn/8221397/webrev.03 >> > I think this looks fine. I've added myself as Reviewer to the CSR too. Thank you, Alan. Does that mean it is ok to push this now or do I need a second reviewer? regards, Andrew Dinn ----------- From adinn at redhat.com Wed Apr 10 08:41:27 2019 From: adinn at redhat.com (Andrew Dinn) Date: Wed, 10 Apr 2019 09:41:27 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <81b955f9-b493-cc70-3bd1-c9b8c074739b@redhat.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <81b955f9-b493-cc70-3bd1-c9b8c074739b@redhat.com> Message-ID: <2a484676-cd50-77b1-c659-3b82bc7d511c@redhat.com> On 09/04/2019 19:30, Andrew Haley wrote: > On 4/9/19 11:42 AM, Andrew Dinn wrote: >> This new API method was conceived as a preliminary change for JEP 352 to >> allow selective writeback of NVRAM-backed buffers. However, it has been >> implemented to provide a similar capability for file-mapped byte >> buffers. The old brute-force API method, force(), continues to operate >> as before for file-mapped byte buffers. >> >> One detail that is worth highlighting is that for file-backed buffers >> the start address passed to the native method force0 is rounded down to >> a page boundary. This is needed for Unix implementations to ensure that >> the underlying msync system call does not throw an exception. > > Is it actually necessary to use a system call to do this? I would have > thought that NVRAM allowed a finer granularity than a whole page, too. It is necessary to use a system call to write back a normal, file-backed buffer, whether that is for the whole buffer (original force() method) or some subset of it (new force(int,int) method). That case is all that the current patch is concerned with. When NVRAM support is added the force operation will, of course, employ a cache line writeback and will only do so for the lines that overlap the region (i.e. it will operate at cache-line granularity rather than file page granularity). The prototype implementation of NVRAM support posted in earlier discussions shows how to do that, including how to ensure that the writeback is done using an inlined machine instruction. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From adinn at redhat.com Wed Apr 10 09:23:28 2019 From: adinn at redhat.com (Andrew Dinn) Date: Wed, 10 Apr 2019 10:23:28 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <32C928B7-C744-425F-8F9B-A02CD3AFBCE1@oracle.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> <32C928B7-C744-425F-8F9B-A02CD3AFBCE1@oracle.com> Message-ID: <562790ea-018c-862c-b528-f853ea921420@redhat.com> On 09/04/2019 19:15, Brian Burkhalter wrote: > >> On Apr 9, 2019, at 10:59 AM, Alan Bateman > > wrote: >> >> There are a couple of implementation details to discuss > > I was wondering whether this topic has any synergy / overlap with this > prior thread [1] the principal sticking point of which was IIRC forcing > / loading a slice of a MBB. > > http://mail.openjdk.java.net/pipermail/nio-dev/2019-February/005871.html Oh, bonus points for that question ;-) Currently, for file-backed MBBs, forcing a slice of the MBB has no effect. That happens because the slice is not provided with an fd when it is cloned off the MBB. The same applies when creating a view over the byte buffer memory using some other type e.g. as an int buffer. I don't know exactly why that decision was made (avoiding profileration of fds?) but anyway it is a fait accompli and it means you can only force writes to a slice or view using the original MBB. When creating a slice (or view) over an NVRAM-backed buffer the situation is different. It would be perfectly possible for the slice/view to record that it's originating MBB is backed by NVRAM without needing to store the fd in the slice/view. It does store the base address of the originating MBB and its own offset/scaling. So, it could easily translate the force indices in its own coordinate system into a corresponding region of the original byte buffer and then write back the relevant cache lines in the original MBB byte address range. Much as the above capability would be useful it would mean that NVRAM-backed buffer slices/views had different semantics to file-backed backed buffer slices/views. The prototype implementation I provided earlier chose to follow the existing behaviour so as not to open up any such difference. I am interested to hear if anyone thinks the alternative choice is worth pursuing. It would certainly make life easier for users of NVRAM-backed buffers as it would enable them to use the new flush API to flush regions using slice/view coordinates rather than translated coordinates for the original byte buffer. However, providing this capability only for NVRAM-backed buffers leaves the solution somewhat half-baked. No doubt, existing users of file-backed MBB slices/views have already worked round the current limitation by retaining a handle on the original MBB and flushing it at suitable points using a full force() call. However, those existing implementations will not have had to deal with coordinate translation since the flush is indiscriminate. If they wish to move to using this new region-based flush then they will have to record and translate buffer coordinates. I would prefer this requirement to be fully present or fully removed rather than imposing it for one case but not the other. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From Alan.Bateman at oracle.com Wed Apr 10 09:44:10 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 10 Apr 2019 10:44:10 +0100 Subject: RFR: 8221397 Support implementation-defined Map Modes In-Reply-To: <98be0420-303e-3b4a-ed83-dc75996fa0a1@redhat.com> References: <96710df4-741a-99e0-1b5b-4e0dda538931@redhat.com> <5607e9c2-1f84-7ab5-42e9-4da1cb996dbe@redhat.com> <9946f451-db2d-5662-87ba-cbb527afc108@oracle.com> <296e270c-0db1-1cdb-c4c3-147cbfd417ea@redhat.com> <1de0a2d6-ab0a-4e02-9216-75a2e545bc87@oracle.com> <298ca076-64be-0a6c-cd77-ced66e5468c0@oracle.com> <27be3165-74f7-6d55-2d1e-57d5afd00c8d@redhat.com> <2026d6f7-3133-c6b9-ea50-18984d624810@oracle.com> <98be0420-303e-3b4a-ed83-dc75996fa0a1@redhat.com> Message-ID: On 10/04/2019 09:34, Andrew Dinn wrote: > : > Does that mean it is ok to push this now or do I need a second reviewer? > One Reviewer is fine but you need to finalize the CSR and wait for that to be approved before pushing. -Alan From Michael.Rasmussen at roguewave.com Wed Apr 10 09:48:29 2019 From: Michael.Rasmussen at roguewave.com (Michael Rasmussen) Date: Wed, 10 Apr 2019 09:48:29 +0000 Subject: String.join for Iterable, not just CharSequence Message-ID: Hi I was wonder if there had been any considerations adding an overloaded String.join method, that take an Iterable as argument, and a Function String join(CharSequence delimiter, Iterable elements, Function mappingFunction) { Objects.requireNonNull(delimiter); Objects.requireNonNull(elements); Objects.requireNonNull(mappingFunction); StringJoiner joiner = new StringJoiner(delimiter); for (T elem : elements) { joiner.add(mappingFunction.apply(elem)); } return joiner.toString(); } public static String join(CharSequence delimiter, Iterable elements) { return join(delimiter, elements, Function.identity()); } Kind regards Michael Rasmussen From claes.redestad at oracle.com Wed Apr 10 09:55:53 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Wed, 10 Apr 2019 11:55:53 +0200 Subject: RFR: 8221836: Avoid recalculating String.hash when zero In-Reply-To: References: <3f953f60-a3c4-0881-9aa4-1b1b31568a87@redhat.com> <924616cb-8c2f-3f9f-aae2-09b1d72927d6@oracle.com> <88548c52-3630-9c8b-c222-872ea5d1b58b@redhat.com> <7ee48121-d4a5-08d7-0f4a-ddf116764e0d@redhat.com> <098306c5-2c39-7e72-a2e5-1d7ad9b75f2b@gmail.com> <9d272e1d-7c49-017c-7313-57636b103003@redhat.com> <0d75c78f-c255-147f-ed80-af940ce7b509@redhat.com> <1bfa62d2-fa96-da46-63c0-7e4cf4cf40fd@redhat.com> <183620f8-831f-8754-d3db-b7c3c1328b21@redhat.com> <9b67c12d-8109-e3f7-1d82-b6aecd2ffb39@oracle.com> Message-ID: <249b958e-8fc2-1535-479c-180a44b27eb8@oracle.com> On 2019-04-09 15:03, Andrew Dinn wrote: >> How about this: >> http://cr.openjdk.java.net/~redestad/8221836/open.03/ > Yes, that looks fine. Thanks, Andrew. I'll push this shortly. /Claes From claes.redestad at oracle.com Wed Apr 10 10:27:42 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Wed, 10 Apr 2019 12:27:42 +0200 Subject: RFR: 8222029: Optimize Math.floorMod In-Reply-To: <89da91ca-2cae-07a4-6474-937d9ee9a7eb@oracle.com> References: <407d708a-ab81-bf8a-63fb-d3d769cfe1c3@redhat.com> <5d2c75de-474c-4376-3587-cfee6100f920@oracle.com> <5CABDAD2.9000609@oracle.com> <6931ef30-5c99-5d10-a208-c752f82172cd@oracle.com> <89da91ca-2cae-07a4-6474-937d9ee9a7eb@oracle.com> Message-ID: <2c5a5e82-3d48-c07d-c16e-fa861172747f@oracle.com> I found a few missing corner cases in the existing test (all permutations of [MIN|MAX]/[MIN|MAX]), so I added them and verified the test pass both with and without my patch: http://cr.openjdk.java.net/~redestad/8222029/open.01/ /Claes On 2019-04-09 21:06, Claes Redestad wrote: > In my cursory analysis of the test the interesting corner cases are > covered and I have no reason to believe we'd see spurious errors > elsewhere. I ran an adhoc semi-exhaustive test comparing results > of the new version with the old and got an all-pass. > > /Claes > > On 2019-04-09 18:02, Joe Darcy wrote: >> Basically I'm inquiring about whether the existing tests provide at >> least as good code coverage on the new implementation as the old one. >> As it is a relatively simple method, perhaps it there is full coverage >> before and after. However, at times changing the implementation >> requires updates to the tests to includes different cases to check and >> I wanted to make sure that was looked at here. >> >> Thanks, >> >> -Joe >> >> On 4/9/2019 5:32 AM, Claes Redestad wrote: >>> I think those tests cover all interesting corner cases, so the only way >>> I see it can be improved is to make it more exhaustive (say generate a >>> large random sample of tests every run). Do you feel that is needed? >>> >>> /Claes >>> >>> On 2019-04-09 01:35, Joseph D. Darcy wrote: >>>> Should any additional cases be added to >>>> test/jdk/java/lang/Math/DivModTests.java to cover the new >>>> implementation? >>>> >>>> Thanks, >>>> >>>> -Joe >>>> >>>> On 4/5/2019 10:21 AM, Claes Redestad wrote: >>>>> >>>>> >>>>> On 2019-04-05 17:41, Andrew Haley wrote: >>>>>> On 4/5/19 2:44 PM, Claes Redestad wrote: >>>>>>> Testing: tier1-2, all Math tests run locally, -prof perfasm >>>>>>> verification >>>>>>> on the provided microbenchmark. >>>>>> >>>>>> Looks good. >>>>> >>>>> Thanks! >>>>> >>>>>> >>>>>> I've kicked the tyres on AArch64, and it looks like a useful >>>>>> optimization. The >>>>>> gains when the divisor is constant (a common case) are modest but >>>>>> worthwhile. >>>>>> >>>>> >>>>> Thanks for trying it out and glad to hear it helps on AArch64 as well. >>>>> >>>>> /Claes >>>> From adinn at redhat.com Wed Apr 10 11:15:19 2019 From: adinn at redhat.com (Andrew Dinn) Date: Wed, 10 Apr 2019 12:15:19 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> Message-ID: On 09/04/2019 18:59, Alan Bateman wrote: > There are a couple of implementation details to discuss but I'll stick > to the API/javadoc for now so that you can create the CSR. Ok, thanks. > We discussed the method signature, parameter types, and the semantics in > previous mails so I think they are all okay (meaning the first parameter > is the index in the buffer of the first byte to write back and not an > offset from the position). One nit is that the existing absolute methods > name the parameter "index" and I think we should do the same here. Yes, that is clearer as well as consistent. > In the first sentence it might be better to say "a region" rather "some > region". You could expand this paragraph with a second sentence, > something like "The region starts at the given {@code index} in this > buffer and is {@code length} bytes". Ok. > A suggestion for the description for the index and length parameters is > copy the wording/style from the existing absolute methods, e.g. > > @param index The index of the first byte of the regsion; must be > non-negative and less than limit() > @param length The length of the region in bytes; must be non-negative > and no larger than limit() - index > @throws IndexOutOfBoundException If the preconditions on the index and > length do not hold. Ok. An updated webrev is available: JIRA: https://bugs.openjdk.java.net/browse/JDK-8221696 webrev: http://cr.openjdk.java.net/~adinn/8221696/webrev.01 I will also create a CSR based on the changes in this webrev and post an RFR. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From adinn at redhat.com Wed Apr 10 12:00:15 2019 From: adinn at redhat.com (Andrew Dinn) Date: Wed, 10 Apr 2019 13:00:15 +0100 Subject: RFR: CSR: JDK-8222261: MappedByteBuffer.force method to specify range Message-ID: Could I please get a review for the following CSR which accompanies JDK-8221696 JIRA: https://bugs.openjdk.java.net/browse/JDK-8222261 regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From christoph.langer at sap.com Wed Apr 10 12:21:00 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Wed, 10 Apr 2019 12:21:00 +0000 Subject: RFR (S): 8221979: Cleanups for building Windows resources In-Reply-To: References: Message-ID: Thanks, Erik. I already checked and will check carefully once again before pushing. /Christoph > -----Original Message----- > From: Erik Joelsson > Sent: Dienstag, 9. April 2019 15:22 > To: Langer, Christoph ; build- > dev at openjdk.java.net; hotspot-dev at openjdk.java.net; core-libs-dev > > Subject: Re: RFR (S): 8221979: Cleanups for building Windows resources > > Hello, > > Looks ok to me. > > I assume you have inspected all affected files and made sure all > attributes are the same pre and post this change? > > /Erik > > On 2019-04-09 02:55, Langer, Christoph wrote: > > Hi, > > > > during work on JDK-8221880 I spotted some opportunity for cleanup in > Windows resource files and their handling in the build. > > > > The naming of variables used for customizing resource properties in the > build system should be aligned between hotspot and JDK. This should be > carefully reviewed by the build team (Erik). Maybe there are conflicts with > some Oracle internal usage of variables... > > > > Furthermore some minor stuff: > > There are some indentation issues in the rc files. > > > src/jdk.accessibility/windows/native/common/AccessBridgeStatusWindow.R > C uses RC in capital letters as suffix, which is different to all other .rc files > used. > > > > Bug: https://bugs.openjdk.java.net/browse/JDK-8221979 > > Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8221979.0/ > > > > Thanks > > Christoph > > From hohensee at amazon.com Wed Apr 10 13:27:54 2019 From: hohensee at amazon.com (Hohensee, Paul) Date: Wed, 10 Apr 2019 13:27:54 +0000 Subject: [8u] 8205432: Replace the placeholder Japanese era name In-Reply-To: References: <12F0D3AE-3F14-492E-8CD1-1611D70262D2@amazon.com> <22BEE3A9-5368-4538-AC0C-4C90E9B42B3B@amazon.com> Message-ID: Thanks, Andrew. :) ?On 4/9/19, 10:27 AM, "Andrew John Hughes" wrote: On 09/04/2019 18:18, Hohensee, Paul wrote: > I meant the current webrev > > https://cr.openjdk.java.net/~andrew/openjdk8/8205432/webrev.02/ > > is fine. Just backport what's in tip and fix whatever's wrong later as another backport or backports. > > Paul Thanks. I've pushed based on the review of yourself & aph: https://hg.openjdk.java.net/jdk8u/jdk8u-dev/jdk/rev/ee55428fe158 I can't credit Deepak anyway, as he's not a reviewer, but his suggestions have been incorporated in this latest webrev. -- Andrew :) Senior Free Java Software Engineer Red Hat, Inc. (http://www.redhat.com) PGP Key: ed25519/0xCFDA0F9B35964222 (hkp://keys.gnupg.net) Fingerprint = 5132 579D D154 0ED2 3E04 C5A0 CFDA 0F9B 3596 4222 https://keybase.io/gnu_andrew From stuart.marks at oracle.com Thu Apr 11 01:22:52 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Wed, 10 Apr 2019 18:22:52 -0700 Subject: RFR(s): 8217405 rmic should reject class files with preview features enabled Message-ID: Hi all, Please review this small fix to rmic to make it reject class files that were compiled with preview features enabled. Bug: https://bugs.openjdk.java.net/browse/JDK-8217405 Webrev: http://cr.openjdk.java.net/~smarks/reviews/8217405/webrev.0/ Note that there is no regression test with this patch; I've added the noreg-hard label. The main reason is that to test this properly requires multiple different JDK versions to be available simultaneously, which isn't supported in out the test environment. One could work around this, e.g. by constructing class files with the desired version information, from but this hardly seems worth it for something like rmic. Thanks, s'marks From lance.andersen at oracle.com Thu Apr 11 02:00:39 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Wed, 10 Apr 2019 22:00:39 -0400 Subject: RFR(s): 8217405 rmic should reject class files with preview features enabled In-Reply-To: References: Message-ID: Looks OK Stuart :-) > On Apr 10, 2019, at 9:22 PM, Stuart Marks wrote: > > Hi all, > > Please review this small fix to rmic to make it reject class files that were compiled with preview features enabled. > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8217405 > > Webrev: > > http://cr.openjdk.java.net/~smarks/reviews/8217405/webrev.0/ > > Note that there is no regression test with this patch; I've added the noreg-hard label. The main reason is that to test this properly requires multiple different JDK versions to be available simultaneously, which isn't supported in out the test environment. One could work around this, e.g. by constructing class files with the desired version information, from but this hardly seems worth it for something like rmic. > > Thanks, > > s'marks 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 stuart.marks at oracle.com Thu Apr 11 02:02:38 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Wed, 10 Apr 2019 19:02:38 -0700 Subject: String.join for Iterable, not just CharSequence In-Reply-To: References: Message-ID: <871cdf97-69f0-5c7b-c4dd-a1a644d28f98@oracle.com> Hi Michael, This seems focused rather too narrowly on the task of joining strings obtained by applying exactly one mapper. It doesn't help if the task is something other than joining, and it doesn't help if there is something other than exactly one mapper. You'd then have to fall back to using a stream, which in fact isn't all that bad in the first place. Compare the code with your proposed enhancement, String.join(";", List.of(1.234, 2.345, 3.456), NumberFormat.getInstance()::format); to the stream version you suggested: Stream.of(1.234, 2.345, 3.456) .map(NumberFormat.getInstance()::format) .collect(joining(";")); (using static imports, and with line breaks for clarity). This isn't much of a difference. But also note, if my IterableOnce proposal (JDK-8148917) gets in (yes, I need to pick this back up), it would be possible to write: String.join(";", Stream.of(1.234, 2.345, 3.456) .map(NumberFormat.getInstance()::format)); The Path example is somewhat more cumbersome, because of the need to convert the Path (as an Iterable) to a Stream: StreamSupport.stream(path.spliterator(), false) .map(Object::toString) .collect(joining(";")); Now this isn't terrible, but it does seem more cumbersome than it ought to be. In particular having to create a Spliterator to convert an Iterable to a Stream is pretty non-obvious. It suggests to me that it would be better to work on making it easier to convert an Iterable to a Stream instead of adding a mapper to String.join(). However, we're probably not going to add a default method stream() to the Iterable interface at this point. It's just too high up in the hierarchy to be safe. See this Stack Overflow answer from Brian [1] and the Lambda EG discussion on the topic [2]. But with the benefit of several years of experience with this stuff, it might be feasible to create a smoother path with the judicious addition of factory methods. s'marks [1] https://stackoverflow.com/a/23177907/1441122 [2] http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/2013-June/001910.html On 4/10/19 2:48 AM, Michael Rasmussen wrote: > Hi > > I was wonder if there had been any considerations adding an overloaded String.join method, that take an Iterable as argument, and a Function This would allow you easily join an Iterable of items that are not Strings, but you could easily map to a String by calling toString or another method. > > Example usage: String.join(";", List.of(1.234, 2.345, 3.456), NumberFormat.getInstance()::format); > > I know the same thing is doable using a Stream, for instance the above like: Stream.of(1.234, 2.345, 3.456).map(NumberFormat.getInstance()::format).collect(Collectors.joining(";")); > The String.join version just seems more convenient and easier to read. Also, for non-collection Iterable object (i.e. that doesn't have a .stream() method), such as java.nio.file.Path, the Stream version becomes rather cumbersome. > for instance joining path elements with a different delimiter would be as easy as String.join(";", path, Object::toString); > > Implementation wise, the existing implementation only requires slight modification to apply the mapping function, and the existing method then just becomes a wrapper: > > public static String join(CharSequence delimiter, > Iterable elements, > Function mappingFunction) { > Objects.requireNonNull(delimiter); > Objects.requireNonNull(elements); > Objects.requireNonNull(mappingFunction); > StringJoiner joiner = new StringJoiner(delimiter); > for (T elem : elements) { > joiner.add(mappingFunction.apply(elem)); > } > return joiner.toString(); > } > > public static String join(CharSequence delimiter, > Iterable elements) { > return join(delimiter, elements, Function.identity()); > } > > Kind regards > Michael Rasmussen > From Michael.Rasmussen at roguewave.com Thu Apr 11 08:25:44 2019 From: Michael.Rasmussen at roguewave.com (Michael Rasmussen) Date: Thu, 11 Apr 2019 08:25:44 +0000 Subject: String.join for Iterable, not just CharSequence In-Reply-To: <871cdf97-69f0-5c7b-c4dd-a1a644d28f98@oracle.com> References: , <871cdf97-69f0-5c7b-c4dd-a1a644d28f98@oracle.com> Message-ID: Hi Stuart Thanks for the references to the discussion regarding .stream() on Iterable; I had been wondering that myself from time to time why they weren't there. It has always bothered my, that converting an Iterable to a Stream is a bit cumbersome, having to go through the spliterator and the StreamSupport. With the IterableOnce suggestion and Stream implementing it, I agree this would cover some of the scenarios, still the example with Path is cumbersome, as you also commented on. I don't know if with IterableOnce it would be a good time to revisit the .stream on Iterable question, or this is something that would fit better in/after Valhalla. IterableOnce does seem to answer some of the questions raised in the discussions you linked. Sure, there is still the Iterable to IntStream question, while it might be desirable, it will hopefully be moot come Valhalla (and there's always .mapToInt(i->i)). The reason for the question was basically, because it seemed like it would fit well with the existing String.join methods, doing the same thing - taking the entire Iterable/array and joining them, just applying a mapping function in between. But again, as you said, it might be too narrow, and we don't want to clutter classes with utility methods everywhere; the existing String.join methods are themselves simply convenience methods around StringJoiner. /Michael From Alan.Bateman at oracle.com Thu Apr 11 10:34:57 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 11 Apr 2019 11:34:57 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> Message-ID: On 10/04/2019 12:15, Andrew Dinn wrote: > : > An updated webrev is available: > > JIRA: https://bugs.openjdk.java.net/browse/JDK-8221696 > webrev: http://cr.openjdk.java.net/~adinn/8221696/webrev.01 > > The updated javadoc looks good. A minor nit is that it reads "and includes {@code length} bytes" when it should say "and is {@code length} bytes". There is also a stray quote at the end of the paragraph. I've added myself as Reviewer to the CSR so you can finalize it. -Alan From adinn at redhat.com Thu Apr 11 10:56:26 2019 From: adinn at redhat.com (Andrew Dinn) Date: Thu, 11 Apr 2019 11:56:26 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> Message-ID: <00ae2771-ba76-9ff1-5fbc-af487e0da3e7@redhat.com> On 11/04/2019 11:34, Alan Bateman wrote: > On 10/04/2019 12:15, Andrew Dinn wrote: >> : >> An updated webrev is available: >> >> JIRA:?? https://bugs.openjdk.java.net/browse/JDK-8221696 >> webrev: http://cr.openjdk.java.net/~adinn/8221696/webrev.01 >> >> > The updated javadoc looks good. A minor nit is that it reads "and > includes {@code length} bytes" when it should say "and is {@code length} > bytes". There is also a stray quote at the end of the paragraph. Ok, I have corrected that and will update the patch accordingly > I've added myself as Reviewer to the CSR so you can finalize it. Excellent, thank you. It has now been finalized. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From Alan.Bateman at oracle.com Thu Apr 11 12:36:14 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 11 Apr 2019 13:36:14 +0100 Subject: RFR(s): 8217405 rmic should reject class files with preview features enabled In-Reply-To: References: Message-ID: On 11/04/2019 02:22, Stuart Marks wrote: > Hi all, > > Please review this small fix to rmic to make it reject class files > that were compiled with preview features enabled. > > Bug: > > ????https://bugs.openjdk.java.net/browse/JDK-8217405 > > Webrev: > > ????http://cr.openjdk.java.net/~smarks/reviews/8217405/webrev.0/ > > Note that there is no regression test with this patch; I've added the > noreg-hard label. The main reason is that to test this properly > requires multiple different JDK versions to be available > simultaneously, which isn't supported in out the test environment. One > could work around this, e.g. by constructing class files with the > desired version information, from but this hardly seems worth it for > something like rmic. I think this looks okay. If you are putting any effort into rmic then I think it should be to work out a plan to remove it :-) -Alan From christoph.langer at sap.com Thu Apr 11 14:06:06 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Thu, 11 Apr 2019 14:06:06 +0000 Subject: RFR: 8222276: (zipfs) Refactoring and cleanups to prepare for JDK-8213031 Message-ID: Hi, working on JDK-8213031 to add posix file permission support for the zipfs, I thought it makes sense to factor out some of the changes into a separate change. Those changes reorganize and clean up some parts of the code which I think makes sense in any case. Please review: Bug: https://bugs.openjdk.java.net/browse/JDK-8222276 Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8222276.0/ In detail: The main change is to the hierarchy of inner classes ZipFileSystem.IndexNode and ZipFileSystem.Entry (the latter extends the former). Both classes are static classes currently. It makes sense, though, to have those associated with the ZipFileSystem they belong to. To do that, I need to add a static superclass named ZFSNode which only holds a node name and its hashcode. This class needs to exist because of the lookup implementation to find specific nodes of tze ZipFileSystem in its node map. Then the classes IndexNode extends ZFSNode and Entry extends IndexNode can be made non-static. Further changes are: Improve error handling for ZipFileAttributeView::get methods improve handling for zip64 attribute/version minor clenaups such as adding @Override annotations, whitespace fixes, private method visibility etc. Furthermore, there is some suspicious coding in JarFileSystem:: createVersionedLinks where a temporary key node is inserted into the alias map. However, this is a singleton instance which always gets new values. I'll open a separate bug for that and I'll try to create a test case which demonstrates an issue with the current code. I ran the zipfs jtreg tests successfully and will put it into our internal system as well as run it through jdk-submit. Thanks Christoph From claes.redestad at oracle.com Thu Apr 11 14:07:19 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 11 Apr 2019 16:07:19 +0200 Subject: RFR: 8215017: Improve String::equals warmup characteristics In-Reply-To: References: Message-ID: Hi, please review this improved version, which drops the new sameCoder() method and insteads inlines that test in the one place where its use is performance sensitive. Webrev: http://cr.openjdk.java.net/~redestad/8215017/jdk.01/ Microbenchmark show perfectly matching results, except an additional 8-20% improvement in interpreter results (which means a more noticeable improvement in startup/warmup tests): Benchmark Mode Cnt Score Error Units StringEquals.almostEqual avgt 5 740.164 ? 2.586 ns/op StringEquals.almostEqualUTF16 avgt 5 707.969 ? 2.796 ns/op StringEquals.different avgt 5 357.230 ? 9.751 ns/op StringEquals.differentCoders avgt 5 287.026 ? 2.112 ns/op StringEquals.equal avgt 5 762.012 ? 5.500 ns/op StringEquals.equalsUTF16 avgt 5 767.058 ? 4.619 ns/op Thanks! /Claes On 2018-12-08 01:11, Claes Redestad wrote: > Hi, > > following up from discussions during review of JDK-8214971[1], I > examined the startup and peak performance of a few different variant of > writing String::equals. > > Webrev: http://cr.openjdk.java.net/~redestad/8215017/jdk.00/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8215017 > > - folding coder() == aString.coder() into sameCoder(aString) helps > interpreter without adversely affecting higher optimization levels > > - Jim's proposal to use Arrays.equals is _interesting_: it improves > peak performance on some inputs but regress it on others. I'll defer > that to a future RFE as it needs a more thorough examination. > > - what we can do is simplify to only use StringLatin1.equals. If I'm not > completely mistaken these are all semantically neutral (and > StringUTF16.equals effectively redundant). If I'm completely wrong here > I'll welcome the learning opportunity. :-) > > This removes a branch and two method calls, and for UTF16 Strings we'll > use a simpler algorithm early, which turns out to be beneficial during > interpreter and C1 level. > > I added a simple microbenchmark to explore this, results show 1.2-2.5x > improvements in interpreter performance, while remaining perfectly > neutral results for optimized code on this simple micro[2]. > > This could be extended to clean up and move StringLatin1.equals back > into String and remove StringUTF16, but we'd also need to rearrange the > intrinsics on the VM side. Let me know what you think. > > Thanks! > > /Claes > > [1] > http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-December/057162.html > > > [2] > ========== Baseline ================= > > -Xint > Benchmark??????????????????????????? Mode? Cnt???? Score??? Error? Units > StringEquals.equalsAlmostEqual?????? avgt??? 4?? 968.640 ?? 1.337? ns/op > StringEquals.equalsAlmostEqualUTF16? avgt??? 4? 2082.007 ?? 5.303? ns/op > StringEquals.equalsDifferent???????? avgt??? 4?? 583.166 ? 29.461? ns/op > StringEquals.equalsDifferentCoders?? avgt??? 4?? 422.993 ?? 1.291? ns/op > StringEquals.equalsEqual???????????? avgt??? 4?? 988.671 ?? 1.492? ns/op > StringEquals.equalsEqualsUTF16?????? avgt??? 4? 2103.060 ?? 5.705? ns/op > > -XX:+CompactStrings > Benchmark??????????????????????????? Mode? Cnt?? Score?? Error? Units > StringEquals.equalsAlmostEqual?????? avgt??? 4? 23.896 ? 0.089? ns/op > StringEquals.equalsAlmostEqualUTF16? avgt??? 4? 23.935 ? 0.562? ns/op > StringEquals.equalsDifferent???????? avgt??? 4? 15.086 ? 0.044? ns/op > StringEquals.equalsDifferentCoders?? avgt??? 4? 12.572 ? 0.008? ns/op > StringEquals.equalsEqual???????????? avgt??? 4? 25.143 ? 0.025? ns/op > StringEquals.equalsEqualsUTF16?????? avgt??? 4? 25.148 ? 0.021? ns/op > > -XX:-CompactStrings > Benchmark??????????????????????????? Mode? Cnt?? Score?? Error? Units > StringEquals.equalsAlmostEqual?????? avgt??? 4? 24.539 ? 0.127? ns/op > StringEquals.equalsAlmostEqualUTF16? avgt??? 4? 22.638 ? 0.047? ns/op > StringEquals.equalsDifferent???????? avgt??? 4? 13.930 ? 0.835? ns/op > StringEquals.equalsDifferentCoders?? avgt??? 4? 13.836 ? 0.025? ns/op > StringEquals.equalsEqual???????????? avgt??? 4? 26.420 ? 0.020? ns/op > StringEquals.equalsEqualsUTF16?????? avgt??? 4? 23.889 ? 0.037? ns/op > > ========== Fix ====================== > > -Xint > Benchmark??????????????????????????? Mode? Cnt??? Score???? Error? Units > StringEquals.equalsAlmostEqual?????? avgt??? 4? 811.859 ??? 8.663? ns/op > StringEquals.equalsAlmostEqualUTF16? avgt??? 4? 802.784 ? 352.884? ns/op > StringEquals.equalsDifferent???????? avgt??? 4? 431.837 ??? 1.884? ns/op > StringEquals.equalsDifferentCoders?? avgt??? 4? 358.244 ??? 1.208? ns/op > StringEquals.equalsEqual???????????? avgt??? 4? 832.056 ??? 3.541? ns/op > StringEquals.equalsEqualsUTF16?????? avgt??? 4? 832.434 ??? 3.516? ns/op > > -XX:+CompactStrings > Benchmark??????????????????????????? Mode? Cnt?? Score?? Error? Units > StringEquals.equalsAlmostEqual?????? avgt??? 4? 23.906 ? 0.151? ns/op > StringEquals.equalsAlmostEqualUTF16? avgt??? 4? 23.905 ? 0.123? ns/op > StringEquals.equalsDifferent???????? avgt??? 4? 15.088 ? 0.023? ns/op > StringEquals.equalsDifferentCoders?? avgt??? 4? 12.575 ? 0.030? ns/op > StringEquals.equalsEqual???????????? avgt??? 4? 25.149 ? 0.059? ns/op > StringEquals.equalsEqualsUTF16?????? avgt??? 4? 25.149 ? 0.033? ns/op > > -XX:-CompactStrings > Benchmark??????????????????????????? Mode? Cnt?? Score?? Error? Units > StringEquals.equalsAlmostEqual?????? avgt??? 4? 24.521 ? 0.050? ns/op > StringEquals.equalsAlmostEqualUTF16? avgt??? 4? 22.639 ? 0.035? ns/op > StringEquals.equalsDifferent???????? avgt??? 4? 13.831 ? 0.020? ns/op > StringEquals.equalsDifferentCoders?? avgt??? 4? 13.884 ? 0.345? ns/op > StringEquals.equalsEqual???????????? avgt??? 4? 26.395 ? 0.066? ns/op > StringEquals.equalsEqualsUTF16?????? avgt??? 4? 23.904 ? 0.112? ns/op From martinrb at google.com Thu Apr 11 16:06:12 2019 From: martinrb at google.com (Martin Buchholz) Date: Thu, 11 Apr 2019 09:06:12 -0700 Subject: RFR: 8215017: Improve String::equals warmup characteristics In-Reply-To: References: Message-ID: I'm confused. This change seems to remove the one and only call to StringUTF16.equals, making that dead code? Looking more closely at StringUTF16.equals and StringLatin1.equals, both seem to boil down to equivalent """do the byte arrays contain the same bytes?"""? Which suggests we can coalesce these two methods and have String.equals simply check that the two coders and bytes are the same? Arrays.equals(byte[],byte[]) is also an intrinsic but has more checks. Hmmmm ... there's been performance work on ArraysSupport.mismatch. Maybe we're not using it for Strings because we expect Strings to be short? I don't know if hotspot these days needs to keep intrinsics around for library code that has been deleted. On Thu, Apr 11, 2019 at 7:09 AM Claes Redestad wrote: > Hi, > > please review this improved version, which drops the new sameCoder() > method and insteads inlines that test in the one place where > its use is performance sensitive. > > Webrev: http://cr.openjdk.java.net/~redestad/8215017/jdk.01/ > > Microbenchmark show perfectly matching results, except an additional > 8-20% improvement in interpreter results (which means a more > noticeable improvement in startup/warmup tests): > > Benchmark Mode Cnt Score Error Units > StringEquals.almostEqual avgt 5 740.164 ? 2.586 ns/op > StringEquals.almostEqualUTF16 avgt 5 707.969 ? 2.796 ns/op > StringEquals.different avgt 5 357.230 ? 9.751 ns/op > StringEquals.differentCoders avgt 5 287.026 ? 2.112 ns/op > StringEquals.equal avgt 5 762.012 ? 5.500 ns/op > StringEquals.equalsUTF16 avgt 5 767.058 ? 4.619 ns/op > > Thanks! > > /Claes > > On 2018-12-08 01:11, Claes Redestad wrote: > > Hi, > > > > following up from discussions during review of JDK-8214971[1], I > > examined the startup and peak performance of a few different variant of > > writing String::equals. > > > > Webrev: http://cr.openjdk.java.net/~redestad/8215017/jdk.00/ > > Bug: https://bugs.openjdk.java.net/browse/JDK-8215017 > > > > - folding coder() == aString.coder() into sameCoder(aString) helps > > interpreter without adversely affecting higher optimization levels > > > > - Jim's proposal to use Arrays.equals is _interesting_: it improves > > peak performance on some inputs but regress it on others. I'll defer > > that to a future RFE as it needs a more thorough examination. > > > > - what we can do is simplify to only use StringLatin1.equals. If I'm not > > completely mistaken these are all semantically neutral (and > > StringUTF16.equals effectively redundant). If I'm completely wrong here > > I'll welcome the learning opportunity. :-) > > > > This removes a branch and two method calls, and for UTF16 Strings we'll > > use a simpler algorithm early, which turns out to be beneficial during > > interpreter and C1 level. > > > > I added a simple microbenchmark to explore this, results show 1.2-2.5x > > improvements in interpreter performance, while remaining perfectly > > neutral results for optimized code on this simple micro[2]. > > > > This could be extended to clean up and move StringLatin1.equals back > > into String and remove StringUTF16, but we'd also need to rearrange the > > intrinsics on the VM side. Let me know what you think. > > > > Thanks! > > > > /Claes > > > > [1] > > > http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-December/057162.html > > > > > > [2] > > ========== Baseline ================= > > > > -Xint > > Benchmark Mode Cnt Score Error Units > > StringEquals.equalsAlmostEqual avgt 4 968.640 ? 1.337 ns/op > > StringEquals.equalsAlmostEqualUTF16 avgt 4 2082.007 ? 5.303 ns/op > > StringEquals.equalsDifferent avgt 4 583.166 ? 29.461 ns/op > > StringEquals.equalsDifferentCoders avgt 4 422.993 ? 1.291 ns/op > > StringEquals.equalsEqual avgt 4 988.671 ? 1.492 ns/op > > StringEquals.equalsEqualsUTF16 avgt 4 2103.060 ? 5.705 ns/op > > > > -XX:+CompactStrings > > Benchmark Mode Cnt Score Error Units > > StringEquals.equalsAlmostEqual avgt 4 23.896 ? 0.089 ns/op > > StringEquals.equalsAlmostEqualUTF16 avgt 4 23.935 ? 0.562 ns/op > > StringEquals.equalsDifferent avgt 4 15.086 ? 0.044 ns/op > > StringEquals.equalsDifferentCoders avgt 4 12.572 ? 0.008 ns/op > > StringEquals.equalsEqual avgt 4 25.143 ? 0.025 ns/op > > StringEquals.equalsEqualsUTF16 avgt 4 25.148 ? 0.021 ns/op > > > > -XX:-CompactStrings > > Benchmark Mode Cnt Score Error Units > > StringEquals.equalsAlmostEqual avgt 4 24.539 ? 0.127 ns/op > > StringEquals.equalsAlmostEqualUTF16 avgt 4 22.638 ? 0.047 ns/op > > StringEquals.equalsDifferent avgt 4 13.930 ? 0.835 ns/op > > StringEquals.equalsDifferentCoders avgt 4 13.836 ? 0.025 ns/op > > StringEquals.equalsEqual avgt 4 26.420 ? 0.020 ns/op > > StringEquals.equalsEqualsUTF16 avgt 4 23.889 ? 0.037 ns/op > > > > ========== Fix ====================== > > > > -Xint > > Benchmark Mode Cnt Score Error Units > > StringEquals.equalsAlmostEqual avgt 4 811.859 ? 8.663 ns/op > > StringEquals.equalsAlmostEqualUTF16 avgt 4 802.784 ? 352.884 ns/op > > StringEquals.equalsDifferent avgt 4 431.837 ? 1.884 ns/op > > StringEquals.equalsDifferentCoders avgt 4 358.244 ? 1.208 ns/op > > StringEquals.equalsEqual avgt 4 832.056 ? 3.541 ns/op > > StringEquals.equalsEqualsUTF16 avgt 4 832.434 ? 3.516 ns/op > > > > -XX:+CompactStrings > > Benchmark Mode Cnt Score Error Units > > StringEquals.equalsAlmostEqual avgt 4 23.906 ? 0.151 ns/op > > StringEquals.equalsAlmostEqualUTF16 avgt 4 23.905 ? 0.123 ns/op > > StringEquals.equalsDifferent avgt 4 15.088 ? 0.023 ns/op > > StringEquals.equalsDifferentCoders avgt 4 12.575 ? 0.030 ns/op > > StringEquals.equalsEqual avgt 4 25.149 ? 0.059 ns/op > > StringEquals.equalsEqualsUTF16 avgt 4 25.149 ? 0.033 ns/op > > > > -XX:-CompactStrings > > Benchmark Mode Cnt Score Error Units > > StringEquals.equalsAlmostEqual avgt 4 24.521 ? 0.050 ns/op > > StringEquals.equalsAlmostEqualUTF16 avgt 4 22.639 ? 0.035 ns/op > > StringEquals.equalsDifferent avgt 4 13.831 ? 0.020 ns/op > > StringEquals.equalsDifferentCoders avgt 4 13.884 ? 0.345 ns/op > > StringEquals.equalsEqual avgt 4 26.395 ? 0.066 ns/op > > StringEquals.equalsEqualsUTF16 avgt 4 23.904 ? 0.112 ns/op > From claes.redestad at oracle.com Thu Apr 11 16:19:43 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 11 Apr 2019 18:19:43 +0200 Subject: RFR: 8215017: Improve String::equals warmup characteristics In-Reply-To: References: Message-ID: <305b3754-d382-1862-a60a-d64d49005dee@oracle.com> On 2019-04-11 18:06, Martin Buchholz wrote: > I'm confused. > This change seems to remove the one and only call to StringUTF16.equals, > making that dead code? > Looking more closely at?StringUTF16.equals and StringLatin1.equals, both > seem to boil down to equivalent """do the byte arrays contain the same > bytes?"""? > Which suggests we can coalesce these two methods and have String.equals > simply check that the two coders and bytes are the same? > Arrays.equals(byte[],byte[]) is also an intrinsic but has more checks. > Hmmmm ... there's been performance work on ArraysSupport.mismatch. > Maybe we're not using it for Strings because we expect Strings to be short? > I don't know if hotspot these days needs to keep intrinsics around for > library code that has been deleted. Yes, this'd effectively kill off the need for StringUTF16.equals. I don't think we need to hold on to the intrinsic, but would prefer deferring that cleanup to a follow-up. I noted earlier that Arrays.equals would work, but has quite different peak and warmup behavior - some of it good, some of it bad (especially during startup/warmup). As this is a performance-sensitive area I'd prefer taking steps that are all-round improvements. /Claes From john.r.rose at oracle.com Thu Apr 11 16:22:03 2019 From: john.r.rose at oracle.com (John Rose) Date: Thu, 11 Apr 2019 09:22:03 -0700 Subject: RFR: 8215017: Improve String::equals warmup characteristics In-Reply-To: References: Message-ID: <68B48A75-AAAD-4022-9724-555B3464A27B@oracle.com> On Dec 7, 2018, at 4:11 PM, Claes Redestad wrote: > > - Jim's proposal to use Arrays.equals is _interesting_: it improves > peak performance on some inputs but regress it on others. I'll defer > that to a future RFE as it needs a more thorough examination. > > - what we can do is simplify to only use StringLatin1.equals. If I'm not > completely mistaken these are all semantically neutral (and > StringUTF16.equals effectively redundant). If I'm completely wrong here > I'll welcome the learning opportunity. :-) If they are semantically neutral then they belong in the same place as the neutral intrinsics, which is jdk.internal.util.ArraysSupport. This in turn calls the question of how the operation differs from the existing mismatch intrinsic. I'll go out on a limb here and say that the standard ArraysSupport.mismatch intrinsic can probably be tuned to cover string compares without hurting its other customers. Often such intrinsics are only engineered for throughput on long inputs. Later on we may find they can be additionally tuned for other workloads, by adjusting the setup logic, or (alternatively) they can be factored into multiple entry points for specific use cases, with complete sharing of assembly-level code except for differing setup logic for the different use cases. This sort of thing is the case with our arraycopy intrinsics (used by the JIT) and may well also be the case for array matching intrinsics. I agree the above questions can be answered in a separate investigation. ? John From stuart.marks at oracle.com Thu Apr 11 16:39:02 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 11 Apr 2019 09:39:02 -0700 Subject: RFR(s): 8217405 rmic should reject class files with preview features enabled In-Reply-To: References: Message-ID: <485a2328-de5b-d7ef-b37a-3592a9ff30c5@oracle.com> Thanks Lance. On 4/10/19 7:00 PM, Lance Andersen wrote: > Looks OK Stuart :-) >> On Apr 10, 2019, at 9:22 PM, Stuart Marks > > wrote: >> >> Hi all, >> >> Please review this small fix to rmic to make it reject class files that were >> compiled with preview features enabled. >> >> Bug: >> >> https://bugs.openjdk.java.net/browse/JDK-8217405 >> >> Webrev: >> >> http://cr.openjdk.java.net/~smarks/reviews/8217405/webrev.0/ >> >> Note that there is no regression test with this patch; I've added the >> noreg-hard label. The main reason is that to test this properly requires >> multiple different JDK versions to be available simultaneously, which isn't >> supported in out the test environment. One could work around this, e.g. by >> constructing class files with the desired version information, from but this >> hardly seems worth it for something like rmic. >> >> Thanks, >> >> s'marks > > > > 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 stuart.marks at oracle.com Thu Apr 11 16:39:57 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 11 Apr 2019 09:39:57 -0700 Subject: RFR(s): 8217405 rmic should reject class files with preview features enabled In-Reply-To: References: Message-ID: <8196454b-b82f-deff-dd67-18dfc4366b06@oracle.com> On 4/11/19 5:36 AM, Alan Bateman wrote: > I think this looks okay. If you are putting any effort into rmic then I think it > should be to work out a plan to remove it :-) Hold my beer. From vicente.romero at oracle.com Thu Apr 11 17:22:06 2019 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 11 Apr 2019 13:22:06 -0400 Subject: RFR: JDK-8222151: refactoring: enhancements to java.lang.Class::methodToString and java.lang.Class::getTypeName Message-ID: Please review the enhancements to java.lang.Class proposed by Sergei Tsypanov see discussion at [1]. The bug can be found at [2] and the fix at [3]. This enhancement is removing uses of StringBuilder in: ??? ::toGenericString ??? ::methodToString, and ??? ::getTypeName Thanks, Vicente [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-March/059110.html [2] https://bugs.openjdk.java.net/browse/JDK-8222151 [3] http://cr.openjdk.java.net/~vromero/8222151/webrev.00/ From joe.darcy at oracle.com Thu Apr 11 17:26:04 2019 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Thu, 11 Apr 2019 10:26:04 -0700 Subject: RFR: JDK-8222151: refactoring: enhancements to java.lang.Class::methodToString and java.lang.Class::getTypeName In-Reply-To: References: Message-ID: <5CAF78AC.80805@oracle.com> Hi Vicente, For methodToString, factoring out computing the common getName() + '.' + name prefix might be preferable, but otherwise the patch looks fine. Thanks, -Joe On 4/11/2019 10:22 AM, Vicente Romero wrote: > Please review the enhancements to java.lang.Class proposed by Sergei > Tsypanov see discussion at [1]. The bug can be found at [2] and the > fix at [3]. This enhancement is removing uses of StringBuilder in: > ::toGenericString > ::methodToString, and > ::getTypeName > > Thanks, > Vicente > > [1] > http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-March/059110.html > [2] https://bugs.openjdk.java.net/browse/JDK-8222151 > [3] http://cr.openjdk.java.net/~vromero/8222151/webrev.00/ From andy.herrick at oracle.com Thu Apr 11 19:05:23 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Thu, 11 Apr 2019 15:05:23 -0400 Subject: RFE: JDK-8217895: jpackage --identifier purpose Message-ID: <4c709612-5350-884a-6c80-9fd5a470f8b0@oracle.com> Please review the jpackage fix for bug [1] at [2]. This is a fix for the JDK-8200758-branch branch of the open sandbox repository (jpackage). [1] https://bugs.openjdk.java.net/browse/JDK-8217895 [2] http://cr.openjdk.java.net/~herrick/8217895/ /Andy From vicente.romero at oracle.com Thu Apr 11 20:30:36 2019 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 11 Apr 2019 16:30:36 -0400 Subject: RFR: JDK-8222151: refactoring: enhancements to java.lang.Class::methodToString and java.lang.Class::getTypeName In-Reply-To: <5CAF78AC.80805@oracle.com> References: <5CAF78AC.80805@oracle.com> Message-ID: Hi Joe, Thanks for the review please, I have modified the webrev [1] [1] http://cr.openjdk.java.net/~vromero/8222151/webrev.01/ On 4/11/19 1:26 PM, Joseph D. Darcy wrote: > Hi Vicente, > > For methodToString, factoring out computing the common > > ??? getName() + '.' + name > > prefix might be preferable, but otherwise the patch looks fine. > > Thanks, > > -Joe > > On 4/11/2019 10:22 AM, Vicente Romero wrote: >> Please review the enhancements to java.lang.Class proposed by Sergei >> Tsypanov see discussion at [1]. The bug can be found at [2] and the >> fix at [3]. This enhancement is removing uses of StringBuilder in: >> ??? ::toGenericString >> ??? ::methodToString, and >> ??? ::getTypeName >> >> Thanks, >> Vicente >> >> [1] >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-March/059110.html >> [2] https://bugs.openjdk.java.net/browse/JDK-8222151 >> [3] http://cr.openjdk.java.net/~vromero/8222151/webrev.00/ > From joe.darcy at oracle.com Thu Apr 11 20:48:43 2019 From: joe.darcy at oracle.com (Joe Darcy) Date: Thu, 11 Apr 2019 13:48:43 -0700 Subject: RFR: JDK-8222151: refactoring: enhancements to java.lang.Class::methodToString and java.lang.Class::getTypeName In-Reply-To: References: <5CAF78AC.80805@oracle.com> Message-ID: <26b8066c-81e7-84d4-2aea-5c00d79a0b3e@oracle.com> Hi Vicente, That version is better. If one doesn't mind the ?: operator, something like the following is possible: return getName() + '.' + name + (argTypes == null || argTypes.length == 0) ? "()": ? Arrays.stream(argTypes) ? .map(c -> c == null ? "null" : c.getName()) ? .collect(Collectors.joining(",", "(", ")")); HTH, -Joe On 4/11/2019 1:30 PM, Vicente Romero wrote: > Hi Joe, > > Thanks for the review please, I have modified the webrev [1] > > [1] http://cr.openjdk.java.net/~vromero/8222151/webrev.01/ > > On 4/11/19 1:26 PM, Joseph D. Darcy wrote: >> Hi Vicente, >> >> For methodToString, factoring out computing the common >> >> ??? getName() + '.' + name >> >> prefix might be preferable, but otherwise the patch looks fine. >> >> Thanks, >> >> -Joe >> >> On 4/11/2019 10:22 AM, Vicente Romero wrote: >>> Please review the enhancements to java.lang.Class proposed by Sergei >>> Tsypanov see discussion at [1]. The bug can be found at [2] and the >>> fix at [3]. This enhancement is removing uses of StringBuilder in: >>> ??? ::toGenericString >>> ??? ::methodToString, and >>> ??? ::getTypeName >>> >>> Thanks, >>> Vicente >>> >>> [1] >>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-March/059110.html >>> [2] https://bugs.openjdk.java.net/browse/JDK-8222151 >>> [3] http://cr.openjdk.java.net/~vromero/8222151/webrev.00/ >> > From alexander.matveev at oracle.com Thu Apr 11 21:37:41 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Thu, 11 Apr 2019 14:37:41 -0700 Subject: RFE: JDK-8217895: jpackage --identifier purpose In-Reply-To: <4c709612-5350-884a-6c80-9fd5a470f8b0@oracle.com> References: <4c709612-5350-884a-6c80-9fd5a470f8b0@oracle.com> Message-ID: <7fb78930-319b-7283-594c-143f1703e461@oracle.com> Hi Andy, Looks good. Thanks, Alexander On 4/11/2019 12:05 PM, Andy Herrick wrote: > Please review the jpackage fix for bug [1] at [2]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > [1] https://bugs.openjdk.java.net/browse/JDK-8217895 > > [2] http://cr.openjdk.java.net/~herrick/8217895/ > > /Andy > From semyon.sadetsky at oracle.com Thu Apr 11 22:06:36 2019 From: semyon.sadetsky at oracle.com (semyon.sadetsky at oracle.com) Date: Thu, 11 Apr 2019 15:06:36 -0700 Subject: RFE: JDK-8217895: jpackage --identifier purpose In-Reply-To: <4c709612-5350-884a-6c80-9fd5a470f8b0@oracle.com> References: <4c709612-5350-884a-6c80-9fd5a470f8b0@oracle.com> Message-ID: <6b759662-1d4a-99e7-e02e-ade3881491be@oracle.com> On 4/11/19 12:05 PM, Andy Herrick wrote: > Please review the jpackage fix for bug [1] at [2]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > [1] https://bugs.openjdk.java.net/browse/JDK-8217895 > > [2] http://cr.openjdk.java.net/~herrick/8217895/ Andy, Can I ask you to explain why your fix modifies so many files while the bug requests a change in help texts? Shouldn't it be a change in the property bundle? What are those other changes? --Semyon > > /Andy > From vicente.romero at oracle.com Thu Apr 11 22:07:41 2019 From: vicente.romero at oracle.com (Vicente Romero) Date: Thu, 11 Apr 2019 18:07:41 -0400 Subject: RFR: JDK-8222151: refactoring: enhancements to java.lang.Class::methodToString and java.lang.Class::getTypeName In-Reply-To: <26b8066c-81e7-84d4-2aea-5c00d79a0b3e@oracle.com> References: <5CAF78AC.80805@oracle.com> <26b8066c-81e7-84d4-2aea-5c00d79a0b3e@oracle.com> Message-ID: Hi Joe, Thanks for your suggestion, please see [1] Vicente [1] http://cr.openjdk.java.net/~vromero/8222151/webrev.02/ On 4/11/19 4:48 PM, Joe Darcy wrote: > > Hi Vicente, > > That version is better. If one doesn't mind the ?: operator, something > like the following is possible: > > return getName() + '.' + name + > (argTypes == null || argTypes.length == 0) ? > "()": > ? Arrays.stream(argTypes) > ? .map(c -> c == null ? "null" : c.getName()) > ? .collect(Collectors.joining(",", "(", ")")); > > HTH, > > -Joe > > On 4/11/2019 1:30 PM, Vicente Romero wrote: >> Hi Joe, >> >> Thanks for the review please, I have modified the webrev [1] >> >> [1] http://cr.openjdk.java.net/~vromero/8222151/webrev.01/ >> >> On 4/11/19 1:26 PM, Joseph D. Darcy wrote: >>> Hi Vicente, >>> >>> For methodToString, factoring out computing the common >>> >>> ??? getName() + '.' + name >>> >>> prefix might be preferable, but otherwise the patch looks fine. >>> >>> Thanks, >>> >>> -Joe >>> >>> On 4/11/2019 10:22 AM, Vicente Romero wrote: >>>> Please review the enhancements to java.lang.Class proposed by >>>> Sergei Tsypanov see discussion at [1]. The bug can be found at [2] >>>> and the fix at [3]. This enhancement is removing uses of >>>> StringBuilder in: >>>> ??? ::toGenericString >>>> ??? ::methodToString, and >>>> ??? ::getTypeName >>>> >>>> Thanks, >>>> Vicente >>>> >>>> [1] >>>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-March/059110.html >>>> [2] https://bugs.openjdk.java.net/browse/JDK-8222151 >>>> [3] http://cr.openjdk.java.net/~vromero/8222151/webrev.00/ >>> >> From joe.darcy at oracle.com Fri Apr 12 00:46:26 2019 From: joe.darcy at oracle.com (Joe Darcy) Date: Thu, 11 Apr 2019 17:46:26 -0700 Subject: RFR: JDK-8222151: refactoring: enhancements to java.lang.Class::methodToString and java.lang.Class::getTypeName In-Reply-To: References: <5CAF78AC.80805@oracle.com> <26b8066c-81e7-84d4-2aea-5c00d79a0b3e@oracle.com> Message-ID: <4a7c60e2-d09f-7bf8-0fca-8fe87f01bb8e@oracle.com> Hi Vicente, Looks good; thanks, -Joe On 4/11/2019 3:07 PM, Vicente Romero wrote: > Hi Joe, > > Thanks for your suggestion, please see [1] > > Vicente > > [1] http://cr.openjdk.java.net/~vromero/8222151/webrev.02/ > > On 4/11/19 4:48 PM, Joe Darcy wrote: >> >> Hi Vicente, >> >> That version is better. If one doesn't mind the ?: operator, >> something like the following is possible: >> >> return getName() + '.' + name + >> (argTypes == null || argTypes.length == 0) ? >> "()": >> ? Arrays.stream(argTypes) >> ? .map(c -> c == null ? "null" : c.getName()) >> ? .collect(Collectors.joining(",", "(", ")")); >> >> HTH, >> >> -Joe >> >> On 4/11/2019 1:30 PM, Vicente Romero wrote: >>> Hi Joe, >>> >>> Thanks for the review please, I have modified the webrev [1] >>> >>> [1] http://cr.openjdk.java.net/~vromero/8222151/webrev.01/ >>> >>> On 4/11/19 1:26 PM, Joseph D. Darcy wrote: >>>> Hi Vicente, >>>> >>>> For methodToString, factoring out computing the common >>>> >>>> ??? getName() + '.' + name >>>> >>>> prefix might be preferable, but otherwise the patch looks fine. >>>> >>>> Thanks, >>>> >>>> -Joe >>>> >>>> On 4/11/2019 10:22 AM, Vicente Romero wrote: >>>>> Please review the enhancements to java.lang.Class proposed by >>>>> Sergei Tsypanov see discussion at [1]. The bug can be found at [2] >>>>> and the fix at [3]. This enhancement is removing uses of >>>>> StringBuilder in: >>>>> ??? ::toGenericString >>>>> ??? ::methodToString, and >>>>> ??? ::getTypeName >>>>> >>>>> Thanks, >>>>> Vicente >>>>> >>>>> [1] >>>>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2019-March/059110.html >>>>> [2] https://bugs.openjdk.java.net/browse/JDK-8222151 >>>>> [3] http://cr.openjdk.java.net/~vromero/8222151/webrev.00/ >>>> >>> > From patrick at os.amperecomputing.com Fri Apr 12 07:51:09 2019 From: patrick at os.amperecomputing.com (Patrick Zhang OS) Date: Fri, 12 Apr 2019 07:51:09 +0000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: References: Message-ID: Moved this to core-libs-dev for review, thanks. Dropped and bcc'ed jdk-dev and jdk-updates-dev. Regards Patrick -----Original Message----- From: David Holmes Sent: Friday, April 12, 2019 3:43 PM To: Patrick Zhang OS ; jdk-dev at openjdk.java.net Cc: jdk-updates-dev at openjdk.java.net Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError Hi Patrick, Please takes this to core-libs-dev for review. Thanks, David On 12/04/2019 5:24 pm, Patrick Zhang OS wrote: > Hi, > > Please review this patch. > > The problem is that the launcher does a check on the input -Xss and > ensure it >=64K for the initial thread, while vm has another function > to determine whether the input stack size is big enough to future > threads, such as cgc_thread, vm_thread, java_thead etc. However if > -Xss0, the initial thread is created with stack size 64K, while others > use hotspot/system default sizes, which would trigger > StackOverflowError. We could either fine tune the threshold 64K to be > a bigger one, or have the initial thread created with system defaults > that may be what the user expects. This patch chooses the second > solution, to avoid potential side-effect of the first. > > This can be reproduced with 10, 11, 12 too, so I cc'ed jdk-updates-dev here. > > More details please refer to the ticket. > > JBS: https://bugs.openjdk.java.net/browse/JDK-8222334 > > Webrev: http://cr.openjdk.java.net/~qpzhang/8222334/webrev.01/ > > Thanks for David's comments in Jira. > > Regards > > Patrick > From david.holmes at oracle.com Fri Apr 12 08:11:50 2019 From: david.holmes at oracle.com (David Holmes) Date: Fri, 12 Apr 2019 18:11:50 +1000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: References: Message-ID: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> Hi Patrick, First apologies that it took me so long to get my head around this. :) Let me summarise the problem as I see it. The launcher specifies no particular semantics for -Xss0, to it 0 is just a very small size. However the VM maps -Xss to -XX:ThreadStackSize and for it 0 means "use the platform default stack size". The launcher examines -Xss because it needs to use it to define the stacksize for the initial thread created to launch the VM. The VM examines -Xss to see what stacksize to use for subsequently created threads and it treats 0 as 'use the platform default' and it otherwise checks the value against some hardcoded minimums and reports an error if it is too small. The initial thread that loads the VM needs sufficient stack to be able to process things to the point where it can determine that the requested stacksize is too small and report the error. The value of the minimum stack is hardcoded into the launcher, as STACK_SIZE_MINIMUM (64KB). If the -Xss value is less than that then it gets set to that. If no -Xss is specified then the launcher asks the VM for a reasonable value to use for the stacksize of the initial thread (typically 1MB). The problem arises with -Xss0 because this causes the launcher to set an initial thread stacksize of STACK_SIZE_MINIMUM, but the VM sees this as "use the default" and so does not reject it and tries to continue with VM initialization. That can't succeed as we only have a tiny STACK_SIZE_MINIMUM stack and so we get StackOverflowError (or fail an assert in debug builds). So the solution, as Patrick proposes, is to treat -Xss0 in the launcher as-if -Xss has not been set and so use the VM suggested default for the initial thread's stacksize. So I agree with the functional change here, but have some alternate suggestions for additional commentary. Unfortunately I have to step away at the moment (its Friday night) so will send that later - sorry. Thanks, David On 12/04/2019 5:51 pm, Patrick Zhang OS wrote: > Moved this to core-libs-dev for review, thanks. > > Dropped and bcc'ed jdk-dev and jdk-updates-dev. > > Regards > Patrick > > -----Original Message----- > From: David Holmes > Sent: Friday, April 12, 2019 3:43 PM > To: Patrick Zhang OS ; jdk-dev at openjdk.java.net > Cc: jdk-updates-dev at openjdk.java.net > Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError > > Hi Patrick, > > Please takes this to core-libs-dev for review. > > Thanks, > David > > On 12/04/2019 5:24 pm, Patrick Zhang OS wrote: >> Hi, >> >> Please review this patch. >> >> The problem is that the launcher does a check on the input -Xss and >> ensure it >=64K for the initial thread, while vm has another function >> to determine whether the input stack size is big enough to future >> threads, such as cgc_thread, vm_thread, java_thead etc. However if >> -Xss0, the initial thread is created with stack size 64K, while others >> use hotspot/system default sizes, which would trigger >> StackOverflowError. We could either fine tune the threshold 64K to be >> a bigger one, or have the initial thread created with system defaults >> that may be what the user expects. This patch chooses the second >> solution, to avoid potential side-effect of the first. >> >> This can be reproduced with 10, 11, 12 too, so I cc'ed jdk-updates-dev here. >> >> More details please refer to the ticket. >> >> JBS: https://bugs.openjdk.java.net/browse/JDK-8222334 >> >> Webrev: http://cr.openjdk.java.net/~qpzhang/8222334/webrev.01/ >> >> Thanks for David's comments in Jira. >> >> Regards >> >> Patrick >> From patrick at os.amperecomputing.com Fri Apr 12 09:46:24 2019 From: patrick at os.amperecomputing.com (Patrick Zhang OS) Date: Fri, 12 Apr 2019 09:46:24 +0000 Subject: RFR(trivial): 8222394: HashMap.compute() throws CME on an empty Map if clear() called concurrently Message-ID: Created a ticket to track it, welcome any comments. Thanks. JBS https://bugs.openjdk.java.net/browse/JDK-8222394 Webrev: http://cr.openjdk.java.net/~qpzhang/map.clear/webrev.01 Regards Patrick -----Original Message----- From: core-libs-dev On Behalf Of Patrick Zhang OS Sent: Saturday, March 30, 2019 1:34 PM To: core-libs-dev Subject: ConcurrentModificationException thrown by HashMap.compute() operating on an empty Map, expected/unexpected? Hi, Here I have a case simplified from a practical issue that throws ConcurrentModificationException (CME) unexpectedly (I think). [0] creates a HashMap, keeps it empty, and calls m.computeIfAbsent() or m.compute(), in which a "sneaky" m.clear() occurs, some of the test cases throw CME although there were no "structural" changes in fact. (A structural modification is defined as "any operation that adds or deletes one or more mappings..."). This case cannot be reproduced with jdk8u, while jdk9 and beyond can, after the bug [1] got fixed for computeIfAbsent() concurrent co-modification issues. A couple of test cases [2] were introduced at that time, and the focus was to verify the behaviors at resizing, while empty maps were not tested. A possible "fix" for this issue is to move the unconditional "modCount++" [3] into the if-clause, which indicates that a "structural" change would be happening indeed. public void clear() { Node[] tab; - modCount++; if ((tab = table) != null && size > 0) { + modCount++; size = 0; for (int i = 0; i < tab.length; ++i) tab[i] = null; } } Therefore, a dilemma here is "modCount++ before-if-clause but overkills some cases" vs. "modCount++ into-if-clause but weakens the CME checking potentially". I want to make balance regarding how to "throw CME on a best-effort basis" more appropriately. Any suggestion? I understand that CME here in HashMap.java cannot guarantee much and may be only for debugging purpose, any concurrent modification needs to be typically accomplished by synchronizing on some object that naturally encapsulates the map. So the mentioned issue is a just a tricky case. [0]http://cr.openjdk.java.net/~qpzhang/map.clear/webrev.01/test/jdk/java/util/concurrent/ConcurrentMap/ConcurrentModification.java.udiff.html [1]https://bugs.openjdk.java.net/browse/JDK-8071667 [2]http://hg.openjdk.java.net/jdk/jdk/file/5a9d780eb9dd/test/jdk/java/util/Map/FunctionalCMEs.java [3]http://hg.openjdk.java.net/jdk/jdk/file/1042cac8bc2a/src/java.base/share/classes/java/util/HashMap.java#l860 Regards Patrick From goetz.lindenmaier at sap.com Fri Apr 12 10:33:05 2019 From: goetz.lindenmaier at sap.com (Lindenmaier, Goetz) Date: Fri, 12 Apr 2019 10:33:05 +0000 Subject: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null. In-Reply-To: References: <7c4b0bc27961471e91195bef9e767226@sap.com> <5c445ea9-24fb-0007-78df-41b94aadde2a@oracle.com> <8d1cc0b0-4a01-4564-73a9-4c635bfbfbaf@oracle.com> <3245ec3cefe2471e8382048164c0ba6b@sap.com> Message-ID: Hi, while waiting for progress on corresponding the JEP, I improved the implementation of generating the NPE message. It now uses a single outputStream. This removes several allocations of temporary data. I also removed TrackingStackSource. The analysis code originally addressed several use cases, for NullPointerExceptions this is not needed. I cleaned up bytecodeUtils from some code not (really) needed. I split get_null_pointer_slot() into two methods: get_NPE_null_slot() and print_NPE_failed_action(). This simplifies the implementation, and streamlines it more with the text in the JEP. I print methods using the code added in "8221470: Print methods in exception messages in java-like Syntax.", so it now prints 'void m(int)' instead of 'm(I)V'. I implemented a row of new test cases, and rearranged the test to test the message part of print_NPE_failed_action() and print_NPE_cause() separated. I made sure all bytecodes handled in these methods are covered. Further I arranged the tests in methods according to the functional properties as discussed in the JEP. http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/07 Best regards, Goetz. > -----Original Message----- > From: Lindenmaier, Goetz > Sent: Donnerstag, 14. M?rz 2019 21:56 > To: 'Mandy Chung' ; 'Roger Riggs' > > Cc: 'Java Core Libs' ; 'hotspot-runtime- > dev at openjdk.java.net' > Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException > describing what is null. > > Hi, > > I had promised to work on a better wording of the messages. > > This I deliver with this webrev: > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05- > otherMessages/ > > The test in the webrev is modified to just print messages along with the > code that raised the messages. > > Please have a look at these files with test output contained in the webrev: > Messages with debug information: > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05- > otherMessages/output_with_debug_info.txt > Messages without debug information: > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05- > otherMessages/output_no_debug_info.txt > > Especially look at the first few messages, they point out the usefulness > of this change. They precisely say what was null in a chain of dereferences. > > Best regards, > Goetz. > > > > -----Original Message----- > > From: Lindenmaier, Goetz > > Sent: Wednesday, February 13, 2019 10:09 AM > > To: 'Mandy Chung' ; Roger Riggs > > > > Cc: Java Core Libs ; hotspot-runtime- > > dev at openjdk.java.net > > Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException > > describing what is null. > > > > Hi Mandy, > > > > Thanks for supporting my intend of adding the message as such! > > I'll start implementing this in Java and come back with a webrev > > in a while. > > > > In parallel, I would like to continue discussing the other > > topics, e.g., the wording of the message. I will probably come up > > with a separate webrev for that. > > > > Best regards, > > Goetz. > > > > > > > > > -----Original Message----- > > > From: core-libs-dev On Behalf > > > Of Mandy Chung > > > Sent: Tuesday, February 12, 2019 7:32 PM > > > To: Roger Riggs > > > Cc: Java Core Libs ; hotspot-runtime- > > > dev at openjdk.java.net > > > Subject: Re: RFR(L): 8218628: Add detailed message to > > NullPointerException > > > describing what is null. > > > > > > On 2/8/19 11:46 AM, Roger Riggs wrote: > > > > Hi, > > > > > > > > A few higher level issues should be considered, though the details > > > > of the webrev captured my immediate attention. > > > > > > > > Is this the right feature and is this the right level of implementation > > > > (C++/native)? > > > > : > > > > How much of this can be done in Java code with StackWalker and other > > > > java APIs? > > > > It would be a shame to add this much native code if there was a more > > > robust > > > > way to implement it using APIs with more leverage. > > > > > > Improving the NPE message for better diagnosability is helpful while > > > I share the same concern Roger raised. > > > > > > Implementing this feature in Java and the library would be a better > > > choice as this isn't absolutely required to be done in VM in native. > > > > > > NPE keeps a backtrace capturing the method id and bci of each stack > > > frame. One option to explore is to have StackWalker to accept a > > > Throwable object that returns a stream of StackFrame which allows > > > you to get the method and BCI and also code source (I started a > > > prototype for JDK-8189752 some time ago). It can use the bytecode > > > library e.g. ASM to read the bytecode. For NPE message, you can > > > implement a specialized StackFrameTraverser just for building > > > an exception message purpose. > > > > > > Mandy From goetz.lindenmaier at sap.com Fri Apr 12 10:44:51 2019 From: goetz.lindenmaier at sap.com (Lindenmaier, Goetz) Date: Fri, 12 Apr 2019 10:44:51 +0000 Subject: RFR: 8220715 JEP Draft: Add detailed message to NullPointerException describing what is null Message-ID: Hi, This JEP proposes to enhance the messages of NullPointerExceptions that are thrown if execution of a bytecode fails due to a null reference. https://bugs.openjdk.java.net/browse/JDK-8220715 A corresponding prototype exists and is submitted to the sandbox repo and is available as change 8218628. I already got valuable input on this topic by Mandy: http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2019-March/033115.html Is anyone else interested in commenting on this? Would someone sponsor this JEP? Best regards, Goetz. > -----Original Message----- > From: Lindenmaier, Goetz > Sent: Freitag, 15. M?rz 2019 11:55 > To: 'mark.reinhold at oracle.com' ; > maurizio.cimadamore at oracle.com > Cc: mandy.chung at oracle.com; roger.riggs at oracle.com; core-libs- > dev at openjdk.java.net; hotspot-runtime-dev at openjdk.java.net > Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException > describing what is null. > > Hi everybody, Mark, > > I followed your advice and created a JEP: > https://bugs.openjdk.java.net/browse/JDK-8220715 > > Please point me to things I need to improve formally, this is my first > JEP. Also feel free to fix the administrative information in the > Jira issue if it is wrong. > > And, naturally, you're welcome to discuss the topic! > > Best regards, > Goetz. > > > -----Original Message----- > > From: mark.reinhold at oracle.com > > Sent: Donnerstag, 14. M?rz 2019 22:38 > > To: maurizio.cimadamore at oracle.com; Lindenmaier, Goetz > > > > Cc: mandy.chung at oracle.com; roger.riggs at oracle.com; core-libs- > > dev at openjdk.java.net; hotspot-runtime-dev at openjdk.java.net > > Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException > > describing what is null. > > > > 2019/3/14 8:00:20 -0700, maurizio.cimadamore at oracle.com: > > > I second what Mandy says. > > > > > > First let me start by saying that this enhancement will be a great > > > addition to our platform; back in the days when I was teaching some Java > > > classes at the university, I was very aware of how hard it is to > > > diagnose a NPE for someone novel to Java programming. > > > > Agreed! > > > > > ... > > > > > > I also think that the design space for such an enhancement is non > > > trivial, and would best be explored (and captured!) in a medium that is > > > something other than a patch. ... > > > > Agreed, also. > > > > Goetz -- if, per Mandy?s suggestion, you?re going to write something > > up using the JEP template, might I suggest that you then submit it as > > an actual JEP? Giving visibility to, and recording, such design-space > > explorations is one of the primary goals of the JEP process. > > > > - Mark From andy.herrick at oracle.com Fri Apr 12 11:51:42 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Fri, 12 Apr 2019 07:51:42 -0400 Subject: RFE: JDK-8217895: jpackage --identifier purpose In-Reply-To: <6b759662-1d4a-99e7-e02e-ade3881491be@oracle.com> References: <4c709612-5350-884a-6c80-9fd5a470f8b0@oracle.com> <6b759662-1d4a-99e7-e02e-ade3881491be@oracle.com> Message-ID: On 4/11/2019 6:06 PM, semyon.sadetsky at oracle.com wrote: > > On 4/11/19 12:05 PM, Andy Herrick wrote: >> Please review the jpackage fix for bug [1] at [2]. >> >> This is a fix for the JDK-8200758-branch branch of the open sandbox >> repository (jpackage). >> >> [1] https://bugs.openjdk.java.net/browse/JDK-8217895 >> >> [2] http://cr.openjdk.java.net/~herrick/8217895/ > Andy, > > Can I ask you to explain why your fix modifies so many files while the > bug requests a change in help texts? > Shouldn't it be a change in the property bundle? What are those other > changes? The bug also requests "reducing --identifier option's unused impact". Part of that (as described in the bugs comments) is that "app.preferences.id" was written into the cfg file and used by the native code for functionality no longer present (using the files generated and read by the preferences api). Another part of that was native code to handle the (now obsolete) old form of the cfg file (as a java properties file). I will add comment in JBS to describe the changes more explicitly. /Andy > > --Semyon >> >> /Andy >> > From kustaa.nyholm at sparetimelabs.com Fri Apr 12 12:00:33 2019 From: kustaa.nyholm at sparetimelabs.com (Kustaa Nyholm) Date: Fri, 12 Apr 2019 15:00:33 +0300 Subject: jpackaged .app not compatible with macOS sandboxing? In-Reply-To: <890699b0-70bb-7990-c258-77e1da4b00b5@oracle.com> References: <269EB126-0208-463F-98F2-828B33750338@sparetimelabs.com> <890699b0-70bb-7990-c258-77e1da4b00b5@oracle.com> Message-ID: > On 4 Apr 2019, at 16.13, Andy Herrick wrote: > > We will file a bug for this part, and address it soon. > > /Andy > Thanks. Is there a bug report number and where can I monitor the progress please? wbr Kusti From lenborje at gmail.com Fri Apr 12 12:25:56 2019 From: lenborje at gmail.com (=?utf-8?Q?Lennart_B=C3=B6rjeson?=) Date: Fri, 12 Apr 2019 14:25:56 +0200 Subject: ZipFileSystem performance regression Message-ID: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> I've found what I believe is a rather severe performance regression in ZipFileSystem. 1.8 and 11 runs OK, 12 does not. Is this the right forum to report such issues? Best regards, /Lennart B?rjeson From claes.redestad at oracle.com Fri Apr 12 12:33:11 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 12 Apr 2019 14:33:11 +0200 Subject: ZipFileSystem performance regression In-Reply-To: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> Message-ID: <0b3d54d4-8c2f-b577-533e-06d2e7835f12@oracle.com> On 2019-04-12 14:25, Lennart B?rjeson wrote: > Is this the right forum to report such issues? I'm sure there are some friendly OpenJDK contributors around these parts who'd be interested in a description and a reproducer. /Claes From christoph.langer at sap.com Fri Apr 12 12:42:19 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Fri, 12 Apr 2019 12:42:19 +0000 Subject: ZipFileSystem performance regression In-Reply-To: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> Message-ID: Hi Lennart, sure, excited to hear it... ?? Thanks Christoph > -----Original Message----- > From: core-libs-dev On Behalf > Of Lennart B?rjeson > Sent: Freitag, 12. April 2019 14:26 > To: core-libs-dev at openjdk.java.net > Subject: ZipFileSystem performance regression > > I've found what I believe is a rather severe performance regression in > ZipFileSystem. 1.8 and 11 runs OK, 12 does not. > > Is this the right forum to report such issues? > > Best regards, > > /Lennart B?rjeson From andy.herrick at oracle.com Fri Apr 12 17:35:09 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Fri, 12 Apr 2019 13:35:09 -0400 Subject: RFR: JDK-8222406: Multiple arguments for the same option - aggragation broken. Message-ID: <153064e9-552e-ddfc-8b36-d3e0cbf64647@oracle.com> Please review the jpackage fix for bug [1] at [2]. This is a fix for the JDK-8200758-branch branch of the open sandbox repository (jpackage). [1] https://bugs.openjdk.java.net/browse/JDK-8222406 [2] http://cr.openjdk.java.net/~herrick/8222406/ /Andy From ivan.gerasimov at oracle.com Fri Apr 12 19:29:33 2019 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Fri, 12 Apr 2019 12:29:33 -0700 Subject: [12u] RFR : 8221530: Caller sensitive methods not handling caller = null when invoked by JNI code with no java frames on stack + JDK-8222078, JDK-8222082, JDK-8222111 Message-ID: <382a5e15-3529-0ffa-95ff-434b58211675@oracle.com> Hello! This is request to review the combined backport for the four listed bugs (the later three are the test fixes). The first fix had to be slightly modified: 1) The spec change was removed from AccessibleObject.java, 2) The method jdk.test.lib.Platform.sharedLibraryPathVariableName(), which is used in the regression test was added (this method was introduced with the fix for JDK-8216265 , which is not feasible to backport). Would you please review and approve? BUGURL: https://bugs.openjdk.java.net/browse/JDK-8221530 WEBREV: http://cr.openjdk.java.net/~igerasim/8221530/00/webrev/ Thanks in advance! -- With kind regards, Ivan Gerasimov From stuart.marks at oracle.com Fri Apr 12 20:14:46 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Fri, 12 Apr 2019 13:14:46 -0700 Subject: RFR(trivial): 8222394: HashMap.compute() throws CME on an empty Map if clear() called concurrently In-Reply-To: References: Message-ID: [I'm about to leave for a week's vacation, so I won't be able to respond further until after I return] Hi Patrick, A bit of background about my thinking on this proposal. The Collections Framework has a set of weird edge cases ("tricky", as you say) that I'll describe as "state-dependent" behavior, where operations that seem illegal on their face might or might not throw an exception depending on the current state of the system. The current state potentially depends on everything that happened previously, including input to the program. As an example of this, consider the following code snippet: List list1 = Collections.emptyList(); List list2 = getStringsFromSomewhere(); list1.addAll(list2); What happens on the third line? The spec for Collections.emptyList() [1] says that the returned list is immutable. You might think, then, that addAll() will throw UnsupportedOperationException. What actually happens is, "it depends." If list2 has elements, then addAll() will throw UOE as expected. However, if list2 happens to be empty, then addAll() returns false, because nothing was added. To me, the code above clearly has a bug: it's calling a mutator method on an immutable collection. The only time this doesn't throw an exception is if list2 is empty, so it can't possibly have any useful effect in this case. Presumably getStringsFromSomewhere() will return some actual strings from time to time. If this happens rarely, we might put this code into production, and it might blow up unexpectedly when a different set of inputs causes list2 to be nonempty. (Aside 1: the Java 9 unmodifiable collections throw UOE unconditionally, so List.of().addAll(List.of()) will throw UOE.) (Aside 2: even though it's inconsistent and arguably wrong, I don't think this behavior of emptyList() should be changed, for compatibility reasons.) I think you can see the analogy with HashMap.compute(). The cases from the tests essentially do this: var m = new HashMap(); // possible modifications to m m.compute(someKey, (k, v) -> { m.clear(); return someValue; }); Looking at this code, and not knowing the state of m, it seems to me it has a bug. The spec for compute() [2] says "The remapping function should not modify this map during computation" and there's a call to clear() right there. Indeed, the current code always throws ConcurrentModificationException. You're proposing that it not throw CME in the case where m is empty, when clear() has no effect. This is similar to the case above; if m is often empty, then this code appears to "work". But if the program's input were to change and m becomes non-empty, it'll throw CME unexpectedly. On the other hand, it would allow clear() in exactly the cases where it has no effect. Overall I don't see that the system is improved by this change. It allows a particular operation only when it has no effect (thus adding no value), and it increases the risk of bugs in programs going undetected. s'marks [1] https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collections.html#emptyList() [2] https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Map.html#compute(K,java.util.function.BiFunction) On 4/12/19 2:46 AM, Patrick Zhang OS wrote: > Created a ticket to track it, welcome any comments. Thanks. > > JBS https://bugs.openjdk.java.net/browse/JDK-8222394 > Webrev: http://cr.openjdk.java.net/~qpzhang/map.clear/webrev.01 > > Regards > Patrick > > -----Original Message----- > From: core-libs-dev On Behalf Of Patrick Zhang OS > Sent: Saturday, March 30, 2019 1:34 PM > To: core-libs-dev > Subject: ConcurrentModificationException thrown by HashMap.compute() operating on an empty Map, expected/unexpected? > > Hi, > Here I have a case simplified from a practical issue that throws ConcurrentModificationException (CME) unexpectedly (I think). [0] creates a HashMap, keeps it empty, and calls m.computeIfAbsent() or m.compute(), in which a "sneaky" m.clear() occurs, some of the test cases throw CME although there were no "structural" changes in fact. (A structural modification is defined as "any operation that adds or deletes one or more mappings..."). > > This case cannot be reproduced with jdk8u, while jdk9 and beyond can, after the bug [1] got fixed for computeIfAbsent() concurrent co-modification issues. A couple of test cases [2] were introduced at that time, and the focus was to verify the behaviors at resizing, while empty maps were not tested. > > A possible "fix" for this issue is to move the unconditional "modCount++" [3] into the if-clause, which indicates that a "structural" change would be happening indeed. > > public void clear() { > Node[] tab; > - modCount++; > if ((tab = table) != null && size > 0) { > + modCount++; > size = 0; > for (int i = 0; i < tab.length; ++i) > tab[i] = null; > } > } > > Therefore, a dilemma here is "modCount++ before-if-clause but overkills some cases" vs. "modCount++ into-if-clause but weakens the CME checking potentially". I want to make balance regarding how to "throw CME on a best-effort basis" more appropriately. Any suggestion? > > I understand that CME here in HashMap.java cannot guarantee much and may be only for debugging purpose, any concurrent modification needs to be typically accomplished by synchronizing on some object that naturally encapsulates the map. So the mentioned issue is a just a tricky case. > > [0]http://cr.openjdk.java.net/~qpzhang/map.clear/webrev.01/test/jdk/java/util/concurrent/ConcurrentMap/ConcurrentModification.java.udiff.html > [1]https://bugs.openjdk.java.net/browse/JDK-8071667 > [2]http://hg.openjdk.java.net/jdk/jdk/file/5a9d780eb9dd/test/jdk/java/util/Map/FunctionalCMEs.java > [3]http://hg.openjdk.java.net/jdk/jdk/file/1042cac8bc2a/src/java.base/share/classes/java/util/HashMap.java#l860 > > Regards > Patrick > From jason_mehrens at hotmail.com Fri Apr 12 20:52:13 2019 From: jason_mehrens at hotmail.com (Jason Mehrens) Date: Fri, 12 Apr 2019 20:52:13 +0000 Subject: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null. In-Reply-To: References: <7c4b0bc27961471e91195bef9e767226@sap.com> <5c445ea9-24fb-0007-78df-41b94aadde2a@oracle.com> <8d1cc0b0-4a01-4564-73a9-4c635bfbfbaf@oracle.com> <3245ec3cefe2471e8382048164c0ba6b@sap.com> , Message-ID: Hi Goetz, Looking at the test cases I didn't see any tests for the single argument java.util.Objects.requireNonNull. Using this prototype is that method treated like a hidden frame? Cheers, Jason ________________________________________ From: core-libs-dev on behalf of Lindenmaier, Goetz Sent: Friday, April 12, 2019 5:33 AM To: Mandy Chung; Roger Riggs Cc: Java Core Libs; hotspot-runtime-dev at openjdk.java.net Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException describing what is null. Hi, while waiting for progress on corresponding the JEP, I improved the implementation of generating the NPE message. It now uses a single outputStream. This removes several allocations of temporary data. I also removed TrackingStackSource. The analysis code originally addressed several use cases, for NullPointerExceptions this is not needed. I cleaned up bytecodeUtils from some code not (really) needed. I split get_null_pointer_slot() into two methods: get_NPE_null_slot() and print_NPE_failed_action(). This simplifies the implementation, and streamlines it more with the text in the JEP. I print methods using the code added in "8221470: Print methods in exception messages in java-like Syntax.", so it now prints 'void m(int)' instead of 'm(I)V'. I implemented a row of new test cases, and rearranged the test to test the message part of print_NPE_failed_action() and print_NPE_cause() separated. I made sure all bytecodes handled in these methods are covered. Further I arranged the tests in methods according to the functional properties as discussed in the JEP. http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/07 Best regards, Goetz. > -----Original Message----- > From: Lindenmaier, Goetz > Sent: Donnerstag, 14. M?rz 2019 21:56 > To: 'Mandy Chung' ; 'Roger Riggs' > > Cc: 'Java Core Libs' ; 'hotspot-runtime- > dev at openjdk.java.net' > Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException > describing what is null. > > Hi, > > I had promised to work on a better wording of the messages. > > This I deliver with this webrev: > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05- > otherMessages/ > > The test in the webrev is modified to just print messages along with the > code that raised the messages. > > Please have a look at these files with test output contained in the webrev: > Messages with debug information: > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05- > otherMessages/output_with_debug_info.txt > Messages without debug information: > http://cr.openjdk.java.net/~goetz/wr19/8218628-exMsg-NPE/05- > otherMessages/output_no_debug_info.txt > > Especially look at the first few messages, they point out the usefulness > of this change. They precisely say what was null in a chain of dereferences. > > Best regards, > Goetz. > > > > -----Original Message----- > > From: Lindenmaier, Goetz > > Sent: Wednesday, February 13, 2019 10:09 AM > > To: 'Mandy Chung' ; Roger Riggs > > > > Cc: Java Core Libs ; hotspot-runtime- > > dev at openjdk.java.net > > Subject: RE: RFR(L): 8218628: Add detailed message to NullPointerException > > describing what is null. > > > > Hi Mandy, > > > > Thanks for supporting my intend of adding the message as such! > > I'll start implementing this in Java and come back with a webrev > > in a while. > > > > In parallel, I would like to continue discussing the other > > topics, e.g., the wording of the message. I will probably come up > > with a separate webrev for that. > > > > Best regards, > > Goetz. > > > > > > > > > -----Original Message----- > > > From: core-libs-dev On Behalf > > > Of Mandy Chung > > > Sent: Tuesday, February 12, 2019 7:32 PM > > > To: Roger Riggs > > > Cc: Java Core Libs ; hotspot-runtime- > > > dev at openjdk.java.net > > > Subject: Re: RFR(L): 8218628: Add detailed message to > > NullPointerException > > > describing what is null. > > > > > > On 2/8/19 11:46 AM, Roger Riggs wrote: > > > > Hi, > > > > > > > > A few higher level issues should be considered, though the details > > > > of the webrev captured my immediate attention. > > > > > > > > Is this the right feature and is this the right level of implementation > > > > (C++/native)? > > > > : > > > > How much of this can be done in Java code with StackWalker and other > > > > java APIs? > > > > It would be a shame to add this much native code if there was a more > > > robust > > > > way to implement it using APIs with more leverage. > > > > > > Improving the NPE message for better diagnosability is helpful while > > > I share the same concern Roger raised. > > > > > > Implementing this feature in Java and the library would be a better > > > choice as this isn't absolutely required to be done in VM in native. > > > > > > NPE keeps a backtrace capturing the method id and bci of each stack > > > frame. One option to explore is to have StackWalker to accept a > > > Throwable object that returns a stream of StackFrame which allows > > > you to get the method and BCI and also code source (I started a > > > prototype for JDK-8189752 some time ago). It can use the bytecode > > > library e.g. ASM to read the bytecode. For NPE message, you can > > > implement a specialized StackFrameTraverser just for building > > > an exception message purpose. > > > > > > Mandy From alexander.matveev at oracle.com Fri Apr 12 21:28:18 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Fri, 12 Apr 2019 14:28:18 -0700 Subject: RFR: JDK-8222406: Multiple arguments for the same option - aggragation broken. In-Reply-To: <153064e9-552e-ddfc-8b36-d3e0cbf64647@oracle.com> References: <153064e9-552e-ddfc-8b36-d3e0cbf64647@oracle.com> Message-ID: <9d7bf7e0-1470-b84c-4a29-e1d8201f34d5@oracle.com> Hi Andy, Looks good. Thanks, Alexander On 4/12/2019 10:35 AM, Andy Herrick wrote: > Please review the jpackage fix for bug [1] at [2]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > [1] https://bugs.openjdk.java.net/browse/JDK-8222406 > > [2] http://cr.openjdk.java.net/~herrick/8222406/ > > /Andy > From mandy.chung at oracle.com Sat Apr 13 09:35:38 2019 From: mandy.chung at oracle.com (Mandy Chung) Date: Sat, 13 Apr 2019 17:35:38 +0800 Subject: [12u] RFR : 8221530: Caller sensitive methods not handling caller = null when invoked by JNI code with no java frames on stack + JDK-8222078, JDK-8222082, JDK-8222111 In-Reply-To: <382a5e15-3529-0ffa-95ff-434b58211675@oracle.com> References: <382a5e15-3529-0ffa-95ff-434b58211675@oracle.com> Message-ID: <257b5a0f-cf33-2c6a-eb40-1c0cb1a761c6@oracle.com> On 4/13/19 3:29 AM, Ivan Gerasimov wrote: > Hello! > > This is request to review the combined backport for the four listed > bugs (the later three are the test fixes). > > The first fix had to be slightly modified: > 1) The spec change was removed from AccessibleObject.java, > 2) The method jdk.test.lib.Platform.sharedLibraryPathVariableName(), > which is used in the regression test was added (this method was > introduced with the fix for JDK-8216265 > , which is not > feasible to backport). > > Would you please review and approve? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8221530 > WEBREV: http://cr.openjdk.java.net/~igerasim/8221530/00/webrev/ > The backport looks good to me. Mandy From andy.herrick at oracle.com Sun Apr 14 14:16:15 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Sun, 14 Apr 2019 10:16:15 -0400 Subject: RFR: JDK-8222439: New jpackage test fails on mac, linux Message-ID: <6f4765f3-dbed-08d2-89b4-13850c769203@oracle.com> Please review the jpackage fix for bug [1] at [2]. This is a fix for the JDK-8200758-branch branch of the open sandbox repository (jpackage). [1] https://bugs.openjdk.java.net/browse/JDK-8222439 [2] http://cr.openjdk.java.net/~herrick/8222406/ /Andy From david.holmes at oracle.com Sun Apr 14 22:55:20 2019 From: david.holmes at oracle.com (David Holmes) Date: Mon, 15 Apr 2019 08:55:20 +1000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> References: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> Message-ID: <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> Hi Patrick, Please see: http://cr.openjdk.java.net/~dholmes/8222334/webrev/ for my suggested updates to the commentary. Note that GetDefaultJavaVMInitArgs returns the build-time default stack sizes and so will only return 0 (for "use the system default") on Windows. It is not affected by -XX:ThreadStackSize=n as that only gets processed when the JVM is actually loaded. Thanks, David On 12/04/2019 6:11 pm, David Holmes wrote: > Hi Patrick, > > First apologies that it took me so long to get my head around this. :) > Let me summarise the problem as I see it. > > The launcher specifies no particular semantics for -Xss0, to it 0 is > just a very small size. However the VM maps -Xss to -XX:ThreadStackSize > and for it 0 means "use the platform default stack size". > > The launcher examines -Xss because it needs to use it to define the > stacksize for the initial thread created to launch the VM. > > The VM examines -Xss to see what stacksize to use for subsequently > created threads and it treats 0 as 'use the platform default' and it > otherwise checks the value against some hardcoded minimums and reports > an error if it is too small. > > The initial thread that loads the VM needs sufficient stack to be able > to process things to the point where it can determine that the requested > stacksize is too small and report the error. The value of the minimum > stack is hardcoded into the launcher, as STACK_SIZE_MINIMUM (64KB). If > the -Xss value is less than that then it gets set to that. > > If no -Xss is specified then the launcher asks the VM for a reasonable > value to use for the stacksize of the initial thread (typically 1MB). > > The problem arises with -Xss0 because this causes the launcher to set an > initial thread stacksize of STACK_SIZE_MINIMUM, but the VM sees this as > "use the default" and so does not reject it and tries to continue with > VM initialization. That can't succeed as we only have a tiny > STACK_SIZE_MINIMUM stack and so we get StackOverflowError (or fail an > assert in debug builds). > > So the solution, as Patrick proposes, is to treat -Xss0 in the launcher > as-if -Xss has not been set and so use the VM suggested default for the > initial thread's stacksize. > > So I agree with the functional change here, but have some alternate > suggestions for additional commentary. Unfortunately I have to step away > at the moment (its Friday night) so will send that later - sorry. > > Thanks, > David > > On 12/04/2019 5:51 pm, Patrick Zhang OS wrote: >> Moved this to core-libs-dev for review, thanks. >> >> Dropped and bcc'ed jdk-dev and jdk-updates-dev. >> >> Regards >> Patrick >> >> -----Original Message----- >> From: David Holmes >> Sent: Friday, April 12, 2019 3:43 PM >> To: Patrick Zhang OS ; >> jdk-dev at openjdk.java.net >> Cc: jdk-updates-dev at openjdk.java.net >> Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError >> >> Hi Patrick, >> >> Please takes this to core-libs-dev for review. >> >> Thanks, >> David >> >> On 12/04/2019 5:24 pm, Patrick Zhang OS wrote: >>> Hi, >>> >>> Please review this patch. >>> >>> The problem is that the launcher does a check on the input -Xss and >>> ensure it >=64K for the initial thread, while vm has another function >>> to determine whether the input stack size is big enough to future >>> threads, such as cgc_thread, vm_thread, java_thead etc. However if >>> -Xss0, the initial thread is created with stack size 64K, while others >>> use hotspot/system default sizes, which would trigger >>> StackOverflowError. We could either fine tune the threshold 64K to be >>> a bigger one, or have the initial thread created with system defaults >>> that may be what the user expects. This patch chooses the second >>> solution, to avoid potential side-effect of the first. >>> >>> This can be reproduced with 10, 11, 12 too, so I cc'ed >>> jdk-updates-dev here. >>> >>> More details please refer to the ticket. >>> >>> JBS: https://bugs.openjdk.java.net/browse/JDK-8222334 >>> >>> Webrev: http://cr.openjdk.java.net/~qpzhang/8222334/webrev.01/ >>> >>> Thanks for David's comments in Jira. >>> >>> Regards >>> >>> Patrick >>> From patrick at os.amperecomputing.com Mon Apr 15 05:42:06 2019 From: patrick at os.amperecomputing.com (Patrick Zhang OS) Date: Mon, 15 Apr 2019 05:42:06 +0000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> References: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> Message-ID: Hi David, Many thanks, I integrated your updates into the new patch. > I think STACK_SIZE_MINIMUM is an empirical value, NOT suitable for 'all' platforms, at least not that safe, for example, a tricky experiment is: create the initial thread with 320K, and have later VM inner threads created with 448K, on my aarch64 system, StackOverflowError would be thrown. Fortunately this probably would not occur in real cases, as -Xss60k, -Xss320k, etc. can be stopped by these if-clauses. I changed "all platforms" to "most platforms". > "only used for windows" might ambiguously mean "GetDefaultJavaVMInitArgs returns 0 for windows only" or "only windows supports 0". I updated it as "for example, Windows" http://cr.openjdk.java.net/~qpzhang/8222334/webrev.02/ Regards Patrick -----Original Message----- From: David Holmes Sent: Monday, April 15, 2019 6:55 AM To: Patrick Zhang OS ; core-libs-dev Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError Hi Patrick, Please see: http://cr.openjdk.java.net/~dholmes/8222334/webrev/ for my suggested updates to the commentary. Note that GetDefaultJavaVMInitArgs returns the build-time default stack sizes and so will only return 0 (for "use the system default") on Windows. It is not affected by -XX:ThreadStackSize=n as that only gets processed when the JVM is actually loaded. Thanks, David On 12/04/2019 6:11 pm, David Holmes wrote: > Hi Patrick, > > First apologies that it took me so long to get my head around this. :) > Let me summarise the problem as I see it. > > The launcher specifies no particular semantics for -Xss0, to it 0 is > just a very small size. However the VM maps -Xss to > -XX:ThreadStackSize and for it 0 means "use the platform default stack size". > > The launcher examines -Xss because it needs to use it to define the > stacksize for the initial thread created to launch the VM. > > The VM examines -Xss to see what stacksize to use for subsequently > created threads and it treats 0 as 'use the platform default' and it > otherwise checks the value against some hardcoded minimums and reports > an error if it is too small. > > The initial thread that loads the VM needs sufficient stack to be able > to process things to the point where it can determine that the > requested stacksize is too small and report the error. The value of > the minimum stack is hardcoded into the launcher, as > STACK_SIZE_MINIMUM (64KB). If the -Xss value is less than that then it gets set to that. > > If no -Xss is specified then the launcher asks the VM for a reasonable > value to use for the stacksize of the initial thread (typically 1MB). > > The problem arises with -Xss0 because this causes the launcher to set > an initial thread stacksize of STACK_SIZE_MINIMUM, but the VM sees > this as "use the default" and so does not reject it and tries to > continue with VM initialization. That can't succeed as we only have a > tiny STACK_SIZE_MINIMUM stack and so we get StackOverflowError (or > fail an assert in debug builds). > > So the solution, as Patrick proposes, is to treat -Xss0 in the > launcher as-if -Xss has not been set and so use the VM suggested > default for the initial thread's stacksize. > > So I agree with the functional change here, but have some alternate > suggestions for additional commentary. Unfortunately I have to step > away at the moment (its Friday night) so will send that later - sorry. > > Thanks, > David > > On 12/04/2019 5:51 pm, Patrick Zhang OS wrote: >> Moved this to core-libs-dev for review, thanks. >> >> Dropped and bcc'ed jdk-dev and jdk-updates-dev. >> >> Regards >> Patrick >> >> -----Original Message----- >> From: David Holmes >> Sent: Friday, April 12, 2019 3:43 PM >> To: Patrick Zhang OS ; >> jdk-dev at openjdk.java.net >> Cc: jdk-updates-dev at openjdk.java.net >> Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError >> >> Hi Patrick, >> >> Please takes this to core-libs-dev for review. >> >> Thanks, >> David >> >> On 12/04/2019 5:24 pm, Patrick Zhang OS wrote: >>> Hi, >>> >>> Please review this patch. >>> >>> The problem is that the launcher does a check on the input -Xss and >>> ensure it >=64K for the initial thread, while vm has another >>> function to determine whether the input stack size is big enough to >>> future threads, such as cgc_thread, vm_thread, java_thead etc. >>> However if -Xss0, the initial thread is created with stack size 64K, >>> while others use hotspot/system default sizes, which would trigger >>> StackOverflowError. We could either fine tune the threshold 64K to >>> be a bigger one, or have the initial thread created with system >>> defaults that may be what the user expects. This patch chooses the >>> second solution, to avoid potential side-effect of the first. >>> >>> This can be reproduced with 10, 11, 12 too, so I cc'ed >>> jdk-updates-dev here. >>> >>> More details please refer to the ticket. >>> >>> JBS: https://bugs.openjdk.java.net/browse/JDK-8222334 >>> >>> Webrev: http://cr.openjdk.java.net/~qpzhang/8222334/webrev.01/ >>> >>> Thanks for David's comments in Jira. >>> >>> Regards >>> >>> Patrick >>> From david.holmes at oracle.com Mon Apr 15 06:33:00 2019 From: david.holmes at oracle.com (David Holmes) Date: Mon, 15 Apr 2019 16:33:00 +1000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: References: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> Message-ID: <4b1221a9-fce2-d708-8ea5-084c891c4765@oracle.com> Hi Patrick, On 15/04/2019 3:42 pm, Patrick Zhang OS wrote: > Hi David, > > Many thanks, I integrated your updates into the new patch. Thanks. My only further comment is to not have: 947 * See JDK-8222334 for details Cross references from code to bug reports should be very rare and I don't think this one warrants it. No need to see updated webrev in that case. Cheers, David > >> I think STACK_SIZE_MINIMUM is an empirical value, NOT suitable for 'all' platforms, at least not that safe, for example, a tricky experiment is: create the initial thread with 320K, and have later VM inner threads created with 448K, on my aarch64 system, StackOverflowError would be thrown. Fortunately this probably would not occur in real cases, as -Xss60k, -Xss320k, etc. can be stopped by these if-clauses. I changed "all platforms" to "most platforms". >> "only used for windows" might ambiguously mean "GetDefaultJavaVMInitArgs returns 0 for windows only" or "only windows supports 0". I updated it as "for example, Windows" > > http://cr.openjdk.java.net/~qpzhang/8222334/webrev.02/ > > Regards > Patrick > > -----Original Message----- > From: David Holmes > Sent: Monday, April 15, 2019 6:55 AM > To: Patrick Zhang OS ; core-libs-dev > Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError > > Hi Patrick, > > Please see: > > http://cr.openjdk.java.net/~dholmes/8222334/webrev/ > > for my suggested updates to the commentary. Note that GetDefaultJavaVMInitArgs returns the build-time default stack sizes and so will only return 0 (for "use the system default") on Windows. It is not affected by -XX:ThreadStackSize=n as that only gets processed when the JVM is actually loaded. > > Thanks, > David > > On 12/04/2019 6:11 pm, David Holmes wrote: >> Hi Patrick, >> >> First apologies that it took me so long to get my head around this. :) >> Let me summarise the problem as I see it. >> >> The launcher specifies no particular semantics for -Xss0, to it 0 is >> just a very small size. However the VM maps -Xss to >> -XX:ThreadStackSize and for it 0 means "use the platform default stack size". >> >> The launcher examines -Xss because it needs to use it to define the >> stacksize for the initial thread created to launch the VM. >> >> The VM examines -Xss to see what stacksize to use for subsequently >> created threads and it treats 0 as 'use the platform default' and it >> otherwise checks the value against some hardcoded minimums and reports >> an error if it is too small. >> >> The initial thread that loads the VM needs sufficient stack to be able >> to process things to the point where it can determine that the >> requested stacksize is too small and report the error. The value of >> the minimum stack is hardcoded into the launcher, as >> STACK_SIZE_MINIMUM (64KB). If the -Xss value is less than that then it gets set to that. >> >> If no -Xss is specified then the launcher asks the VM for a reasonable >> value to use for the stacksize of the initial thread (typically 1MB). >> >> The problem arises with -Xss0 because this causes the launcher to set >> an initial thread stacksize of STACK_SIZE_MINIMUM, but the VM sees >> this as "use the default" and so does not reject it and tries to >> continue with VM initialization. That can't succeed as we only have a >> tiny STACK_SIZE_MINIMUM stack and so we get StackOverflowError (or >> fail an assert in debug builds). >> >> So the solution, as Patrick proposes, is to treat -Xss0 in the >> launcher as-if -Xss has not been set and so use the VM suggested >> default for the initial thread's stacksize. >> >> So I agree with the functional change here, but have some alternate >> suggestions for additional commentary. Unfortunately I have to step >> away at the moment (its Friday night) so will send that later - sorry. >> >> Thanks, >> David >> >> On 12/04/2019 5:51 pm, Patrick Zhang OS wrote: >>> Moved this to core-libs-dev for review, thanks. >>> >>> Dropped and bcc'ed jdk-dev and jdk-updates-dev. >>> >>> Regards >>> Patrick >>> >>> -----Original Message----- >>> From: David Holmes >>> Sent: Friday, April 12, 2019 3:43 PM >>> To: Patrick Zhang OS ; >>> jdk-dev at openjdk.java.net >>> Cc: jdk-updates-dev at openjdk.java.net >>> Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError >>> >>> Hi Patrick, >>> >>> Please takes this to core-libs-dev for review. >>> >>> Thanks, >>> David >>> >>> On 12/04/2019 5:24 pm, Patrick Zhang OS wrote: >>>> Hi, >>>> >>>> Please review this patch. >>>> >>>> The problem is that the launcher does a check on the input -Xss and >>>> ensure it >=64K for the initial thread, while vm has another >>>> function to determine whether the input stack size is big enough to >>>> future threads, such as cgc_thread, vm_thread, java_thead etc. >>>> However if -Xss0, the initial thread is created with stack size 64K, >>>> while others use hotspot/system default sizes, which would trigger >>>> StackOverflowError. We could either fine tune the threshold 64K to >>>> be a bigger one, or have the initial thread created with system >>>> defaults that may be what the user expects. This patch chooses the >>>> second solution, to avoid potential side-effect of the first. >>>> >>>> This can be reproduced with 10, 11, 12 too, so I cc'ed >>>> jdk-updates-dev here. >>>> >>>> More details please refer to the ticket. >>>> >>>> JBS: https://bugs.openjdk.java.net/browse/JDK-8222334 >>>> >>>> Webrev: http://cr.openjdk.java.net/~qpzhang/8222334/webrev.01/ >>>> >>>> Thanks for David's comments in Jira. >>>> >>>> Regards >>>> >>>> Patrick >>>> From patrick at os.amperecomputing.com Mon Apr 15 07:34:00 2019 From: patrick at os.amperecomputing.com (Patrick Zhang OS) Date: Mon, 15 Apr 2019 07:34:00 +0000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: <4b1221a9-fce2-d708-8ea5-084c891c4765@oracle.com> References: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> <4b1221a9-fce2-d708-8ea5-084c891c4765@oracle.com> Message-ID: Removed it. http://cr.openjdk.java.net/~qpzhang/8222334/webrev.03/jdk.changeset By the way, could you please sponsor to push it once approved? thanks in advance. Regards Patrick -----Original Message----- From: David Holmes Sent: Monday, April 15, 2019 2:33 PM To: Patrick Zhang OS ; core-libs-dev Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError Hi Patrick, On 15/04/2019 3:42 pm, Patrick Zhang OS wrote: > Hi David, > > Many thanks, I integrated your updates into the new patch. Thanks. My only further comment is to not have: 947 * See JDK-8222334 for details Cross references from code to bug reports should be very rare and I don't think this one warrants it. No need to see updated webrev in that case. Cheers, David > >> I think STACK_SIZE_MINIMUM is an empirical value, NOT suitable for 'all' platforms, at least not that safe, for example, a tricky experiment is: create the initial thread with 320K, and have later VM inner threads created with 448K, on my aarch64 system, StackOverflowError would be thrown. Fortunately this probably would not occur in real cases, as -Xss60k, -Xss320k, etc. can be stopped by these if-clauses. I changed "all platforms" to "most platforms". >> "only used for windows" might ambiguously mean "GetDefaultJavaVMInitArgs returns 0 for windows only" or "only windows supports 0". I updated it as "for example, Windows" > > http://cr.openjdk.java.net/~qpzhang/8222334/webrev.02/ > > Regards > Patrick > > -----Original Message----- > From: David Holmes > Sent: Monday, April 15, 2019 6:55 AM > To: Patrick Zhang OS ; core-libs-dev > > Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError > > Hi Patrick, > > Please see: > > http://cr.openjdk.java.net/~dholmes/8222334/webrev/ > > for my suggested updates to the commentary. Note that GetDefaultJavaVMInitArgs returns the build-time default stack sizes and so will only return 0 (for "use the system default") on Windows. It is not affected by -XX:ThreadStackSize=n as that only gets processed when the JVM is actually loaded. > > Thanks, > David > > On 12/04/2019 6:11 pm, David Holmes wrote: >> Hi Patrick, >> >> First apologies that it took me so long to get my head around this. >> :) Let me summarise the problem as I see it. >> >> The launcher specifies no particular semantics for -Xss0, to it 0 is >> just a very small size. However the VM maps -Xss to >> -XX:ThreadStackSize and for it 0 means "use the platform default stack size". >> >> The launcher examines -Xss because it needs to use it to define the >> stacksize for the initial thread created to launch the VM. >> >> The VM examines -Xss to see what stacksize to use for subsequently >> created threads and it treats 0 as 'use the platform default' and it >> otherwise checks the value against some hardcoded minimums and >> reports an error if it is too small. >> >> The initial thread that loads the VM needs sufficient stack to be >> able to process things to the point where it can determine that the >> requested stacksize is too small and report the error. The value of >> the minimum stack is hardcoded into the launcher, as >> STACK_SIZE_MINIMUM (64KB). If the -Xss value is less than that then it gets set to that. >> >> If no -Xss is specified then the launcher asks the VM for a >> reasonable value to use for the stacksize of the initial thread (typically 1MB). >> >> The problem arises with -Xss0 because this causes the launcher to set >> an initial thread stacksize of STACK_SIZE_MINIMUM, but the VM sees >> this as "use the default" and so does not reject it and tries to >> continue with VM initialization. That can't succeed as we only have a >> tiny STACK_SIZE_MINIMUM stack and so we get StackOverflowError (or >> fail an assert in debug builds). >> >> So the solution, as Patrick proposes, is to treat -Xss0 in the >> launcher as-if -Xss has not been set and so use the VM suggested >> default for the initial thread's stacksize. >> >> So I agree with the functional change here, but have some alternate >> suggestions for additional commentary. Unfortunately I have to step >> away at the moment (its Friday night) so will send that later - sorry. >> >> Thanks, >> David >> >> On 12/04/2019 5:51 pm, Patrick Zhang OS wrote: >>> Moved this to core-libs-dev for review, thanks. >>> >>> Dropped and bcc'ed jdk-dev and jdk-updates-dev. >>> >>> Regards >>> Patrick >>> >>> -----Original Message----- >>> From: David Holmes >>> Sent: Friday, April 12, 2019 3:43 PM >>> To: Patrick Zhang OS ; >>> jdk-dev at openjdk.java.net >>> Cc: jdk-updates-dev at openjdk.java.net >>> Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError >>> >>> Hi Patrick, >>> >>> Please takes this to core-libs-dev for review. >>> >>> Thanks, >>> David >>> >>> On 12/04/2019 5:24 pm, Patrick Zhang OS wrote: >>>> Hi, >>>> >>>> Please review this patch. >>>> >>>> The problem is that the launcher does a check on the input -Xss and >>>> ensure it >=64K for the initial thread, while vm has another >>>> function to determine whether the input stack size is big enough to >>>> future threads, such as cgc_thread, vm_thread, java_thead etc. >>>> However if -Xss0, the initial thread is created with stack size >>>> 64K, while others use hotspot/system default sizes, which would >>>> trigger StackOverflowError. We could either fine tune the threshold >>>> 64K to be a bigger one, or have the initial thread created with >>>> system defaults that may be what the user expects. This patch >>>> chooses the second solution, to avoid potential side-effect of the first. >>>> >>>> This can be reproduced with 10, 11, 12 too, so I cc'ed >>>> jdk-updates-dev here. >>>> >>>> More details please refer to the ticket. >>>> >>>> JBS: https://bugs.openjdk.java.net/browse/JDK-8222334 >>>> >>>> Webrev: http://cr.openjdk.java.net/~qpzhang/8222334/webrev.01/ >>>> >>>> Thanks for David's comments in Jira. >>>> >>>> Regards >>>> >>>> Patrick >>>> From david.holmes at oracle.com Mon Apr 15 07:48:33 2019 From: david.holmes at oracle.com (David Holmes) Date: Mon, 15 Apr 2019 17:48:33 +1000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: References: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> <4b1221a9-fce2-d708-8ea5-084c891c4765@oracle.com> Message-ID: <5f228dd6-adae-dc59-e712-46a6d2982ae8@oracle.com> On 15/04/2019 5:34 pm, Patrick Zhang OS wrote: > Removed it. http://cr.openjdk.java.net/~qpzhang/8222334/webrev.03/jdk.changeset > > By the way, could you please sponsor to push it once approved? thanks in advance. Sure - if the core-libs person who also reviews doesn't volunteer (hint hint ;-) ) Cheers, David > Regards > Patrick > > -----Original Message----- > From: David Holmes > Sent: Monday, April 15, 2019 2:33 PM > To: Patrick Zhang OS ; core-libs-dev > Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError > > Hi Patrick, > > On 15/04/2019 3:42 pm, Patrick Zhang OS wrote: >> Hi David, >> >> Many thanks, I integrated your updates into the new patch. > > Thanks. My only further comment is to not have: > > 947 * See JDK-8222334 for details > > Cross references from code to bug reports should be very rare and I don't think this one warrants it. No need to see updated webrev in that case. > > Cheers, > David > >> >>> I think STACK_SIZE_MINIMUM is an empirical value, NOT suitable for 'all' platforms, at least not that safe, for example, a tricky experiment is: create the initial thread with 320K, and have later VM inner threads created with 448K, on my aarch64 system, StackOverflowError would be thrown. Fortunately this probably would not occur in real cases, as -Xss60k, -Xss320k, etc. can be stopped by these if-clauses. I changed "all platforms" to "most platforms". >>> "only used for windows" might ambiguously mean "GetDefaultJavaVMInitArgs returns 0 for windows only" or "only windows supports 0". I updated it as "for example, Windows" >> >> http://cr.openjdk.java.net/~qpzhang/8222334/webrev.02/ >> >> Regards >> Patrick >> >> -----Original Message----- >> From: David Holmes >> Sent: Monday, April 15, 2019 6:55 AM >> To: Patrick Zhang OS ; core-libs-dev >> >> Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError >> >> Hi Patrick, >> >> Please see: >> >> http://cr.openjdk.java.net/~dholmes/8222334/webrev/ >> >> for my suggested updates to the commentary. Note that GetDefaultJavaVMInitArgs returns the build-time default stack sizes and so will only return 0 (for "use the system default") on Windows. It is not affected by -XX:ThreadStackSize=n as that only gets processed when the JVM is actually loaded. >> >> Thanks, >> David >> >> On 12/04/2019 6:11 pm, David Holmes wrote: >>> Hi Patrick, >>> >>> First apologies that it took me so long to get my head around this. >>> :) Let me summarise the problem as I see it. >>> >>> The launcher specifies no particular semantics for -Xss0, to it 0 is >>> just a very small size. However the VM maps -Xss to >>> -XX:ThreadStackSize and for it 0 means "use the platform default stack size". >>> >>> The launcher examines -Xss because it needs to use it to define the >>> stacksize for the initial thread created to launch the VM. >>> >>> The VM examines -Xss to see what stacksize to use for subsequently >>> created threads and it treats 0 as 'use the platform default' and it >>> otherwise checks the value against some hardcoded minimums and >>> reports an error if it is too small. >>> >>> The initial thread that loads the VM needs sufficient stack to be >>> able to process things to the point where it can determine that the >>> requested stacksize is too small and report the error. The value of >>> the minimum stack is hardcoded into the launcher, as >>> STACK_SIZE_MINIMUM (64KB). If the -Xss value is less than that then it gets set to that. >>> >>> If no -Xss is specified then the launcher asks the VM for a >>> reasonable value to use for the stacksize of the initial thread (typically 1MB). >>> >>> The problem arises with -Xss0 because this causes the launcher to set >>> an initial thread stacksize of STACK_SIZE_MINIMUM, but the VM sees >>> this as "use the default" and so does not reject it and tries to >>> continue with VM initialization. That can't succeed as we only have a >>> tiny STACK_SIZE_MINIMUM stack and so we get StackOverflowError (or >>> fail an assert in debug builds). >>> >>> So the solution, as Patrick proposes, is to treat -Xss0 in the >>> launcher as-if -Xss has not been set and so use the VM suggested >>> default for the initial thread's stacksize. >>> >>> So I agree with the functional change here, but have some alternate >>> suggestions for additional commentary. Unfortunately I have to step >>> away at the moment (its Friday night) so will send that later - sorry. >>> >>> Thanks, >>> David >>> >>> On 12/04/2019 5:51 pm, Patrick Zhang OS wrote: >>>> Moved this to core-libs-dev for review, thanks. >>>> >>>> Dropped and bcc'ed jdk-dev and jdk-updates-dev. >>>> >>>> Regards >>>> Patrick >>>> >>>> -----Original Message----- >>>> From: David Holmes >>>> Sent: Friday, April 12, 2019 3:43 PM >>>> To: Patrick Zhang OS ; >>>> jdk-dev at openjdk.java.net >>>> Cc: jdk-updates-dev at openjdk.java.net >>>> Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError >>>> >>>> Hi Patrick, >>>> >>>> Please takes this to core-libs-dev for review. >>>> >>>> Thanks, >>>> David >>>> >>>> On 12/04/2019 5:24 pm, Patrick Zhang OS wrote: >>>>> Hi, >>>>> >>>>> Please review this patch. >>>>> >>>>> The problem is that the launcher does a check on the input -Xss and >>>>> ensure it >=64K for the initial thread, while vm has another >>>>> function to determine whether the input stack size is big enough to >>>>> future threads, such as cgc_thread, vm_thread, java_thead etc. >>>>> However if -Xss0, the initial thread is created with stack size >>>>> 64K, while others use hotspot/system default sizes, which would >>>>> trigger StackOverflowError. We could either fine tune the threshold >>>>> 64K to be a bigger one, or have the initial thread created with >>>>> system defaults that may be what the user expects. This patch >>>>> chooses the second solution, to avoid potential side-effect of the first. >>>>> >>>>> This can be reproduced with 10, 11, 12 too, so I cc'ed >>>>> jdk-updates-dev here. >>>>> >>>>> More details please refer to the ticket. >>>>> >>>>> JBS: https://bugs.openjdk.java.net/browse/JDK-8222334 >>>>> >>>>> Webrev: http://cr.openjdk.java.net/~qpzhang/8222334/webrev.01/ >>>>> >>>>> Thanks for David's comments in Jira. >>>>> >>>>> Regards >>>>> >>>>> Patrick >>>>> From claes.redestad at oracle.com Mon Apr 15 10:49:12 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 15 Apr 2019 12:49:12 +0200 Subject: RFR: 8222484: Specialize generation of simple String concatenation expressions Message-ID: <570f7566-e70b-4c47-e930-4cc46d9bbed6@oracle.com> Hi, please review this enhancement to specialize a few simple and common String concatenation patterns in the default strategy. Bug: https://bugs.openjdk.java.net/browse/JDK-8222484 Webrev: http://cr.openjdk.java.net/~redestad/8222484/open.00/ This reduces first-time bootstrap times for the targeted patterns from ~20ms to be lost in the noise on my machine (so ~0.5ms), while being peak performance neutral and not regressing bootstrap characteristics on more complex patterns. This also consolidates the String::concat method to reuse the optimized method in StringConcatHelper, which speeds up that method by ~1.4x for a few sampled inputs. Testing: tier1-3 Thanks! /Claes From patrick at os.amperecomputing.com Mon Apr 15 10:51:37 2019 From: patrick at os.amperecomputing.com (Patrick Zhang OS) Date: Mon, 15 Apr 2019 10:51:37 +0000 Subject: RFR(trivial): 8222394: HashMap.compute() throws CME on an empty Map if clear() called concurrently In-Reply-To: References: Message-ID: Hi Stuart, Thanks. I intentionally modified the map in remapping functions, just like those tests in http://hg.openjdk.java.net/jdk/jdk/file/00c0906bf4d1/test/jdk/java/util/Map/FunctionalCMEs.java. My original tests were: create two threads, modify or perform read-only operations in each, and verify those CMEs. There seems some inconsistencies: 1. clear() would modify the map completely, so it can be more 'defensible' (Martin mentioned so in Jira), while other modifying functions like put()/remove()/merge() are 'weaker', so ++modCount happens conditionally, say there would be really some structural modifications in map. 2. compute()/computeIfAbsent() throws CME almost unconditionally, while functions like forEach()/computeIfPresent()/iterator.next() are touching the map content practically so these are wrapped by if-clauses. So the concern is how to undertand "throw CME on a best-effort basis", if I want to try best to detect the risk of bugs in program, unconditionlly throwing CME can be the right way to go, e.g. do ++modCount in removeNode() without telling if the removing would really occur, if I want to make it more logically rigorous, we might need this: http://cr.openjdk.java.net/~qpzhang/8222394/webrev.02 for compute()/computeIfAbsent(). Centainly I know it has to afford the risk of missing bugs. Regards Patrick -----Original Message----- From: Stuart Marks Sent: Saturday, April 13, 2019 4:15 AM To: Patrick Zhang OS Cc: core-libs-dev Subject: Re: RFR(trivial): 8222394: HashMap.compute() throws CME on an empty Map if clear() called concurrently [I'm about to leave for a week's vacation, so I won't be able to respond further until after I return] Hi Patrick, A bit of background about my thinking on this proposal. The Collections Framework has a set of weird edge cases ("tricky", as you say) that I'll describe as "state-dependent" behavior, where operations that seem illegal on their face might or might not throw an exception depending on the current state of the system. The current state potentially depends on everything that happened previously, including input to the program. As an example of this, consider the following code snippet: List list1 = Collections.emptyList(); List list2 = getStringsFromSomewhere(); list1.addAll(list2); What happens on the third line? The spec for Collections.emptyList() [1] says that the returned list is immutable. You might think, then, that addAll() will throw UnsupportedOperationException. What actually happens is, "it depends." If list2 has elements, then addAll() will throw UOE as expected. However, if list2 happens to be empty, then addAll() returns false, because nothing was added. To me, the code above clearly has a bug: it's calling a mutator method on an immutable collection. The only time this doesn't throw an exception is if list2 is empty, so it can't possibly have any useful effect in this case. Presumably getStringsFromSomewhere() will return some actual strings from time to time. If this happens rarely, we might put this code into production, and it might blow up unexpectedly when a different set of inputs causes list2 to be nonempty. (Aside 1: the Java 9 unmodifiable collections throw UOE unconditionally, so List.of().addAll(List.of()) will throw UOE.) (Aside 2: even though it's inconsistent and arguably wrong, I don't think this behavior of emptyList() should be changed, for compatibility reasons.) I think you can see the analogy with HashMap.compute(). The cases from the tests essentially do this: var m = new HashMap(); // possible modifications to m m.compute(someKey, (k, v) -> { m.clear(); return someValue; }); Looking at this code, and not knowing the state of m, it seems to me it has a bug. The spec for compute() [2] says "The remapping function should not modify this map during computation" and there's a call to clear() right there. Indeed, the current code always throws ConcurrentModificationException. You're proposing that it not throw CME in the case where m is empty, when clear() has no effect. This is similar to the case above; if m is often empty, then this code appears to "work". But if the program's input were to change and m becomes non-empty, it'll throw CME unexpectedly. On the other hand, it would allow clear() in exactly the cases where it has no effect. Overall I don't see that the system is improved by this change. It allows a particular operation only when it has no effect (thus adding no value), and it increases the risk of bugs in programs going undetected. s'marks [1] https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collections.html#emptyList() [2] https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Map.html#compute(K,java.util.function.BiFunction) On 4/12/19 2:46 AM, Patrick Zhang OS wrote: > Created a ticket to track it, welcome any comments. Thanks. > > JBS https://bugs.openjdk.java.net/browse/JDK-8222394 > Webrev: http://cr.openjdk.java.net/~qpzhang/map.clear/webrev.01 > > Regards > Patrick > > -----Original Message----- > From: core-libs-dev On Behalf Of Patrick Zhang OS > Sent: Saturday, March 30, 2019 1:34 PM > To: core-libs-dev > Subject: ConcurrentModificationException thrown by HashMap.compute() operating on an empty Map, expected/unexpected? > > Hi, > Here I have a case simplified from a practical issue that throws ConcurrentModificationException (CME) unexpectedly (I think). [0] creates a HashMap, keeps it empty, and calls m.computeIfAbsent() or m.compute(), in which a "sneaky" m.clear() occurs, some of the test cases throw CME although there were no "structural" changes in fact. (A structural modification is defined as "any operation that adds or deletes one or more mappings..."). > > This case cannot be reproduced with jdk8u, while jdk9 and beyond can, after the bug [1] got fixed for computeIfAbsent() concurrent co-modification issues. A couple of test cases [2] were introduced at that time, and the focus was to verify the behaviors at resizing, while empty maps were not tested. > > A possible "fix" for this issue is to move the unconditional "modCount++" [3] into the if-clause, which indicates that a "structural" change would be happening indeed. > > public void clear() { > Node[] tab; > - modCount++; > if ((tab = table) != null && size > 0) { > + modCount++; > size = 0; > for (int i = 0; i < tab.length; ++i) > tab[i] = null; > } > } > > Therefore, a dilemma here is "modCount++ before-if-clause but overkills some cases" vs. "modCount++ into-if-clause but weakens the CME checking potentially". I want to make balance regarding how to "throw CME on a best-effort basis" more appropriately. Any suggestion? > > I understand that CME here in HashMap.java cannot guarantee much and may be only for debugging purpose, any concurrent modification needs to be typically accomplished by synchronizing on some object that naturally encapsulates the map. So the mentioned issue is a just a tricky case. > > [0]http://cr.openjdk.java.net/~qpzhang/map.clear/webrev.01/test/jdk/java/util/concurrent/ConcurrentMap/ConcurrentModification.java.udiff.html > [1]https://bugs.openjdk.java.net/browse/JDK-8071667 > [2]http://hg.openjdk.java.net/jdk/jdk/file/5a9d780eb9dd/test/jdk/java/util/Map/FunctionalCMEs.java > [3]http://hg.openjdk.java.net/jdk/jdk/file/1042cac8bc2a/src/java.base/share/classes/java/util/HashMap.java#l860 > > Regards > Patrick > From kevin.rushforth at oracle.com Mon Apr 15 12:23:45 2019 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Mon, 15 Apr 2019 05:23:45 -0700 Subject: RFR: JDK-8222439: New jpackage test fails on mac, linux In-Reply-To: <6f4765f3-dbed-08d2-89b4-13850c769203@oracle.com> References: <6f4765f3-dbed-08d2-89b4-13850c769203@oracle.com> Message-ID: Looks fine. -- Kevin On 4/14/2019 7:16 AM, Andy Herrick wrote: > Please review the jpackage fix for bug [1] at [2]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > [1] https://bugs.openjdk.java.net/browse/JDK-8222439 > > [2] http://cr.openjdk.java.net/~herrick/8222406/ > > > /Andy > From james.laskey at oracle.com Mon Apr 15 12:37:05 2019 From: james.laskey at oracle.com (Jim Laskey) Date: Mon, 15 Apr 2019 09:37:05 -0300 Subject: RFR: 8222484: Specialize generation of simple String concatenation expressions In-Reply-To: <570f7566-e70b-4c47-e930-4cc46d9bbed6@oracle.com> References: <570f7566-e70b-4c47-e930-4cc46d9bbed6@oracle.com> Message-ID: The StringConcatHelper::valueOf really should be StringConcatHelper::stringOf to clarify the result. Use here is unlike String::valueOf context where the result is logically String. StringConcatHelper::mix comments really should describe the encoding. If does a lot of handwaving re checking for overflow and mixing coder. Cheers, -- Jim > On Apr 15, 2019, at 7:49 AM, Claes Redestad wrote: > > Hi, > > please review this enhancement to specialize a few simple and common > String concatenation patterns in the default strategy. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8222484 > Webrev: http://cr.openjdk.java.net/~redestad/8222484/open.00/ > > This reduces first-time bootstrap times for the targeted patterns from > ~20ms to be lost in the noise on my machine (so ~0.5ms), while being > peak performance neutral and not regressing bootstrap characteristics on > more complex patterns. > > This also consolidates the String::concat method to reuse the optimized > method in StringConcatHelper, which speeds up that method by ~1.4x for a > few sampled inputs. > > Testing: tier1-3 > > Thanks! > > /Claes From claes.redestad at oracle.com Mon Apr 15 13:10:22 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 15 Apr 2019 15:10:22 +0200 Subject: RFR: 8222484: Specialize generation of simple String concatenation expressions In-Reply-To: References: <570f7566-e70b-4c47-e930-4cc46d9bbed6@oracle.com> Message-ID: <996985db-a870-41a6-a263-a3a59ba27229@oracle.com> Hi Jim, thanks for reviewing, and it's fair that we seek to improve comments and readability of this code while we're at it: http://cr.openjdk.java.net/~redestad/8222484/open.01/ Also fixed so we're starting with the value of initialCoder() rather than 0L for documentation purposes. Using initialCoder() is only necessary when all operands to a concat expression are primitives, since any Object argument will result in correct mixing in of the UTF16 bit if CompactStrings is disabled. Perhaps there's a small optimization opportunity lurking here.. Thanks! /Claes On 2019-04-15 14:37, Jim Laskey wrote: > The StringConcatHelper::valueOf really should be > StringConcatHelper::stringOf to clarify the result. Use here is unlike > String::valueOf context where the result is logically String. > > StringConcatHelper::mix comments really should describe the encoding. If > does a lot of handwaving re checking for overflow and mixing coder. > > Cheers, > > -- Jim > > > > > > > >> On Apr 15, 2019, at 7:49 AM, Claes Redestad > > wrote: >> >> Hi, >> >> please review this enhancement to specialize a few simple and common >> String concatenation patterns in the default strategy. >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8222484 >> Webrev: http://cr.openjdk.java.net/~redestad/8222484/open.00/ >> >> This reduces first-time bootstrap times for the targeted patterns from >> ~20ms to be lost in the noise on my machine (so ~0.5ms), while being >> peak performance neutral and not regressing bootstrap characteristics on >> more complex patterns. >> >> This also consolidates the String::concat method to reuse the optimized >> method in StringConcatHelper, which speeds up that method by ~1.4x for a >> few sampled inputs. >> >> Testing: tier1-3 >> >> Thanks! >> >> /Claes > From andy.herrick at oracle.com Mon Apr 15 13:32:00 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Mon, 15 Apr 2019 09:32:00 -0400 Subject: RFR: 8222486: Reorder sample usage in jpackage help output Message-ID: <4e56ba04-c92d-660a-8160-81a437876d9e@oracle.com> Please review the jpackage fix for bug [1] at [2]. This is a fix for the JDK-8200758-branch branch of the open sandbox repository (jpackage). [1] https://bugs.openjdk.java.net/browse/JDK-8222486 [2] http://cr.openjdk.java.net/~herrick/8222486/ /Andy From lenborje at gmail.com Mon Apr 15 13:32:38 2019 From: lenborje at gmail.com (=?utf-8?Q?Lennart_B=C3=B6rjeson?=) Date: Mon, 15 Apr 2019 15:32:38 +0200 Subject: ZipFileSystem performance regression In-Reply-To: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> Message-ID: <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> I have made a small command-line utility which creates zip archives by compressing the input files in parallel. I do this by calling Files.copy(input, zipOutputStream) in a parallel Stream over all input files. I have run this with Java 1.8, 9, 10, and 11, on both my local laptop and on server-class machines with up to 40 cores. It scales rather well and I get the expected speedup, i.e. roughly proportional to the number of cores. With OpenJDK 12, however, I get no speedup whatsoever. My understanding is that in JDK 12, the copy method simply transfers the contents of the input stream to a ByteArrayOutputStream, which is then deflated when I close the ZipFileSystem (by the ZipFileSystem.sync() method). Previously, the deflation was done when in the call to Files.copy, thus executed in parallel, and the final ZipFileSystem.close() didn't do anything much. (But I may of course be wrong. In case there's a simpler explanation and something I can remedy in my code, please let me know.) I have a small GitHub gist for the utility here: https://gist.github.com/lenborje/6d2f92430abe4ba881e3c5ff83736923 Steps to reproduce (timings on my 8-core MacBook Pro): 1) Get the contents of the gist as a single file, Zip.java 2) Compile it using Java 8. $ export JAVA_HOME= $ javac -encoding utf8 Zip.java 3) run on a sufficiently large number of files to exercise the parallelity: (I've used about 70 text files ca 60MB each) $ time java -Xmx6g Zip -p /tmp/test.zip /*.log. Working on ZIP FileSystem jar:file:/tmp/test.zip, using the options [PARALLEL] ... completed zip archive, now closing... done! real 0m35.558s user 3m58.134s sys 0m5.543s As is evident from the ratio between "user time" and "real time", all cores have been busy most of the time. (Running with JDK 9, 10, and 11 produces similar timings.) But running with JDK 12 defeats the parallelism: $ export JAVA_HOME= $ rm /tmp/test.zip # From previous run $ time java -Xmx6g Zip -p /tmp/test.zip /*.log. Working on ZIP FileSystem jar:file:/tmp/test.zip, using the options [PARALLEL] ... completed zip archive, now closing... done! real 3m1.187s user 3m5.422s sys 0m12.396s Now there's almost no speedup. When observing the output, note that the ZipFileSystem.close() method is called immediately after the "now closing..." output, and "Done!" Is written when it returns, and when running with JDK 12 almost all running time is apparently spent there. I'm hoping the previous behaviour could somehow be restored, i.e. that deflation actually happens when I'm copying the input files to the ZipFileSystem, and not when I close it. Best regards, /Lennart B?rjeson > 12 apr. 2019 kl. 14:25 skrev Lennart B?rjeson : > > I've found what I believe is a rather severe performance regression in ZipFileSystem. 1.8 and 11 runs OK, 12 does not. > > Is this the right forum to report such issues? > > Best regards, > > /Lennart B?rjeson From claes.redestad at oracle.com Mon Apr 15 14:14:26 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 15 Apr 2019 16:14:26 +0200 Subject: RFR: 8222484: Specialize generation of simple String concatenation expressions In-Reply-To: <996985db-a870-41a6-a263-a3a59ba27229@oracle.com> References: <570f7566-e70b-4c47-e930-4cc46d9bbed6@oracle.com> <996985db-a870-41a6-a263-a3a59ba27229@oracle.com> Message-ID: <24ee0a6b-69a7-d33f-ac1f-aa471a063157@oracle.com> On 2019-04-15 15:10, Claes Redestad wrote: > This reduces first-time bootstrap times for the targeted patterns from > ~20ms to be lost in the noise on my machine (so ~0.5ms), while being > peak performance neutral and not regressing bootstrap characteristics on > more complex patterns. Correction: I accidentally had some tuning flags applied to one set of runs but not the other. In a more fair apple-to-apples re-run the first- time bootstrap cost drops from ~30ms to ~9ms. The 20ms drop was correct in absolute terms, but there's still a measurable cost overhead of initializing SCF itself (this RFE helps amortize those costs in many instances) /Claes From kevin.rushforth at oracle.com Mon Apr 15 15:02:33 2019 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Mon, 15 Apr 2019 08:02:33 -0700 Subject: RFR: 8222486: Reorder sample usage in jpackage help output In-Reply-To: <4e56ba04-c92d-660a-8160-81a437876d9e@oracle.com> References: <4e56ba04-c92d-660a-8160-81a437876d9e@oracle.com> Message-ID: Looks good. -- Kevin On 4/15/2019 6:32 AM, Andy Herrick wrote: > Please review the jpackage fix for bug [1] at [2]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > [1] https://bugs.openjdk.java.net/browse/JDK-8222486 > > [2] http://cr.openjdk.java.net/~herrick/8222486/ > > /Andy > From claes.redestad at oracle.com Mon Apr 15 16:34:33 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 15 Apr 2019 18:34:33 +0200 Subject: ZipFileSystem performance regression In-Reply-To: <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> Message-ID: <9324e5c2-0055-df69-d2c6-c3f3c1087cfa@oracle.com> Hi Lennart, I can reproduce this locally, and have narrowed down to https://bugs.openjdk.java.net/browse/JDK-8034802 as the cause. As you say the compression is deferred to ZipFileSystem.close() now, whereas previously it happened eagerly. We will have to analyze the changes more in-depth to try and see why this is the case. Thanks! /Claes On 2019-04-15 15:32, Lennart B?rjeson wrote: > I have made a small command-line utility which creates zip archives by compressing the input files in parallel. > > I do this by calling Files.copy(input, zipOutputStream) in a parallel Stream over all input files. > > I have run this with Java 1.8, 9, 10, and 11, on both my local laptop and on server-class machines with up to 40 cores. > > It scales rather well and I get the expected speedup, i.e. roughly proportional to the number of cores. > > With OpenJDK 12, however, I get no speedup whatsoever. My understanding is that in JDK 12, the copy method simply > transfers the contents of the input stream to a ByteArrayOutputStream, which is then deflated when I close the ZipFileSystem (by the ZipFileSystem.sync() method). > > Previously, the deflation was done when in the call to Files.copy, thus executed in parallel, and the final ZipFileSystem.close() didn't do anything much. > > (But I may of course be wrong. In case there's a simpler explanation and something I can remedy in my code, please let me know.) > > I have a small GitHub gist for the utility here: https://gist.github.com/lenborje/6d2f92430abe4ba881e3c5ff83736923 > > > Steps to reproduce (timings on my 8-core MacBook Pro): > > 1) Get the contents of the gist as a single file, Zip.java > 2) Compile it using Java 8. > > $ export JAVA_HOME= > $ javac -encoding utf8 Zip.java > > 3) run on a sufficiently large number of files to exercise the parallelity: (I've used about 70 text files ca 60MB each) > > $ time java -Xmx6g Zip -p /tmp/test.zip /*.log. > Working on ZIP FileSystem jar:file:/tmp/test.zip, using the options [PARALLEL] > ... > completed zip archive, now closing... done! > > real 0m35.558s > user 3m58.134s > sys 0m5.543s > > > > As is evident from the ratio between "user time" and "real time", all cores have been busy most of the time. > > (Running with JDK 9, 10, and 11 produces similar timings.) > > > But running with JDK 12 defeats the parallelism: > > $ export JAVA_HOME= > $ rm /tmp/test.zip # From previous run > $ time java -Xmx6g Zip -p /tmp/test.zip /*.log. > Working on ZIP FileSystem jar:file:/tmp/test.zip, using the options [PARALLEL] > ... > completed zip archive, now closing... done! > > real 3m1.187s > user 3m5.422s > sys 0m12.396s > > > > Now there's almost no speedup. When observing the output, note that the ZipFileSystem.close() method is called immediately after the "now closing..." output, and "Done!" Is written when it returns, and when running with JDK 12 almost all running time is apparently spent there. > > I'm hoping the previous behaviour could somehow be restored, i.e. that deflation actually happens when I'm copying the input files to the ZipFileSystem, and not when I close it. > > > Best regards, > > /Lennart B?rjeson > > >> 12 apr. 2019 kl. 14:25 skrev Lennart B?rjeson : >> >> I've found what I believe is a rather severe performance regression in ZipFileSystem. 1.8 and 11 runs OK, 12 does not. >> >> Is this the right forum to report such issues? >> >> Best regards, >> >> /Lennart B?rjeson > From huizhe.wang at oracle.com Mon Apr 15 19:46:06 2019 From: huizhe.wang at oracle.com (Joe Wang) Date: Mon, 15 Apr 2019 12:46:06 -0700 Subject: RFR (JDK 13/java.xml) 8222415: Xerces 2.12.0: Parsing Configuration Message-ID: <5CB4DF7E.6030203@oracle.com> Please review an update from Xerces in the configuration area. The patch contains changes not easily measurable with test (e.g. a few bytes for a parse, or small leaks for a file as large as a GB, or none at all). But the change does improve in that a method ( readAndBuffer) that explicitly buffers was provided so that the processes that required buffer all call it instead of the general read method. While there's a small test added, the testing was focused on getting the existing ones to pass. All XML-related tests in the core tests and JCK passed. JBS: https://bugs.openjdk.java.net/browse/JDK-8222415 webrevs: http://cr.openjdk.java.net/~joehw/jdk13/8222415/webrev/ Thanks, Joe From alexander.matveev at oracle.com Mon Apr 15 20:19:21 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Mon, 15 Apr 2019 13:19:21 -0700 Subject: RFR: 8222486: Reorder sample usage in jpackage help output In-Reply-To: <4e56ba04-c92d-660a-8160-81a437876d9e@oracle.com> References: <4e56ba04-c92d-660a-8160-81a437876d9e@oracle.com> Message-ID: <7460acf1-3093-5b4f-6616-bc455711609a@oracle.com> Hi Andy, Looks good. Thanks, Alexander On 4/15/2019 6:32 AM, Andy Herrick wrote: > Please review the jpackage fix for bug [1] at [2]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > [1] https://bugs.openjdk.java.net/browse/JDK-8222486 > > [2] http://cr.openjdk.java.net/~herrick/8222486/ > > /Andy > From david.holmes at oracle.com Tue Apr 16 02:19:41 2019 From: david.holmes at oracle.com (David Holmes) Date: Tue, 16 Apr 2019 12:19:41 +1000 Subject: SoftReference incorrect javadoc? In-Reply-To: References: Message-ID: <3f29d05c-ee18-ed77-6bda-7f6a76fec587@oracle.com> Hi Michael, Re-directing to core-libs-dev and hotspot-gc-dev. Thanks, David On 16/04/2019 12:14 pm, Michael Pollmeier wrote: > Quoting > https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ref/SoftReference.html > > >> All soft references to softly-reachable objects are guaranteed to have > been cleared before the virtual machine throws an OutOfMemoryError > > That statement was true when soft references were first introduced in > java 1.2, but from java 1.3.1 the jvm property > `-XX:SoftRefLRUPolicyMSPerMB` was introduced. > It defaults to 1000 (milliseconds), meaning that if there?s only 10MB > available heap, the garbage collector will free references that have > been used more than 10s ago. I.e. everything else (including young > softly reachable objects) will *not* be freed, leading to an > OutOfMemoryError, contradicting the above quoted 'guarantee'. > > That's also the behaviour I observed on various JREs. Would you agree, > i.e. should I propose an updated doc? > > Cheers > Michael > From per.liden at oracle.com Tue Apr 16 06:27:15 2019 From: per.liden at oracle.com (Per Liden) Date: Tue, 16 Apr 2019 08:27:15 +0200 Subject: SoftReference incorrect javadoc? In-Reply-To: <3f29d05c-ee18-ed77-6bda-7f6a76fec587@oracle.com> References: <3f29d05c-ee18-ed77-6bda-7f6a76fec587@oracle.com> Message-ID: <99718e43-ad0b-ee70-bdfd-fdea85218288@oracle.com> Hi Michael, On 4/16/19 4:19 AM, David Holmes wrote: > Hi Michael, > > Re-directing to core-libs-dev and hotspot-gc-dev. > > Thanks, > David > > On 16/04/2019 12:14 pm, Michael Pollmeier wrote: >> Quoting >> https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ref/SoftReference.html >> >> >> >>> All soft references to softly-reachable objects are guaranteed to have >> been cleared before the virtual machine throws an OutOfMemoryError >> >> That statement was true when soft references were first introduced in >> java 1.2, but from java 1.3.1 the jvm property >> `-XX:SoftRefLRUPolicyMSPerMB` was introduced. That statement is still true. When the GC gets into a situation where it is having trouble satisfying an allocation, then SoftRefLRUPolicyMSPerMB will be ignored and all soft references will be cleared, before the GC gives up and throws an OOME. >> It defaults to 1000 (milliseconds), meaning that if there?s only 10MB >> available heap, the garbage collector will free references that have >> been used more than 10s ago. I.e. everything else (including young >> softly reachable objects) will *not* be freed, leading to an >> OutOfMemoryError, contradicting the above quoted 'guarantee'. >> >> That's also the behaviour I observed on various JREs. Would you agree, >> i.e. should I propose an updated doc? Could you elaborate on what kind of test you did to come to this conclusion? Preferably provide a re-producer. In OOME situations, if a SoftReference isn't cleared, it is typically because you have unknowingly made it strongly reachable. cheers, Per From lenborje at gmail.com Tue Apr 16 07:05:12 2019 From: lenborje at gmail.com (=?utf-8?Q?Lennart_B=C3=B6rjeson?=) Date: Tue, 16 Apr 2019 09:05:12 +0200 Subject: ZipFileSystem performance regression In-Reply-To: <9324e5c2-0055-df69-d2c6-c3f3c1087cfa@oracle.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9324e5c2-0055-df69-d2c6-c3f3c1087cfa@oracle.com> Message-ID: <4BD18119-2697-4182-B446-1CBD41CD3BF0@gmail.com> Very good, thank you! Also note that the "new" implementation also requires *a lot* more heap, since all *uncompressed* file content is copied to the heap before deflating. Best regards, /Lennart B?rjeson > 15 apr. 2019 kl. 18:34 skrev Claes Redestad : > > Hi Lennart, > > I can reproduce this locally, and have narrowed down to > https://bugs.openjdk.java.net/browse/JDK-8034802 as the cause. > > As you say the compression is deferred to ZipFileSystem.close() now, > whereas previously it happened eagerly. We will have to analyze the > changes more in-depth to try and see why this is the case. > > Thanks! > > /Claes > > On 2019-04-15 15:32, Lennart B?rjeson wrote: >> I have made a small command-line utility which creates zip archives by compressing the input files in parallel. >> I do this by calling Files.copy(input, zipOutputStream) in a parallel Stream over all input files. >> I have run this with Java 1.8, 9, 10, and 11, on both my local laptop and on server-class machines with up to 40 cores. >> It scales rather well and I get the expected speedup, i.e. roughly proportional to the number of cores. >> With OpenJDK 12, however, I get no speedup whatsoever. My understanding is that in JDK 12, the copy method simply >> transfers the contents of the input stream to a ByteArrayOutputStream, which is then deflated when I close the ZipFileSystem (by the ZipFileSystem.sync() method). >> Previously, the deflation was done when in the call to Files.copy, thus executed in parallel, and the final ZipFileSystem.close() didn't do anything much. >> (But I may of course be wrong. In case there's a simpler explanation and something I can remedy in my code, please let me know.) >> I have a small GitHub gist for the utility here: https://gist.github.com/lenborje/6d2f92430abe4ba881e3c5ff83736923 >> Steps to reproduce (timings on my 8-core MacBook Pro): >> 1) Get the contents of the gist as a single file, Zip.java >> 2) Compile it using Java 8. >> $ export JAVA_HOME= >> $ javac -encoding utf8 Zip.java >> 3) run on a sufficiently large number of files to exercise the parallelity: (I've used about 70 text files ca 60MB each) >> $ time java -Xmx6g Zip -p /tmp/test.zip /*.log. >> Working on ZIP FileSystem jar:file:/tmp/test.zip, using the options [PARALLEL] >> ... >> completed zip archive, now closing... done! >> real 0m35.558s >> user 3m58.134s >> sys 0m5.543s >> As is evident from the ratio between "user time" and "real time", all cores have been busy most of the time. >> (Running with JDK 9, 10, and 11 produces similar timings.) >> But running with JDK 12 defeats the parallelism: >> $ export JAVA_HOME= >> $ rm /tmp/test.zip # From previous run >> $ time java -Xmx6g Zip -p /tmp/test.zip /*.log. >> Working on ZIP FileSystem jar:file:/tmp/test.zip, using the options [PARALLEL] >> ... >> completed zip archive, now closing... done! >> real 3m1.187s >> user 3m5.422s >> sys 0m12.396s >> Now there's almost no speedup. When observing the output, note that the ZipFileSystem.close() method is called immediately after the "now closing..." output, and "Done!" Is written when it returns, and when running with JDK 12 almost all running time is apparently spent there. >> I'm hoping the previous behaviour could somehow be restored, i.e. that deflation actually happens when I'm copying the input files to the ZipFileSystem, and not when I close it. >> Best regards, >> /Lennart B?rjeson >>> 12 apr. 2019 kl. 14:25 skrev Lennart B?rjeson : >>> >>> I've found what I believe is a rather severe performance regression in ZipFileSystem. 1.8 and 11 runs OK, 12 does not. >>> >>> Is this the right forum to report such issues? >>> >>> Best regards, >>> >>> /Lennart B?rjeson From christoph.langer at sap.com Tue Apr 16 07:17:28 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Tue, 16 Apr 2019 07:17:28 +0000 Subject: ZipFileSystem performance regression In-Reply-To: <4BD18119-2697-4182-B446-1CBD41CD3BF0@gmail.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9324e5c2-0055-df69-d2c6-c3f3c1087cfa@oracle.com> <4BD18119-2697-4182-B446-1CBD41CD3BF0@gmail.com> Message-ID: Hi Claes, will you open a bug for this? Thanks Christoph > -----Original Message----- > From: core-libs-dev On Behalf > Of Lennart B?rjeson > Sent: Dienstag, 16. April 2019 09:05 > To: Claes Redestad > Cc: core-libs-dev at openjdk.java.net > Subject: Re: ZipFileSystem performance regression > > Very good, thank you! > > Also note that the "new" implementation also requires *a lot* more heap, > since all *uncompressed* file content is copied to the heap before deflating. > > Best regards, > > /Lennart B?rjeson > > > 15 apr. 2019 kl. 18:34 skrev Claes Redestad : > > > > Hi Lennart, > > > > I can reproduce this locally, and have narrowed down to > > https://bugs.openjdk.java.net/browse/JDK-8034802 as the cause. > > > > As you say the compression is deferred to ZipFileSystem.close() now, > > whereas previously it happened eagerly. We will have to analyze the > > changes more in-depth to try and see why this is the case. > > > > Thanks! > > > > /Claes > > > > On 2019-04-15 15:32, Lennart B?rjeson wrote: > >> I have made a small command-line utility which creates zip archives by > compressing the input files in parallel. > >> I do this by calling Files.copy(input, zipOutputStream) in a parallel Stream > over all input files. > >> I have run this with Java 1.8, 9, 10, and 11, on both my local laptop and on > server-class machines with up to 40 cores. > >> It scales rather well and I get the expected speedup, i.e. roughly > proportional to the number of cores. > >> With OpenJDK 12, however, I get no speedup whatsoever. My > understanding is that in JDK 12, the copy method simply > >> transfers the contents of the input stream to a ByteArrayOutputStream, > which is then deflated when I close the ZipFileSystem (by the > ZipFileSystem.sync() method). > >> Previously, the deflation was done when in the call to Files.copy, thus > executed in parallel, and the final ZipFileSystem.close() didn't do anything > much. > >> (But I may of course be wrong. In case there's a simpler explanation and > something I can remedy in my code, please let me know.) > >> I have a small GitHub gist for the utility here: > https://gist.github.com/lenborje/6d2f92430abe4ba881e3c5ff83736923 > > >> Steps to reproduce (timings on my 8-core MacBook Pro): > >> 1) Get the contents of the gist as a single file, Zip.java > >> 2) Compile it using Java 8. > >> $ export JAVA_HOME= > >> $ javac -encoding utf8 Zip.java > >> 3) run on a sufficiently large number of files to exercise the parallelity: > (I've used about 70 text files ca 60MB each) > >> $ time java -Xmx6g Zip -p /tmp/test.zip /*.log. > >> Working on ZIP FileSystem jar:file:/tmp/test.zip, using the options > [PARALLEL] > >> ... > >> completed zip archive, now closing... done! > >> real 0m35.558s > >> user 3m58.134s > >> sys 0m5.543s > >> As is evident from the ratio between "user time" and "real time", all cores > have been busy most of the time. > >> (Running with JDK 9, 10, and 11 produces similar timings.) > >> But running with JDK 12 defeats the parallelism: > >> $ export JAVA_HOME= > >> $ rm /tmp/test.zip # From previous run > >> $ time java -Xmx6g Zip -p /tmp/test.zip /*.log. > >> Working on ZIP FileSystem jar:file:/tmp/test.zip, using the options > [PARALLEL] > >> ... > >> completed zip archive, now closing... done! > >> real 3m1.187s > >> user 3m5.422s > >> sys 0m12.396s > >> Now there's almost no speedup. When observing the output, note that > the ZipFileSystem.close() method is called immediately after the "now > closing..." output, and "Done!" Is written when it returns, and when running > with JDK 12 almost all running time is apparently spent there. > >> I'm hoping the previous behaviour could somehow be restored, i.e. that > deflation actually happens when I'm copying the input files to the > ZipFileSystem, and not when I close it. > >> Best regards, > >> /Lennart B?rjeson > >>> 12 apr. 2019 kl. 14:25 skrev Lennart B?rjeson : > >>> > >>> I've found what I believe is a rather severe performance regression in > ZipFileSystem. 1.8 and 11 runs OK, 12 does not. > >>> > >>> Is this the right forum to report such issues? > >>> > >>> Best regards, > >>> > >>> /Lennart B?rjeson From Alan.Bateman at oracle.com Tue Apr 16 07:29:12 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 16 Apr 2019 08:29:12 +0100 Subject: ZipFileSystem performance regression In-Reply-To: <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> Message-ID: <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> On 15/04/2019 14:32, Lennart B?rjeson wrote: > : > > Previously, the deflation was done when in the call to Files.copy, thus executed in parallel, and the final ZipFileSystem.close() didn't do anything much. > Can you submit a bug? When creating/updating a zip file with zipfs then the closing the file system creates the zip file. Someone needs to check but it may have been that the temporary files (on the file system hosting the zip file) were deflated when writing (which is surprising but may have been the case). -Alan From Alan.Bateman at oracle.com Tue Apr 16 07:40:38 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 16 Apr 2019 08:40:38 +0100 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: <5f228dd6-adae-dc59-e712-46a6d2982ae8@oracle.com> References: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> <4b1221a9-fce2-d708-8ea5-084c891c4765@oracle.com> <5f228dd6-adae-dc59-e712-46a6d2982ae8@oracle.com> Message-ID: <24cc4575-60c1-d654-4847-5191fddb4817@oracle.com> On 15/04/2019 08:48, David Holmes wrote: > On 15/04/2019 5:34 pm, Patrick Zhang OS wrote: >> Removed it. >> http://cr.openjdk.java.net/~qpzhang/8222334/webrev.03/jdk.changeset >> >> By the way, could you please sponsor to push it once approved? thanks >> in advance. > > Sure - if the core-libs person who also reviews doesn't volunteer > (hint hint ;-) ) This looks okay to me too, I think we should fix the intention in ContinueInNewThread while we are there so it matches the rest of the file. -Alan From david.holmes at oracle.com Tue Apr 16 07:47:01 2019 From: david.holmes at oracle.com (David Holmes) Date: Tue, 16 Apr 2019 17:47:01 +1000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: <24cc4575-60c1-d654-4847-5191fddb4817@oracle.com> References: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> <4b1221a9-fce2-d708-8ea5-084c891c4765@oracle.com> <5f228dd6-adae-dc59-e712-46a6d2982ae8@oracle.com> <24cc4575-60c1-d654-4847-5191fddb4817@oracle.com> Message-ID: <16e97060-4bb6-cff5-fb45-940dd7852184@oracle.com> On 16/04/2019 5:40 pm, Alan Bateman wrote: > On 15/04/2019 08:48, David Holmes wrote: >> On 15/04/2019 5:34 pm, Patrick Zhang OS wrote: >>> Removed it. >>> http://cr.openjdk.java.net/~qpzhang/8222334/webrev.03/jdk.changeset >>> >>> By the way, could you please sponsor to push it once approved? thanks >>> in advance. >> >> Sure - if the core-libs person who also reviews doesn't volunteer >> (hint hint ;-) ) > This looks okay to me too, I think we should fix the intention in > ContinueInNewThread while we are there so it matches the rest of the file. Thanks Alan! I'll fix the indent before pushing. David ----- > -Alan From david.holmes at oracle.com Tue Apr 16 08:17:18 2019 From: david.holmes at oracle.com (David Holmes) Date: Tue, 16 Apr 2019 18:17:18 +1000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: <16e97060-4bb6-cff5-fb45-940dd7852184@oracle.com> References: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> <4b1221a9-fce2-d708-8ea5-084c891c4765@oracle.com> <5f228dd6-adae-dc59-e712-46a6d2982ae8@oracle.com> <24cc4575-60c1-d654-4847-5191fddb4817@oracle.com> <16e97060-4bb6-cff5-fb45-940dd7852184@oracle.com> Message-ID: Patrick, Sorry should have picked up on this earlier. Can you please update the following two tests to add a test for '0' as appropriate: ./jdk/tools/launcher/TooSmallStackSize.java ./hotspot/jtreg/runtime/Thread/TooSmallStackSize.java Thanks, David On 16/04/2019 5:47 pm, David Holmes wrote: > On 16/04/2019 5:40 pm, Alan Bateman wrote: >> On 15/04/2019 08:48, David Holmes wrote: >>> On 15/04/2019 5:34 pm, Patrick Zhang OS wrote: >>>> Removed it. >>>> http://cr.openjdk.java.net/~qpzhang/8222334/webrev.03/jdk.changeset >>>> >>>> By the way, could you please sponsor to push it once approved? >>>> thanks in advance. >>> >>> Sure - if the core-libs person who also reviews doesn't volunteer >>> (hint hint ;-) ) >> This looks okay to me too, I think we should fix the intention in >> ContinueInNewThread while we are there so it matches the rest of the >> file. > > Thanks Alan! I'll fix the indent before pushing. > > David > ----- > >> -Alan From patrick at os.amperecomputing.com Tue Apr 16 08:23:08 2019 From: patrick at os.amperecomputing.com (Patrick Zhang OS) Date: Tue, 16 Apr 2019 08:23:08 +0000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: References: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> <4b1221a9-fce2-d708-8ea5-084c891c4765@oracle.com> <5f228dd6-adae-dc59-e712-46a6d2982ae8@oracle.com> <24cc4575-60c1-d654-4847-5191fddb4817@oracle.com> <16e97060-4bb6-cff5-fb45-940dd7852184@oracle.com> Message-ID: Sure I will add this, and fix the intention mentioned by Alan. Regards Patrick -----Original Message----- From: David Holmes Sent: Tuesday, April 16, 2019 4:17 PM To: Patrick Zhang OS Cc: Alan Bateman ; core-libs-dev Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError Patrick, Sorry should have picked up on this earlier. Can you please update the following two tests to add a test for '0' as appropriate: ./jdk/tools/launcher/TooSmallStackSize.java ./hotspot/jtreg/runtime/Thread/TooSmallStackSize.java Thanks, David On 16/04/2019 5:47 pm, David Holmes wrote: > On 16/04/2019 5:40 pm, Alan Bateman wrote: >> On 15/04/2019 08:48, David Holmes wrote: >>> On 15/04/2019 5:34 pm, Patrick Zhang OS wrote: >>>> Removed it. >>>> http://cr.openjdk.java.net/~qpzhang/8222334/webrev.03/jdk.changeset >>>> >>>> By the way, could you please sponsor to push it once approved? >>>> thanks in advance. >>> >>> Sure - if the core-libs person who also reviews doesn't volunteer >>> (hint hint ;-) ) >> This looks okay to me too, I think we should fix the intention in >> ContinueInNewThread while we are there so it matches the rest of the >> file. > > Thanks Alan! I'll fix the indent before pushing. > > David > ----- > >> -Alan From patrick at os.amperecomputing.com Tue Apr 16 09:42:58 2019 From: patrick at os.amperecomputing.com (Patrick Zhang OS) Date: Tue, 16 Apr 2019 09:42:58 +0000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: References: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> <4b1221a9-fce2-d708-8ea5-084c891c4765@oracle.com> <5f228dd6-adae-dc59-e712-46a6d2982ae8@oracle.com> <24cc4575-60c1-d654-4847-5191fddb4817@oracle.com> <16e97060-4bb6-cff5-fb45-940dd7852184@oracle.com> Message-ID: Hi David, Please see my updates, the two '0' size test cases. I have run them with jtreg on jdk13 + linux + x86/aarch64 systems respectively, all passed. http://cr.openjdk.java.net/~qpzhang/8222334/webrev.04 Regards Patrick -----Original Message----- From: core-libs-dev On Behalf Of Patrick Zhang OS Sent: Tuesday, April 16, 2019 4:23 PM To: David Holmes Cc: core-libs-dev Subject: RE: RFR: 8222334: java -Xss0 triggers StackOverflowError Sure I will add this, and fix the intention mentioned by Alan. Regards Patrick -----Original Message----- From: David Holmes Sent: Tuesday, April 16, 2019 4:17 PM To: Patrick Zhang OS Cc: Alan Bateman ; core-libs-dev Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError Patrick, Sorry should have picked up on this earlier. Can you please update the following two tests to add a test for '0' as appropriate: ./jdk/tools/launcher/TooSmallStackSize.java ./hotspot/jtreg/runtime/Thread/TooSmallStackSize.java Thanks, David On 16/04/2019 5:47 pm, David Holmes wrote: > On 16/04/2019 5:40 pm, Alan Bateman wrote: >> On 15/04/2019 08:48, David Holmes wrote: >>> On 15/04/2019 5:34 pm, Patrick Zhang OS wrote: >>>> Removed it. >>>> http://cr.openjdk.java.net/~qpzhang/8222334/webrev.03/jdk.changeset >>>> >>>> By the way, could you please sponsor to push it once approved? >>>> thanks in advance. >>> >>> Sure - if the core-libs person who also reviews doesn't volunteer >>> (hint hint ;-) ) >> This looks okay to me too, I think we should fix the intention in >> ContinueInNewThread while we are there so it matches the rest of the >> file. > > Thanks Alan! I'll fix the indent before pushing. > > David > ----- > >> -Alan From david.holmes at oracle.com Tue Apr 16 10:33:43 2019 From: david.holmes at oracle.com (David Holmes) Date: Tue, 16 Apr 2019 20:33:43 +1000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: References: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> <4b1221a9-fce2-d708-8ea5-084c891c4765@oracle.com> <5f228dd6-adae-dc59-e712-46a6d2982ae8@oracle.com> <24cc4575-60c1-d654-4847-5191fddb4817@oracle.com> <16e97060-4bb6-cff5-fb45-940dd7852184@oracle.com> Message-ID: Hi Patrick, On 16/04/2019 7:42 pm, Patrick Zhang OS wrote: > Hi David, > Please see my updates, the two '0' size test cases. I have run them with jtreg on jdk13 + linux + x86/aarch64 systems respectively, all passed. > http://cr.openjdk.java.net/~qpzhang/8222334/webrev.04 Thanks. Please update copyright years. Also instead of this comment: It can verify the issue fixed in 8222334. Just add 8222334 to the @bug line. Thanks, David > Regards > Patrick > > -----Original Message----- > From: core-libs-dev On Behalf Of Patrick Zhang OS > Sent: Tuesday, April 16, 2019 4:23 PM > To: David Holmes > Cc: core-libs-dev > Subject: RE: RFR: 8222334: java -Xss0 triggers StackOverflowError > > Sure I will add this, and fix the intention mentioned by Alan. > > Regards > Patrick > > -----Original Message----- > From: David Holmes > Sent: Tuesday, April 16, 2019 4:17 PM > To: Patrick Zhang OS > Cc: Alan Bateman ; core-libs-dev > Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError > > Patrick, > > Sorry should have picked up on this earlier. Can you please update the following two tests to add a test for '0' as appropriate: > > ./jdk/tools/launcher/TooSmallStackSize.java > ./hotspot/jtreg/runtime/Thread/TooSmallStackSize.java > > Thanks, > David > > On 16/04/2019 5:47 pm, David Holmes wrote: >> On 16/04/2019 5:40 pm, Alan Bateman wrote: >>> On 15/04/2019 08:48, David Holmes wrote: >>>> On 15/04/2019 5:34 pm, Patrick Zhang OS wrote: >>>>> Removed it. >>>>> http://cr.openjdk.java.net/~qpzhang/8222334/webrev.03/jdk.changeset >>>>> >>>>> By the way, could you please sponsor to push it once approved? >>>>> thanks in advance. >>>> >>>> Sure - if the core-libs person who also reviews doesn't volunteer >>>> (hint hint ;-) ) >>> This looks okay to me too, I think we should fix the intention in >>> ContinueInNewThread while we are there so it matches the rest of the >>> file. >> >> Thanks Alan! I'll fix the indent before pushing. >> >> David >> ----- >> >>> -Alan From patrick at os.amperecomputing.com Tue Apr 16 10:44:43 2019 From: patrick at os.amperecomputing.com (Patrick Zhang OS) Date: Tue, 16 Apr 2019 10:44:43 +0000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: References: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> <4b1221a9-fce2-d708-8ea5-084c891c4765@oracle.com> <5f228dd6-adae-dc59-e712-46a6d2982ae8@oracle.com> <24cc4575-60c1-d654-4847-5191fddb4817@oracle.com> <16e97060-4bb6-cff5-fb45-940dd7852184@oracle.com> Message-ID: Done. http://cr.openjdk.java.net/~qpzhang/8222334/webrev.05 Regards Patrick -----Original Message----- From: David Holmes Sent: Tuesday, April 16, 2019 6:34 PM To: Patrick Zhang OS Cc: core-libs-dev Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError Hi Patrick, On 16/04/2019 7:42 pm, Patrick Zhang OS wrote: > Hi David, > Please see my updates, the two '0' size test cases. I have run them with jtreg on jdk13 + linux + x86/aarch64 systems respectively, all passed. > http://cr.openjdk.java.net/~qpzhang/8222334/webrev.04 Thanks. Please update copyright years. Also instead of this comment: It can verify the issue fixed in 8222334. Just add 8222334 to the @bug line. Thanks, David > Regards > Patrick > > -----Original Message----- > From: core-libs-dev On Behalf > Of Patrick Zhang OS > Sent: Tuesday, April 16, 2019 4:23 PM > To: David Holmes > Cc: core-libs-dev > Subject: RE: RFR: 8222334: java -Xss0 triggers StackOverflowError > > Sure I will add this, and fix the intention mentioned by Alan. > > Regards > Patrick > > -----Original Message----- > From: David Holmes > Sent: Tuesday, April 16, 2019 4:17 PM > To: Patrick Zhang OS > Cc: Alan Bateman ; core-libs-dev > > Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError > > Patrick, > > Sorry should have picked up on this earlier. Can you please update the following two tests to add a test for '0' as appropriate: > > ./jdk/tools/launcher/TooSmallStackSize.java > ./hotspot/jtreg/runtime/Thread/TooSmallStackSize.java > > Thanks, > David > > On 16/04/2019 5:47 pm, David Holmes wrote: >> On 16/04/2019 5:40 pm, Alan Bateman wrote: >>> On 15/04/2019 08:48, David Holmes wrote: >>>> On 15/04/2019 5:34 pm, Patrick Zhang OS wrote: >>>>> Removed it. >>>>> http://cr.openjdk.java.net/~qpzhang/8222334/webrev.03/jdk.changese >>>>> t >>>>> >>>>> By the way, could you please sponsor to push it once approved? >>>>> thanks in advance. >>>> >>>> Sure - if the core-libs person who also reviews doesn't volunteer >>>> (hint hint ;-) ) >>> This looks okay to me too, I think we should fix the intention in >>> ContinueInNewThread while we are there so it matches the rest of the >>> file. >> >> Thanks Alan! I'll fix the indent before pushing. >> >> David >> ----- >> >>> -Alan From david.holmes at oracle.com Tue Apr 16 11:01:44 2019 From: david.holmes at oracle.com (David Holmes) Date: Tue, 16 Apr 2019 21:01:44 +1000 Subject: RFR: 8222334: java -Xss0 triggers StackOverflowError In-Reply-To: References: <3d48fc6d-95ae-e6ee-6bec-c02b483dc0b1@oracle.com> <49278a02-333f-54f7-e0d7-e614bc77781c@oracle.com> <4b1221a9-fce2-d708-8ea5-084c891c4765@oracle.com> <5f228dd6-adae-dc59-e712-46a6d2982ae8@oracle.com> <24cc4575-60c1-d654-4847-5191fddb4817@oracle.com> <16e97060-4bb6-cff5-fb45-940dd7852184@oracle.com> Message-ID: <7334527d-49d9-4f67-c0b7-b1d7f5373ac8@oracle.com> Thanks Patrick! Changes pushed. David On 16/04/2019 8:44 pm, Patrick Zhang OS wrote: > Done. http://cr.openjdk.java.net/~qpzhang/8222334/webrev.05 > > Regards > Patrick > > -----Original Message----- > From: David Holmes > Sent: Tuesday, April 16, 2019 6:34 PM > To: Patrick Zhang OS > Cc: core-libs-dev > Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError > > Hi Patrick, > > On 16/04/2019 7:42 pm, Patrick Zhang OS wrote: >> Hi David, >> Please see my updates, the two '0' size test cases. I have run them with jtreg on jdk13 + linux + x86/aarch64 systems respectively, all passed. >> http://cr.openjdk.java.net/~qpzhang/8222334/webrev.04 > > Thanks. Please update copyright years. Also instead of this comment: > > It can verify the issue fixed in 8222334. > > Just add 8222334 to the @bug line. > > Thanks, > David > >> Regards >> Patrick >> >> -----Original Message----- >> From: core-libs-dev On Behalf >> Of Patrick Zhang OS >> Sent: Tuesday, April 16, 2019 4:23 PM >> To: David Holmes >> Cc: core-libs-dev >> Subject: RE: RFR: 8222334: java -Xss0 triggers StackOverflowError >> >> Sure I will add this, and fix the intention mentioned by Alan. >> >> Regards >> Patrick >> >> -----Original Message----- >> From: David Holmes >> Sent: Tuesday, April 16, 2019 4:17 PM >> To: Patrick Zhang OS >> Cc: Alan Bateman ; core-libs-dev >> >> Subject: Re: RFR: 8222334: java -Xss0 triggers StackOverflowError >> >> Patrick, >> >> Sorry should have picked up on this earlier. Can you please update the following two tests to add a test for '0' as appropriate: >> >> ./jdk/tools/launcher/TooSmallStackSize.java >> ./hotspot/jtreg/runtime/Thread/TooSmallStackSize.java >> >> Thanks, >> David >> >> On 16/04/2019 5:47 pm, David Holmes wrote: >>> On 16/04/2019 5:40 pm, Alan Bateman wrote: >>>> On 15/04/2019 08:48, David Holmes wrote: >>>>> On 15/04/2019 5:34 pm, Patrick Zhang OS wrote: >>>>>> Removed it. >>>>>> http://cr.openjdk.java.net/~qpzhang/8222334/webrev.03/jdk.changese >>>>>> t >>>>>> >>>>>> By the way, could you please sponsor to push it once approved? >>>>>> thanks in advance. >>>>> >>>>> Sure - if the core-libs person who also reviews doesn't volunteer >>>>> (hint hint ;-) ) >>>> This looks okay to me too, I think we should fix the intention in >>>> ContinueInNewThread while we are there so it matches the rest of the >>>> file. >>> >>> Thanks Alan! I'll fix the indent before pushing. >>> >>> David >>> ----- >>> >>>> -Alan From claes.redestad at oracle.com Tue Apr 16 12:21:53 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 16 Apr 2019 14:21:53 +0200 Subject: ZipFileSystem performance regression In-Reply-To: <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> Message-ID: <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> Both before and after this regression, it seems the default behavior is not to use a temporary file (until ZFS.sync(), which writes to a temp file and then moves it in place, but that's different from what happens with the useTempFile option enabled). Instead entries (and the backing zip file system) are kept in-memory. The cause of the issue here is instead that no deflation happens until sync(), even when writing to entries in-memory. Previously, the deflation happened eagerly, then the result of that was copied into the zip file during sync(). I've written a proof-of-concept patch that restores the behavior of eagerly compressing entries when the method is METHOD_DEFLATED and the target is to store byte[]s in-memory (the default scenario): http://cr.openjdk.java.net/~redestad/scratch/zfs.eager_deflation.00/ This restores performance of parallel zip to that of 11.0.2 for the default case. It still has a similar regression for the case where useTempFile is enabled, but that should be easily addressed if this looks like a way forward? (I've not yet created a bug as I got too caught up in trying to figure out what was going on here...) Thanks! /Claes On 2019-04-16 09:29, Alan Bateman wrote: > On 15/04/2019 14:32, Lennart B?rjeson wrote: >> : >> >> Previously, the deflation was done when in the call to Files.copy, >> thus executed in parallel, and the final ZipFileSystem.close() didn't >> do anything much. >> > Can you submit a bug? When creating/updating a zip file with zipfs then > the closing the file system creates the zip file. Someone needs to check > but it may have been that the temporary files (on the file system > hosting the zip file) were deflated when writing (which is surprising > but may have been the case). > > -Alan From claes.redestad at oracle.com Tue Apr 16 14:15:30 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 16 Apr 2019 16:15:30 +0200 Subject: ZipFileSystem performance regression In-Reply-To: <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> Message-ID: Filed: https://bugs.openjdk.java.net/browse/JDK-8222532 I've marked the bug as potentially affecting the upcoming 11.0.3 release, since the issue that caused this regression is purportedly being backported to that version. /Claes On 2019-04-16 14:21, Claes Redestad wrote: > Both before and after this regression, it seems the default behavior is > not to use a temporary file (until ZFS.sync(), which writes to a temp > file and then moves it in place, but that's different from what happens > with the useTempFile option enabled). Instead entries (and the backing > zip file system) are kept in-memory. > > The cause of the issue here is instead that no deflation happens until > sync(), even when writing to entries in-memory. Previously, the > deflation happened eagerly, then the result of that was copied into > the zip file during sync(). > > I've written a proof-of-concept patch that restores the behavior of > eagerly compressing entries when the method is METHOD_DEFLATED and the > target is to store byte[]s in-memory (the default scenario): > > http://cr.openjdk.java.net/~redestad/scratch/zfs.eager_deflation.00/ > > This restores performance of parallel zip to that of 11.0.2 for the > default case. It still has a similar regression for the case where > useTempFile is enabled, but that should be easily addressed if this > looks like a way forward? > > (I've not yet created a bug as I got too caught up in trying to figure > out what was going on here...) > > Thanks! > > /Claes > > On 2019-04-16 09:29, Alan Bateman wrote: >> On 15/04/2019 14:32, Lennart B?rjeson wrote: >>> : >>> >>> Previously, the deflation was done when in the call to Files.copy, >>> thus executed in parallel, and the final ZipFileSystem.close() didn't >>> do anything much. >>> >> Can you submit a bug? When creating/updating a zip file with zipfs >> then the closing the file system creates the zip file. Someone needs >> to check but it may have been that the temporary files (on the file >> system hosting the zip file) were deflated when writing (which is >> surprising but may have been the case). >> >> -Alan From semyon.sadetsky at oracle.com Tue Apr 16 19:18:53 2019 From: semyon.sadetsky at oracle.com (semyon.sadetsky at oracle.com) Date: Tue, 16 Apr 2019 12:18:53 -0700 Subject: RFE: JDK-8217895: jpackage --identifier purpose In-Reply-To: References: <4c709612-5350-884a-6c80-9fd5a470f8b0@oracle.com> <6b759662-1d4a-99e7-e02e-ade3881491be@oracle.com> Message-ID: <52247781-2e84-fb72-e348-ee40e3c79849@oracle.com> On 4/12/19 4:51 AM, Andy Herrick wrote: > > On 4/11/2019 6:06 PM, semyon.sadetsky at oracle.com wrote: >> >> On 4/11/19 12:05 PM, Andy Herrick wrote: >>> Please review the jpackage fix for bug [1] at [2]. >>> >>> This is a fix for the JDK-8200758-branch branch of the open sandbox >>> repository (jpackage). >>> >>> [1] https://bugs.openjdk.java.net/browse/JDK-8217895 >>> >>> [2] http://cr.openjdk.java.net/~herrick/8217895/ >> Andy, >> >> Can I ask you to explain why your fix modifies so many files while >> the bug requests a change in help texts? >> Shouldn't it be a change in the property bundle? What are those other >> changes? > The bug also requests "reducing --identifier option's unused impact". > Part of that (as described in the bugs comments) is that > "app.preferences.id" was written into the cfg file and used by the > native code for functionality no longer present (using the files > generated and read by the preferences api). > Another part of that was native code to handle the (now obsolete) old > form of the cfg file (as a java properties file). > I will add comment in JBS to describe the changes more explicitly. Ok, thanks. Looks good to me then. --Semyon > > /Andy >> >> --Semyon >>> >>> /Andy >>> >> > From xueming.shen at gmail.com Tue Apr 16 19:44:01 2019 From: xueming.shen at gmail.com (Xueming Shen) Date: Tue, 16 Apr 2019 12:44:01 -0700 Subject: ZipFileSystem performance regression In-Reply-To: <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> Message-ID: One of the motivations back then is to speed up the performance of accessing those entries, means you don't have to deflate/inflate those new/updated entries during the lifetime of that zipfilesystem. Those updated entries only get compressed when go to storage. So the regression is more like a trade off of performance of different usages. (it also simplifies the logic on handing different types of entries ...) One idea I experimented long time ago for jartool is to concurrently write out entries when need compression ... it does gain some performance improvement on multi-cores, but not lots, as it ends up coming back to the main thread to write out to the underlying filesystem. -Sherman On 4/16/19 5:21 AM, Claes Redestad wrote: > Both before and after this regression, it seems the default behavior is > not to use a temporary file (until ZFS.sync(), which writes to a temp > file and then moves it in place, but that's different from what happens > with the useTempFile option enabled). Instead entries (and the backing > zip file system) are kept in-memory. > > The cause of the issue here is instead that no deflation happens until > sync(), even when writing to entries in-memory. Previously, the > deflation happened eagerly, then the result of that was copied into > the zip file during sync(). > > I've written a proof-of-concept patch that restores the behavior of > eagerly compressing entries when the method is METHOD_DEFLATED and the > target is to store byte[]s in-memory (the default scenario): > > http://cr.openjdk.java.net/~redestad/scratch/zfs.eager_deflation.00/ > > This restores performance of parallel zip to that of 11.0.2 for the > default case. It still has a similar regression for the case where > useTempFile is enabled, but that should be easily addressed if this > looks like a way forward? > > (I've not yet created a bug as I got too caught up in trying to figure > out what was going on here...) > > Thanks! > > /Claes > > On 2019-04-16 09:29, Alan Bateman wrote: >> On 15/04/2019 14:32, Lennart B?rjeson wrote: >>> : >>> >>> Previously, the deflation was done when in the call to Files.copy, >>> thus executed in parallel, and the final ZipFileSystem.close() >>> didn't do anything much. >>> >> Can you submit a bug? When creating/updating a zip file with zipfs >> then the closing the file system creates the zip file. Someone needs >> to check but it may have been that the temporary files (on the file >> system hosting the zip file) were deflated when writing (which is >> surprising but may have been the case). >> >> -Alan From lenborje at gmail.com Tue Apr 16 19:54:44 2019 From: lenborje at gmail.com (=?utf-8?Q?Lennart_B=C3=B6rjeson?=) Date: Tue, 16 Apr 2019 21:54:44 +0200 Subject: ZipFileSystem performance regression In-Reply-To: References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> Message-ID: <680D03D1-9631-45DA-A89A-6EEDBC63EACE@gmail.com> I?m using the tool I wrote to compress directories with thousands of log files. The standard zip utility (as well as my utility when run with JDK 12) takes up to an hour of user time to create the archive, on our server class 40+ core servers this is reduced to 1?2 minutes. So while I understand the motivation for the change, I don?t get why you would want to use ZipFs for what in essence is a RAM disk, *unless* you want it compressed in memory? Oh well. Do we need a new option for this? /Lennart B?rjeson Electrogramma ab iPhono meo missum est > 16 apr. 2019 kl. 21:44 skrev Xueming Shen : > > One of the motivations back then is to speed up the performance of accessing > > those entries, means you don't have to deflate/inflate those new/updated entries > > during the lifetime of that zipfilesystem. Those updated entries only get compressed > > when go to storage. So the regression is more like a trade off of performance of > > different usages. (it also simplifies the logic on handing different types of entries ...) > > > One idea I experimented long time ago for jartool is to concurrently write out > > entries when need compression ... it does gain some performance improvement > > on multi-cores, but not lots, as it ends up coming back to the main thread to > > write out to the underlying filesystem. > > > -Sherman > >> On 4/16/19 5:21 AM, Claes Redestad wrote: >> Both before and after this regression, it seems the default behavior is >> not to use a temporary file (until ZFS.sync(), which writes to a temp >> file and then moves it in place, but that's different from what happens >> with the useTempFile option enabled). Instead entries (and the backing >> zip file system) are kept in-memory. >> >> The cause of the issue here is instead that no deflation happens until >> sync(), even when writing to entries in-memory. Previously, the >> deflation happened eagerly, then the result of that was copied into >> the zip file during sync(). >> >> I've written a proof-of-concept patch that restores the behavior of >> eagerly compressing entries when the method is METHOD_DEFLATED and the >> target is to store byte[]s in-memory (the default scenario): >> >> http://cr.openjdk.java.net/~redestad/scratch/zfs.eager_deflation.00/ >> >> This restores performance of parallel zip to that of 11.0.2 for the >> default case. It still has a similar regression for the case where >> useTempFile is enabled, but that should be easily addressed if this >> looks like a way forward? >> >> (I've not yet created a bug as I got too caught up in trying to figure >> out what was going on here...) >> >> Thanks! >> >> /Claes >> >>> On 2019-04-16 09:29, Alan Bateman wrote: >>>> On 15/04/2019 14:32, Lennart B?rjeson wrote: >>>> : >>>> >>>> Previously, the deflation was done when in the call to Files.copy, thus executed in parallel, and the final ZipFileSystem.close() didn't do anything much. >>>> >>> Can you submit a bug? When creating/updating a zip file with zipfs then the closing the file system creates the zip file. Someone needs to check but it may have been that the temporary files (on the file system hosting the zip file) were deflated when writing (which is surprising but may have been the case). >>> >>> -Alan From claes.redestad at oracle.com Tue Apr 16 20:12:51 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 16 Apr 2019 22:12:51 +0200 Subject: ZipFileSystem performance regression In-Reply-To: <680D03D1-9631-45DA-A89A-6EEDBC63EACE@gmail.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> <680D03D1-9631-45DA-A89A-6EEDBC63EACE@gmail.com> Message-ID: <050a294b-12b6-0528-db21-456272361e34@oracle.com> I think this behavior should be reverted and if the new behavior something that should be opt-in via an option, if at all. Intrusive behavior changes like this should at the very least have been signalled via a clear, standalone CSR and not buried in what looked like a bug fix. /Claes On 2019-04-16 21:54, Lennart B?rjeson wrote: > I?m using the tool I wrote to compress directories with thousands of log files. The standard zip utility (as well as my utility when run with JDK 12) takes up to an hour of user time to create the archive, on our server class 40+ core servers this is reduced to 1?2 minutes. > > So while I understand the motivation for the change, I don?t get why you would want to use ZipFs for what in essence is a RAM disk, *unless* you want it compressed in memory? > > Oh well. Do we need a new option for this? > > /Lennart B?rjeson > > Electrogramma ab iPhono meo missum est > >> 16 apr. 2019 kl. 21:44 skrev Xueming Shen : >> >> One of the motivations back then is to speed up the performance of accessing >> >> those entries, means you don't have to deflate/inflate those new/updated entries >> >> during the lifetime of that zipfilesystem. Those updated entries only get compressed >> >> when go to storage. So the regression is more like a trade off of performance of >> >> different usages. (it also simplifies the logic on handing different types of entries ...) >> >> >> One idea I experimented long time ago for jartool is to concurrently write out >> >> entries when need compression ... it does gain some performance improvement >> >> on multi-cores, but not lots, as it ends up coming back to the main thread to >> >> write out to the underlying filesystem. >> >> >> -Sherman >> >>> On 4/16/19 5:21 AM, Claes Redestad wrote: >>> Both before and after this regression, it seems the default behavior is >>> not to use a temporary file (until ZFS.sync(), which writes to a temp >>> file and then moves it in place, but that's different from what happens >>> with the useTempFile option enabled). Instead entries (and the backing >>> zip file system) are kept in-memory. >>> >>> The cause of the issue here is instead that no deflation happens until >>> sync(), even when writing to entries in-memory. Previously, the >>> deflation happened eagerly, then the result of that was copied into >>> the zip file during sync(). >>> >>> I've written a proof-of-concept patch that restores the behavior of >>> eagerly compressing entries when the method is METHOD_DEFLATED and the >>> target is to store byte[]s in-memory (the default scenario): >>> >>> http://cr.openjdk.java.net/~redestad/scratch/zfs.eager_deflation.00/ >>> >>> This restores performance of parallel zip to that of 11.0.2 for the >>> default case. It still has a similar regression for the case where >>> useTempFile is enabled, but that should be easily addressed if this >>> looks like a way forward? >>> >>> (I've not yet created a bug as I got too caught up in trying to figure >>> out what was going on here...) >>> >>> Thanks! >>> >>> /Claes >>> >>>> On 2019-04-16 09:29, Alan Bateman wrote: >>>>> On 15/04/2019 14:32, Lennart B?rjeson wrote: >>>>> : >>>>> >>>>> Previously, the deflation was done when in the call to Files.copy, thus executed in parallel, and the final ZipFileSystem.close() didn't do anything much. >>>>> >>>> Can you submit a bug? When creating/updating a zip file with zipfs then the closing the file system creates the zip file. Someone needs to check but it may have been that the temporary files (on the file system hosting the zip file) were deflated when writing (which is surprising but may have been the case). >>>> >>>> -Alan From lance.andersen at oracle.com Tue Apr 16 20:14:23 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Tue, 16 Apr 2019 16:14:23 -0400 Subject: RFR (JDK 13/java.xml) 8222415: Xerces 2.12.0: Parsing Configuration In-Reply-To: <5CB4DF7E.6030203@oracle.com> References: <5CB4DF7E.6030203@oracle.com> Message-ID: Hi Joe, Overall, I think the updates look OK. One minor correction/cleanup for before you push is in the XMLEntityManager line 3078/79 to move back the else to 3078 No need to update the webrev HTH Best Lance > On Apr 15, 2019, at 3:46 PM, Joe Wang wrote: > > Please review an update from Xerces in the configuration area. The patch contains changes not easily measurable with test (e.g. a few bytes for a parse, or small leaks for a file as large as a GB, or none at all). But the change does improve in that a method ( readAndBuffer) that explicitly buffers was provided so that the processes that required buffer all call it instead of the general read method. While there's a small test added, the testing was focused on getting the existing ones to pass. > > All XML-related tests in the core tests and JCK passed. > > JBS: https://bugs.openjdk.java.net/browse/JDK-8222415 > webrevs: http://cr.openjdk.java.net/~joehw/jdk13/8222415/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 xueming.shen at gmail.com Tue Apr 16 20:50:25 2019 From: xueming.shen at gmail.com (Xueming Shen) Date: Tue, 16 Apr 2019 13:50:25 -0700 Subject: ZipFileSystem performance regression In-Reply-To: <680D03D1-9631-45DA-A89A-6EEDBC63EACE@gmail.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> <680D03D1-9631-45DA-A89A-6EEDBC63EACE@gmail.com> Message-ID: Well, have to admitted I didn't expect your use scenario when made the change. Thought as a filesystem runtime access performance has more weight compared to shutdown performance... basically you are no using zipfs as a filesystem, but another jar tool that happens to have better in/out concurrent performance. Yes, back then I was working on using zipfs as a memory filesystem. One possible usage is that javac to use it as its filesystem (temp?) to write out compiled class files ... so I thought I can have better performance if I can keep those classes uncompressed until the zip/jarfs is closed and written to a "jar" file. That said, regression is a regression, we probably want to get the performance back for your use scenario. Just wanted to give you guys some background what happened back then. -Sherman On 4/16/19 12:54 PM, Lennart B?rjeson wrote: > I?m using the tool I wrote to compress directories with thousands of log files. The standard zip utility (as well as my utility when run with JDK 12) takes up to an hour of user time to create the archive, on our server class 40+ core servers this is reduced to 1?2 minutes. > > So while I understand the motivation for the change, I don?t get why you would want to use ZipFs for what in essence is a RAM disk, *unless* you want it compressed in memory? > > Oh well. Do we need a new option for this? > > /Lennart B?rjeson > > Electrogramma ab iPhono meo missum est > >> 16 apr. 2019 kl. 21:44 skrev Xueming Shen : >> >> One of the motivations back then is to speed up the performance of accessing >> >> those entries, means you don't have to deflate/inflate those new/updated entries >> >> during the lifetime of that zipfilesystem. Those updated entries only get compressed >> >> when go to storage. So the regression is more like a trade off of performance of >> >> different usages. (it also simplifies the logic on handing different types of entries ...) >> >> >> One idea I experimented long time ago for jartool is to concurrently write out >> >> entries when need compression ... it does gain some performance improvement >> >> on multi-cores, but not lots, as it ends up coming back to the main thread to >> >> write out to the underlying filesystem. >> >> >> -Sherman >> >>> On 4/16/19 5:21 AM, Claes Redestad wrote: >>> Both before and after this regression, it seems the default behavior is >>> not to use a temporary file (until ZFS.sync(), which writes to a temp >>> file and then moves it in place, but that's different from what happens >>> with the useTempFile option enabled). Instead entries (and the backing >>> zip file system) are kept in-memory. >>> >>> The cause of the issue here is instead that no deflation happens until >>> sync(), even when writing to entries in-memory. Previously, the >>> deflation happened eagerly, then the result of that was copied into >>> the zip file during sync(). >>> >>> I've written a proof-of-concept patch that restores the behavior of >>> eagerly compressing entries when the method is METHOD_DEFLATED and the >>> target is to store byte[]s in-memory (the default scenario): >>> >>> http://cr.openjdk.java.net/~redestad/scratch/zfs.eager_deflation.00/ >>> >>> This restores performance of parallel zip to that of 11.0.2 for the >>> default case. It still has a similar regression for the case where >>> useTempFile is enabled, but that should be easily addressed if this >>> looks like a way forward? >>> >>> (I've not yet created a bug as I got too caught up in trying to figure >>> out what was going on here...) >>> >>> Thanks! >>> >>> /Claes >>> >>>> On 2019-04-16 09:29, Alan Bateman wrote: >>>>> On 15/04/2019 14:32, Lennart B?rjeson wrote: >>>>> : >>>>> >>>>> Previously, the deflation was done when in the call to Files.copy, thus executed in parallel, and the final ZipFileSystem.close() didn't do anything much. >>>>> >>>> Can you submit a bug? When creating/updating a zip file with zipfs then the closing the file system creates the zip file. Someone needs to check but it may have been that the temporary files (on the file system hosting the zip file) were deflated when writing (which is surprising but may have been the case). >>>> >>>> -Alan From christoph.langer at sap.com Tue Apr 16 20:50:30 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Tue, 16 Apr 2019 20:50:30 +0000 Subject: RFR: 8222440: (zipfs) JarFileSystem does not correctly handle versioned entries if no root entry is present Message-ID: Hi, please review a fix for an issue with zipfs/jarfs regarding multi-release jars. The issue is observed when an mr-jar does have entries for certain files in the versioned subfolders but not in the main tree. This should be allowed as per JEP 238 [0]. So, say, if a jar file contains an entry '/META-INF/versions/11/file.txt' but not the entry 'file.txt', this will not correctly be visible when walking the jar file with jarfs. I discovered this when working on JDK-8222276 and saw a suspicious usage of IndexNode.keyOf() to create a virtual index node for the JarFileSystem lookup table. So I enhanced the test 'test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java' to demonstrate the issue. The updated test case will fail with the current coding and works with the proposed fix. Here are some details: JarFileSystem builds a lookup table to return for any jar entry its versioned entry, should it exist, in favor of the standard root entry. This is done by overriding ZipFileSystem's getInode() method and using a lookup table to return the correct versioned entry. The actual root inode is the key of this lookup table, which requires that it exists. If there is no root inode in the jar, there is code to create a virtual inode. But as it is right now, this does not work because a special singleton key node is used as virtual node which constantly changes its name. Furthermore, the node is not added to the jar file system node hierarchy. I enhanced this by correctly creating a 'virtual' root inode, making sure all parent directory inodes exist and if not creating and adding them into the jarfs/zipfs hierarchy to allow for iterating subdirectories. I also enhanced 'test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java' to demonstrate the issue. The test furthermore does not rely on files that are checked in in the source tree any longer but creates the test.jar by means of JarBuilder. I also don't delete test.jar in the test but leave it to jtreg to delete the scratch directory. That helps when analyzing test issues where scratch directory contents shall be retained. Bug: https://bugs.openjdk.java.net/browse/JDK-8222440 Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8222440.0/ Thanks in advance Christoph [0] https://openjdk.java.net/jeps/238 From christoph.langer at sap.com Tue Apr 16 21:02:07 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Tue, 16 Apr 2019 21:02:07 +0000 Subject: ZipFileSystem performance regression In-Reply-To: References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> <680D03D1-9631-45DA-A89A-6EEDBC63EACE@gmail.com> Message-ID: Hi, I also think the regression should be repaired and maybe we can have an option like "lazy compress" to avoid compression on write but defer it to zipfs closing time. It should also be possible to parallelize deflation during close, shouldn't it? Best regards Christoph > -----Original Message----- > From: core-libs-dev On Behalf > Of Xueming Shen > Sent: Dienstag, 16. April 2019 22:50 > To: Lennart B?rjeson > Cc: core-libs-dev at openjdk.java.net > Subject: Re: ZipFileSystem performance regression > > Well, have to admitted I didn't expect your use scenario when made the > change. Thought as a > > filesystem runtime access performance has more weight compared to > shutdown performance... > > basically you are no using zipfs as a filesystem, but another jar tool > that happens to have > > better in/out concurrent performance. Yes, back then I was working on > using zipfs as a memory > > filesystem. One possible usage is that javac to use it as its filesystem > (temp?) to write out compiled > > class files ... so I thought I can have better performance if I can keep > those classes uncompressed > > until the zip/jarfs is closed and written to a "jar" file. > > That said, regression is a regression, we probably want to get the > performance back for your > > use scenario. Just wanted to give you guys some background what happened > back then. > > > -Sherman > > > On 4/16/19 12:54 PM, Lennart B?rjeson wrote: > > I?m using the tool I wrote to compress directories with thousands of log > files. The standard zip utility (as well as my utility when run with JDK 12) takes > up to an hour of user time to create the archive, on our server class 40+ core > servers this is reduced to 1?2 minutes. > > > > So while I understand the motivation for the change, I don?t get why you > would want to use ZipFs for what in essence is a RAM disk, *unless* you > want it compressed in memory? > > > > Oh well. Do we need a new option for this? > > > > /Lennart B?rjeson > > > > Electrogramma ab iPhono meo missum est > > > >> 16 apr. 2019 kl. 21:44 skrev Xueming Shen : > >> > >> One of the motivations back then is to speed up the performance of > accessing > >> > >> those entries, means you don't have to deflate/inflate those > new/updated entries > >> > >> during the lifetime of that zipfilesystem. Those updated entries only get > compressed > >> > >> when go to storage. So the regression is more like a trade off of > performance of > >> > >> different usages. (it also simplifies the logic on handing different types of > entries ...) > >> > >> > >> One idea I experimented long time ago for jartool is to concurrently write > out > >> > >> entries when need compression ... it does gain some performance > improvement > >> > >> on multi-cores, but not lots, as it ends up coming back to the main thread > to > >> > >> write out to the underlying filesystem. > >> > >> > >> -Sherman > >> > >>> On 4/16/19 5:21 AM, Claes Redestad wrote: > >>> Both before and after this regression, it seems the default behavior is > >>> not to use a temporary file (until ZFS.sync(), which writes to a temp > >>> file and then moves it in place, but that's different from what happens > >>> with the useTempFile option enabled). Instead entries (and the backing > >>> zip file system) are kept in-memory. > >>> > >>> The cause of the issue here is instead that no deflation happens until > >>> sync(), even when writing to entries in-memory. Previously, the > >>> deflation happened eagerly, then the result of that was copied into > >>> the zip file during sync(). > >>> > >>> I've written a proof-of-concept patch that restores the behavior of > >>> eagerly compressing entries when the method is METHOD_DEFLATED > and the > >>> target is to store byte[]s in-memory (the default scenario): > >>> > >>> http://cr.openjdk.java.net/~redestad/scratch/zfs.eager_deflation.00/ > >>> > >>> This restores performance of parallel zip to that of 11.0.2 for the > >>> default case. It still has a similar regression for the case where > >>> useTempFile is enabled, but that should be easily addressed if this > >>> looks like a way forward? > >>> > >>> (I've not yet created a bug as I got too caught up in trying to figure > >>> out what was going on here...) > >>> > >>> Thanks! > >>> > >>> /Claes > >>> > >>>> On 2019-04-16 09:29, Alan Bateman wrote: > >>>>> On 15/04/2019 14:32, Lennart B?rjeson wrote: > >>>>> : > >>>>> > >>>>> Previously, the deflation was done when in the call to Files.copy, thus > executed in parallel, and the final ZipFileSystem.close() didn't do anything > much. > >>>>> > >>>> Can you submit a bug? When creating/updating a zip file with zipfs then > the closing the file system creates the zip file. Someone needs to check but it > may have been that the temporary files (on the file system hosting the zip > file) were deflated when writing (which is surprising but may have been the > case). > >>>> > >>>> -Alan From lance.andersen at oracle.com Tue Apr 16 21:20:46 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Tue, 16 Apr 2019 17:20:46 -0400 Subject: ZipFileSystem performance regression In-Reply-To: References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> <680D03D1-9631-45DA-A89A-6EEDBC63EACE@gmail.com> Message-ID: Would it be worth adding a ZIP File System property similar to createNew which enables/disables the change that Claes has made having the default be the pre-jdk 12 functionality? > On Apr 16, 2019, at 4:50 PM, Xueming Shen wrote: > > Well, have to admitted I didn't expect your use scenario when made the change. Thought as a > > filesystem runtime access performance has more weight compared to shutdown performance... > > basically you are no using zipfs as a filesystem, but another jar tool that happens to have > > better in/out concurrent performance. Yes, back then I was working on using zipfs as a memory > > filesystem. One possible usage is that javac to use it as its filesystem (temp?) to write out compiled > > class files ... so I thought I can have better performance if I can keep those classes uncompressed > > until the zip/jarfs is closed and written to a "jar" file. > > That said, regression is a regression, we probably want to get the performance back for your > > use scenario. Just wanted to give you guys some background what happened back then. > > > -Sherman > > > On 4/16/19 12:54 PM, Lennart B?rjeson wrote: >> I?m using the tool I wrote to compress directories with thousands of log files. The standard zip utility (as well as my utility when run with JDK 12) takes up to an hour of user time to create the archive, on our server class 40+ core servers this is reduced to 1?2 minutes. >> >> So while I understand the motivation for the change, I don?t get why you would want to use ZipFs for what in essence is a RAM disk, *unless* you want it compressed in memory? >> >> Oh well. Do we need a new option for this? >> >> /Lennart B?rjeson >> >> Electrogramma ab iPhono meo missum est >> >>> 16 apr. 2019 kl. 21:44 skrev Xueming Shen : >>> >>> One of the motivations back then is to speed up the performance of accessing >>> >>> those entries, means you don't have to deflate/inflate those new/updated entries >>> >>> during the lifetime of that zipfilesystem. Those updated entries only get compressed >>> >>> when go to storage. So the regression is more like a trade off of performance of >>> >>> different usages. (it also simplifies the logic on handing different types of entries ...) >>> >>> >>> One idea I experimented long time ago for jartool is to concurrently write out >>> >>> entries when need compression ... it does gain some performance improvement >>> >>> on multi-cores, but not lots, as it ends up coming back to the main thread to >>> >>> write out to the underlying filesystem. >>> >>> >>> -Sherman >>> >>>> On 4/16/19 5:21 AM, Claes Redestad wrote: >>>> Both before and after this regression, it seems the default behavior is >>>> not to use a temporary file (until ZFS.sync(), which writes to a temp >>>> file and then moves it in place, but that's different from what happens >>>> with the useTempFile option enabled). Instead entries (and the backing >>>> zip file system) are kept in-memory. >>>> >>>> The cause of the issue here is instead that no deflation happens until >>>> sync(), even when writing to entries in-memory. Previously, the >>>> deflation happened eagerly, then the result of that was copied into >>>> the zip file during sync(). >>>> >>>> I've written a proof-of-concept patch that restores the behavior of >>>> eagerly compressing entries when the method is METHOD_DEFLATED and the >>>> target is to store byte[]s in-memory (the default scenario): >>>> >>>> http://cr.openjdk.java.net/~redestad/scratch/zfs.eager_deflation.00/ >>>> >>>> This restores performance of parallel zip to that of 11.0.2 for the >>>> default case. It still has a similar regression for the case where >>>> useTempFile is enabled, but that should be easily addressed if this >>>> looks like a way forward? >>>> >>>> (I've not yet created a bug as I got too caught up in trying to figure >>>> out what was going on here...) >>>> >>>> Thanks! >>>> >>>> /Claes >>>> >>>>> On 2019-04-16 09:29, Alan Bateman wrote: >>>>>> On 15/04/2019 14:32, Lennart B?rjeson wrote: >>>>>> : >>>>>> >>>>>> Previously, the deflation was done when in the call to Files.copy, thus executed in parallel, and the final ZipFileSystem.close() didn't do anything much. >>>>>> >>>>> Can you submit a bug? When creating/updating a zip file with zipfs then the closing the file system creates the zip file. Someone needs to check but it may have been that the temporary files (on the file system hosting the zip file) were deflated when writing (which is surprising but may have been the case). >>>>> >>>>> -Alan 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 Apr 16 21:31:19 2019 From: huizhe.wang at oracle.com (Joe Wang) Date: Tue, 16 Apr 2019 14:31:19 -0700 Subject: RFR (JDK 13/java.xml) 8222415: Xerces 2.12.0: Parsing Configuration In-Reply-To: References: <5CB4DF7E.6030203@oracle.com> Message-ID: <5CB649A7.1090008@oracle.com> Thanks Lance! Pushed after changing 3078/79 back to 3078. Best, Joe On 4/16/19, 1:14 PM, Lance Andersen wrote: > Hi Joe, > > Overall, I think the updates look OK. One minor correction/cleanup > for before you push is in the XMLEntityManager line 3078/79 to move > back the else to 3078 > > No need to update the webrev > > HTH > > Best > Lance >> On Apr 15, 2019, at 3:46 PM, Joe Wang > > wrote: >> >> Please review an update from Xerces in the configuration area. The >> patch contains changes not easily measurable with test (e.g. a few >> bytes for a parse, or small leaks for a file as large as a GB, or >> none at all). But the change does improve in that a method ( >> readAndBuffer) that explicitly buffers was provided so that the >> processes that required buffer all call it instead of the general >> read method. While there's a small test added, the testing was >> focused on getting the existing ones to pass. >> >> All XML-related tests in the core tests and JCK passed. >> >> JBS: https://bugs.openjdk.java.net/browse/JDK-8222415 >> webrevs: http://cr.openjdk.java.net/~joehw/jdk13/8222415/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 claes.redestad at oracle.com Tue Apr 16 21:50:04 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 16 Apr 2019 23:50:04 +0200 Subject: ZipFileSystem performance regression In-Reply-To: References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> <680D03D1-9631-45DA-A89A-6EEDBC63EACE@gmail.com> Message-ID: It sounds reasonable to have that as an option, but I'd like to see it requested by some user first. And at least one (micro-)benchmark where keeping entries uncompressed in memory actually shows significant positive impact. I can see it might have the opposite effect depending on how often that memory is inflated/deflated and whether or not the inflated entries cause high enough memory pressure to make GC activity spike. javac might be one application where it could be negative as it's tuned to run with a rather small max heap and already spends significant time doing GCs. /Claes On 2019-04-16 23:20, Lance Andersen wrote: > Would it be worth adding a ZIP File System property similar to createNew which enables/disables the change that Claes has made having the default be the pre-jdk 12 functionality? > > >> On Apr 16, 2019, at 4:50 PM, Xueming Shen wrote: >> >> Well, have to admitted I didn't expect your use scenario when made the change. Thought as a >> >> filesystem runtime access performance has more weight compared to shutdown performance... >> >> basically you are no using zipfs as a filesystem, but another jar tool that happens to have >> >> better in/out concurrent performance. Yes, back then I was working on using zipfs as a memory >> >> filesystem. One possible usage is that javac to use it as its filesystem (temp?) to write out compiled >> >> class files ... so I thought I can have better performance if I can keep those classes uncompressed >> >> until the zip/jarfs is closed and written to a "jar" file. >> >> That said, regression is a regression, we probably want to get the performance back for your >> >> use scenario. Just wanted to give you guys some background what happened back then. >> >> >> -Sherman >> >> >> On 4/16/19 12:54 PM, Lennart B?rjeson wrote: >>> I?m using the tool I wrote to compress directories with thousands of log files. The standard zip utility (as well as my utility when run with JDK 12) takes up to an hour of user time to create the archive, on our server class 40+ core servers this is reduced to 1?2 minutes. >>> >>> So while I understand the motivation for the change, I don?t get why you would want to use ZipFs for what in essence is a RAM disk, *unless* you want it compressed in memory? >>> >>> Oh well. Do we need a new option for this? >>> >>> /Lennart B?rjeson >>> >>> Electrogramma ab iPhono meo missum est >>> >>>> 16 apr. 2019 kl. 21:44 skrev Xueming Shen : >>>> >>>> One of the motivations back then is to speed up the performance of accessing >>>> >>>> those entries, means you don't have to deflate/inflate those new/updated entries >>>> >>>> during the lifetime of that zipfilesystem. Those updated entries only get compressed >>>> >>>> when go to storage. So the regression is more like a trade off of performance of >>>> >>>> different usages. (it also simplifies the logic on handing different types of entries ...) >>>> >>>> >>>> One idea I experimented long time ago for jartool is to concurrently write out >>>> >>>> entries when need compression ... it does gain some performance improvement >>>> >>>> on multi-cores, but not lots, as it ends up coming back to the main thread to >>>> >>>> write out to the underlying filesystem. >>>> >>>> >>>> -Sherman >>>> >>>>> On 4/16/19 5:21 AM, Claes Redestad wrote: >>>>> Both before and after this regression, it seems the default behavior is >>>>> not to use a temporary file (until ZFS.sync(), which writes to a temp >>>>> file and then moves it in place, but that's different from what happens >>>>> with the useTempFile option enabled). Instead entries (and the backing >>>>> zip file system) are kept in-memory. >>>>> >>>>> The cause of the issue here is instead that no deflation happens until >>>>> sync(), even when writing to entries in-memory. Previously, the >>>>> deflation happened eagerly, then the result of that was copied into >>>>> the zip file during sync(). >>>>> >>>>> I've written a proof-of-concept patch that restores the behavior of >>>>> eagerly compressing entries when the method is METHOD_DEFLATED and the >>>>> target is to store byte[]s in-memory (the default scenario): >>>>> >>>>> http://cr.openjdk.java.net/~redestad/scratch/zfs.eager_deflation.00/ >>>>> >>>>> This restores performance of parallel zip to that of 11.0.2 for the >>>>> default case. It still has a similar regression for the case where >>>>> useTempFile is enabled, but that should be easily addressed if this >>>>> looks like a way forward? >>>>> >>>>> (I've not yet created a bug as I got too caught up in trying to figure >>>>> out what was going on here...) >>>>> >>>>> Thanks! >>>>> >>>>> /Claes >>>>> >>>>>> On 2019-04-16 09:29, Alan Bateman wrote: >>>>>>> On 15/04/2019 14:32, Lennart B?rjeson wrote: >>>>>>> : >>>>>>> >>>>>>> Previously, the deflation was done when in the call to Files.copy, thus executed in parallel, and the final ZipFileSystem.close() didn't do anything much. >>>>>>> >>>>>> Can you submit a bug? When creating/updating a zip file with zipfs then the closing the file system creates the zip file. Someone needs to check but it may have been that the temporary files (on the file system hosting the zip file) were deflated when writing (which is surprising but may have been the case). >>>>>> >>>>>> -Alan > > > > 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 michael at michaelpollmeier.com Wed Apr 17 01:59:09 2019 From: michael at michaelpollmeier.com (Michael Pollmeier) Date: Wed, 17 Apr 2019 13:59:09 +1200 Subject: SoftReference incorrect javadoc? In-Reply-To: <99718e43-ad0b-ee70-bdfd-fdea85218288@oracle.com> References: <3f29d05c-ee18-ed77-6bda-7f6a76fec587@oracle.com> <99718e43-ad0b-ee70-bdfd-fdea85218288@oracle.com> Message-ID: Hi Per, While testing different JVMs I realized that it's fixed in openjdk 11, e.g. openjdk version "11.0.1" 2018-10-16 LTS (zulu build), maybe by this commit: https://hg.openjdk.java.net/jdk/jdk/rev/6464882498b5 That's great to know, but is it worth updating the javadocs of older versions? To reproduce it I attached a simple SoftRefTest.java to easily reproduce it. It allocates (only) softly referenced objects that occupy some heap, occasionally printing counts (instantiated, finalized, free heap). Usage: javac SoftRefTest.java java -Xms256m -Xmx256m SoftRefTest Output: 100000 instances created; free=212M 200000 instances created; free=181M 300000 instances created; free=152M 400000 instances created; free=121M 500000 instances created; free=93M 600000 instances created; free=61M 700000 instances created; free=33M Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at Instance.(SoftRefTest.java:27) at SoftRefTest.main(SoftRefTest.java:12) Interpretation: It doesn't free any of the only softly referenced objects, resulting in an OutOfMemoryError, contradicting the 'guarantee' in the javadoc. Workaround: if you additionally configure `-XX:SoftRefLRUPolicyMSPerMB=0`, it finalizes them and doesn't run out of memory. Tested with: openjdk version "1.8.0_212" java version "1.8.0_144" (oracle) openjdk version "9.0.4.1" (zulu build) openjdk version "10.0.2" 2018-07-17 (zulu build) Cheers Michael On 16/04/19 6:27 pm, Per Liden wrote: > Hi Michael, > > On 4/16/19 4:19 AM, David Holmes wrote: >> Hi Michael, >> >> Re-directing to core-libs-dev and hotspot-gc-dev. >> >> Thanks, >> David >> >> On 16/04/2019 12:14 pm, Michael Pollmeier wrote: >>> Quoting >>> https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ref/SoftReference.html >>> >>> >>> >>>> All soft references to softly-reachable objects are guaranteed to have >>> been cleared before the virtual machine throws an OutOfMemoryError >>> >>> That statement was true when soft references were first introduced in >>> java 1.2, but from java 1.3.1 the jvm property >>> `-XX:SoftRefLRUPolicyMSPerMB` was introduced. > > That statement is still true. When the GC gets into a situation where it > is having trouble satisfying an allocation, then SoftRefLRUPolicyMSPerMB > will be ignored and all soft references will be cleared, before the GC > gives up and throws an OOME. > >>> It defaults to 1000 (milliseconds), meaning that if there?s only 10MB >>> available heap, the garbage collector will free references that have >>> been used more than 10s ago. I.e. everything else (including young >>> softly reachable objects) will *not* be freed, leading to an >>> OutOfMemoryError, contradicting the above quoted 'guarantee'. >>> >>> That's also the behaviour I observed on various JREs. Would you agree, >>> i.e. should I propose an updated doc? > > Could you elaborate on what kind of test you did to come to this > conclusion? Preferably provide a re-producer. In OOME situations, if a > SoftReference isn't cleared, it is typically because you have > unknowingly made it strongly reachable. > > cheers, > Per > From peter.levart at gmail.com Wed Apr 17 07:23:08 2019 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 17 Apr 2019 09:23:08 +0200 Subject: ZipFileSystem performance regression In-Reply-To: References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> <680D03D1-9631-45DA-A89A-6EEDBC63EACE@gmail.com> Message-ID: <63714ecc-4695-0411-c22f-7cd276cd1435@gmail.com> Just a thought... Would it be feasible to create a brand new "Generic Caching Filesystem" implementation that would delegate to another filesystem for persistent storage (be it ZipFilesystem or any other) and implement interesting caching strategies (lazy flushing, concurrent flushing, etc...) So instead of parameterizing a concrete filesystem (e.g. ZipFilesystem), the filesystems could be layered to achieve the desired performance characteristics. What do you think? Is the existing filesystem API suitable for such layering? Regards, Peter On 4/16/19 11:50 PM, Claes Redestad wrote: > It sounds reasonable to have that as an option, but I'd like to see it > requested by some user first. And at least one (micro-)benchmark where > keeping entries uncompressed in memory actually shows significant > positive impact. > > I can see it might have the opposite effect depending on how often that > memory is inflated/deflated and whether or not the inflated entries > cause high enough memory pressure to make GC activity spike. javac might > be one application where it could be negative as it's tuned to run with > a rather small max heap and already spends significant time doing GCs. > > /Claes > > On 2019-04-16 23:20, Lance Andersen wrote: >> Would it be worth? adding a ZIP File System property similar to >> createNew which enables/disables the change that Claes has made >> having the default be the pre-jdk 12 functionality? >> >> >>> On Apr 16, 2019, at 4:50 PM, Xueming Shen >>> wrote: >>> >>> Well, have to admitted I didn't expect your use scenario when made >>> the change. Thought as a >>> >>> filesystem runtime access performance has more weight compared to >>> shutdown performance... >>> >>> basically you are no using zipfs as a filesystem, but another jar >>> tool that happens to have >>> >>> better in/out concurrent performance. Yes, back then I was working >>> on using zipfs as a memory >>> >>> filesystem. One possible usage is that javac to use it as its >>> filesystem (temp?) to write out compiled >>> >>> class files ... so I thought I can have better performance if I can >>> keep those classes uncompressed >>> >>> until the zip/jarfs is closed and written to a "jar" file. >>> >>> That said, regression is a regression, we probably want to get the >>> performance back for your >>> >>> use scenario. Just wanted to give you guys some background what >>> happened back then. >>> >>> >>> -Sherman >>> >>> >>> On 4/16/19 12:54 PM, Lennart B?rjeson wrote: >>>> I?m using the tool I wrote to compress directories with thousands >>>> of log files. The standard zip utility (as well as my utility when >>>> run with JDK 12) takes up to an hour of user time to create the >>>> archive, on our server class 40+ core servers this is reduced to >>>> 1?2 minutes. >>>> >>>> So while I understand the motivation for the change, I don?t get >>>> why you would want to use ZipFs for what in essence is a RAM disk, >>>> *unless* you want it compressed in memory? >>>> >>>> Oh well. Do we need a new option for this? >>>> >>>> /Lennart B?rjeson >>>> >>>> Electrogramma ab iPhono meo missum est >>>> >>>>> 16 apr. 2019 kl. 21:44 skrev Xueming Shen : >>>>> >>>>> One of the motivations back then is to speed up the performance of >>>>> accessing >>>>> >>>>> those entries, means you don't have to deflate/inflate those >>>>> new/updated entries >>>>> >>>>> during the lifetime of that zipfilesystem. Those updated entries >>>>> only get compressed >>>>> >>>>> when go to storage. So the regression is more like a trade off of >>>>> performance of >>>>> >>>>> different usages. (it also simplifies the logic on handing >>>>> different types of entries ...) >>>>> >>>>> >>>>> One idea I experimented long time ago for jartool is to >>>>> concurrently write out >>>>> >>>>> entries when need compression ... it does gain some performance >>>>> improvement >>>>> >>>>> on multi-cores, but not lots, as it ends up coming back to the >>>>> main thread to >>>>> >>>>> write out to the underlying filesystem. >>>>> >>>>> >>>>> -Sherman >>>>> >>>>>> On 4/16/19 5:21 AM, Claes Redestad wrote: >>>>>> Both before and after this regression, it seems the default >>>>>> behavior is >>>>>> not to use a temporary file (until ZFS.sync(), which writes to a >>>>>> temp >>>>>> file and then moves it in place, but that's different from what >>>>>> happens >>>>>> with the useTempFile option enabled). Instead entries (and the >>>>>> backing >>>>>> zip file system) are kept in-memory. >>>>>> >>>>>> The cause of the issue here is instead that no deflation happens >>>>>> until >>>>>> sync(), even when writing to entries in-memory. Previously, the >>>>>> deflation happened eagerly, then the result of that was copied into >>>>>> the zip file during sync(). >>>>>> >>>>>> I've written a proof-of-concept patch that restores the behavior of >>>>>> eagerly compressing entries when the method is METHOD_DEFLATED >>>>>> and the >>>>>> target is to store byte[]s in-memory (the default scenario): >>>>>> >>>>>> http://cr.openjdk.java.net/~redestad/scratch/zfs.eager_deflation.00/ >>>>>> >>>>>> This restores performance of parallel zip to that of 11.0.2 for the >>>>>> default case. It still has a similar regression for the case where >>>>>> useTempFile is enabled, but that should be easily addressed if this >>>>>> looks like a way forward? >>>>>> >>>>>> (I've not yet created a bug as I got too caught up in trying to >>>>>> figure >>>>>> out what was going on here...) >>>>>> >>>>>> Thanks! >>>>>> >>>>>> /Claes >>>>>> >>>>>>> On 2019-04-16 09:29, Alan Bateman wrote: >>>>>>>> On 15/04/2019 14:32, Lennart B?rjeson wrote: >>>>>>>> : >>>>>>>> >>>>>>>> Previously, the deflation was done when in the call to >>>>>>>> Files.copy, thus executed in parallel, and the final >>>>>>>> ZipFileSystem.close() didn't do anything much. >>>>>>>> >>>>>>> Can you submit a bug? When creating/updating a zip file with >>>>>>> zipfs then the closing the file system creates the zip file. >>>>>>> Someone needs to check but it may have been that the temporary >>>>>>> files (on the file system hosting the zip file) were deflated >>>>>>> when writing (which is surprising but may have been the case). >>>>>>> >>>>>>> -Alan >> >> >> >> >> 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 per.liden at oracle.com Wed Apr 17 10:22:53 2019 From: per.liden at oracle.com (Per Liden) Date: Wed, 17 Apr 2019 12:22:53 +0200 Subject: SoftReference incorrect javadoc? In-Reply-To: References: <3f29d05c-ee18-ed77-6bda-7f6a76fec587@oracle.com> <99718e43-ad0b-ee70-bdfd-fdea85218288@oracle.com> Message-ID: Hi Michael, On 04/17/2019 03:59 AM, Michael Pollmeier wrote: > Hi Per, > > While testing different JVMs I realized that it's fixed in openjdk 11, > e.g. openjdk version "11.0.1" 2018-10-16 LTS (zulu build), maybe by this > commit: https://hg.openjdk.java.net/jdk/jdk/rev/6464882498b5 That bug only affected ZGC (which was introduced in 11), so it didn't change the behavior of any other GC. > That's great to know, but is it worth updating the javadocs of older > versions? > > To reproduce it I attached a simple SoftRefTest.java to easily reproduce > it. It allocates (only) softly referenced objects that occupy some heap, > occasionally printing counts (instantiated, finalized, free heap). Thanks for the test. The problem with the test is that you have a finalize() function on Instance. This means the object will be kept around until it has been finalized. So even if the SoftReference referring to it is cleared, the memory will not be freed until the object also has been finalized. In your test, you're simply creating too many objects, and the Finalizer thread is simply unable to keep up finalizing them at the same pace as they are created, so the heap fills up. I adjusted your test a bit, and removed the use of finalize(). You can run this test forever without running into OOMEs. By having the same thread that creates the objects also poll the reference queue, the test will automatically be throttled. If SoftReferences weren't cleared as they should, this test would OOME pretty fast. import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.util.HashMap; public class SoftRefTest2 { public static void main(String[] args) throws Exception { final ReferenceQueue queue = new ReferenceQueue<>(); final HashMap> instances = new HashMap<>(); long createdCount = 0; long clearedCount = 0; for (;;) { SoftReference softref = new SoftReference(new Instance(), queue); instances.put(softref, softref); if (++createdCount % 100000 == 0) { System.out.println(createdCount + " instances created; free=" + Runtime.getRuntime().freeMemory() / 1024 / 1024 + "M"); } // Drain queue Reference ref; while ((ref = queue.poll()) != null) { instances.remove(ref); if (++clearedCount % 100000 == 0) { System.out.println(clearedCount + " instances cleared"); } } } } static class Instance { static int finalizedCount = 0; String[] occupySomeHeap = new String[50]; } } cheers, Per > > Usage: > javac SoftRefTest.java > java -Xms256m -Xmx256m SoftRefTest > > Output: > 100000 instances created; free=212M > 200000 instances created; free=181M > 300000 instances created; free=152M > 400000 instances created; free=121M > 500000 instances created; free=93M > 600000 instances created; free=61M > 700000 instances created; free=33M > Exception in thread "main" java.lang.OutOfMemoryError: Java heap space > at Instance.(SoftRefTest.java:27) > at SoftRefTest.main(SoftRefTest.java:12) > > Interpretation: > It doesn't free any of the only softly referenced objects, resulting in > an OutOfMemoryError, contradicting the 'guarantee' in the javadoc. > > Workaround: if you additionally configure > `-XX:SoftRefLRUPolicyMSPerMB=0`, it finalizes them and doesn't run out > of memory. > > Tested with: > openjdk version "1.8.0_212" > java version "1.8.0_144" (oracle) > openjdk version "9.0.4.1" (zulu build) > openjdk version "10.0.2" 2018-07-17 (zulu build) > > Cheers > Michael > > > On 16/04/19 6:27 pm, Per Liden wrote: >> Hi Michael, >> >> On 4/16/19 4:19 AM, David Holmes wrote: >>> Hi Michael, >>> >>> Re-directing to core-libs-dev and hotspot-gc-dev. >>> >>> Thanks, >>> David >>> >>> On 16/04/2019 12:14 pm, Michael Pollmeier wrote: >>>> Quoting >>>> https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ref/SoftReference.html >>>> >>>> >>>> >>>>> All soft references to softly-reachable objects are guaranteed to have >>>> been cleared before the virtual machine throws an OutOfMemoryError >>>> >>>> That statement was true when soft references were first introduced in >>>> java 1.2, but from java 1.3.1 the jvm property >>>> `-XX:SoftRefLRUPolicyMSPerMB` was introduced. >> >> That statement is still true. When the GC gets into a situation where it >> is having trouble satisfying an allocation, then SoftRefLRUPolicyMSPerMB >> will be ignored and all soft references will be cleared, before the GC >> gives up and throws an OOME. >> >>>> It defaults to 1000 (milliseconds), meaning that if there?s only 10MB >>>> available heap, the garbage collector will free references that have >>>> been used more than 10s ago. I.e. everything else (including young >>>> softly reachable objects) will *not* be freed, leading to an >>>> OutOfMemoryError, contradicting the above quoted 'guarantee'. >>>> >>>> That's also the behaviour I observed on various JREs. Would you agree, >>>> i.e. should I propose an updated doc? >> >> Could you elaborate on what kind of test you did to come to this >> conclusion? Preferably provide a re-producer. In OOME situations, if a >> SoftReference isn't cleared, it is typically because you have >> unknowingly made it strongly reachable. >> >> cheers, >> Per >> From sgehwolf at redhat.com Wed Apr 17 17:32:12 2019 From: sgehwolf at redhat.com (Severin Gehwolf) Date: Wed, 17 Apr 2019 19:32:12 +0200 Subject: [PING2] RFR: 8217338: [Containers] Improve systemd slice memory limit support In-Reply-To: References: <4a1ae4e0e3efd68818bfe868349972aa878de60b.camel@redhat.com> <9a911da4b2a4a8eff42c7c2f1a19c06f6521da8d.camel@redhat.com> <226CB44C-7B3A-42E8-8385-4E85168DBA4E@oracle.com> <254f53446176175689373b346c11aabc26d9b4b0.camel@redhat.com> Message-ID: Ping? On Tue, 2019-04-09 at 11:33 +0200, Severin Gehwolf wrote: > Hi, > > Could I get another reviewer for this, please? Bob Vandette already reviewed it. > > Thank you! > > Cheers, > Severin > > On Tue, 2019-04-02 at 13:48 +0200, Severin Gehwolf wrote: > > Could I get a second review, please? > > > > Thanks, > > Severin > > > > On Thu, 2019-03-28 at 11:37 -0400, Bob Vandette wrote: > > > Sorry for the delay. The update looks good. > > > > > > Bob. > > > > > > > > > > On Mar 25, 2019, at 1:30 PM, Severin Gehwolf wrote: > > > > > > > > On Fri, 2019-03-22 at 14:25 -0400, Bob Vandette wrote: > > > > > Could you maybe combine subsystem_file_contents with subsystem_file_line_contents > > > > > by adding an additional argument? > > > > > > > > Done: http://cr.openjdk.java.net/~sgehwolf/webrevs/JDK-8217338/05/webrev/ > > > > > > > > Thanks, > > > > Severin > > > > From lance.andersen at oracle.com Wed Apr 17 17:51:15 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Wed, 17 Apr 2019 13:51:15 -0400 Subject: RFR: 8222440: (zipfs) JarFileSystem does not correctly handle versioned entries if no root entry is present In-Reply-To: References: Message-ID: <7C9075D6-69B2-4A8E-A748-CA61537B4710@oracle.com> Hi Christoph, Overall, I think the changes look good. Was there a reason that you did not leave the multi-release 9 test as is when you added the 10 test? As far as removing the jar file, I would think that would still want to be done. I understand why you did this, not sure what the standard is here as most tests try to do clean up Best Lance > On Apr 16, 2019, at 4:50 PM, Langer, Christoph wrote: > > Hi, > > please review a fix for an issue with zipfs/jarfs regarding multi-release jars. > > The issue is observed when an mr-jar does have entries for certain files in the versioned subfolders but not in the main tree. This should be allowed as per JEP 238 [0]. So, say, if a jar file contains an entry '/META-INF/versions/11/file.txt' but not the entry 'file.txt', this will not correctly be visible when walking the jar file with jarfs. I discovered this when working on JDK-8222276 and saw a suspicious usage of IndexNode.keyOf() to create a virtual index node for the JarFileSystem lookup table. So I enhanced the test 'test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java' to demonstrate the issue. The updated test case will fail with the current coding and works with the proposed fix. > > Here are some details: > JarFileSystem builds a lookup table to return for any jar entry its versioned entry, should it exist, in favor of the standard root entry. This is done by overriding ZipFileSystem's getInode() method and using a lookup table to return the correct versioned entry. The actual root inode is the key of this lookup table, which requires that it exists. If there is no root inode in the jar, there is code to create a virtual inode. But as it is right now, this does not work because a special singleton key node is used as virtual node which constantly changes its name. Furthermore, the node is not added to the jar file system node hierarchy. I enhanced this by correctly creating a 'virtual' root inode, making sure all parent directory inodes exist and if not creating and adding them into the jarfs/zipfs hierarchy to allow for iterating subdirectories. > > I also enhanced 'test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java' to demonstrate the issue. The test furthermore does not rely on files that are checked in in the source tree any longer but creates the test.jar by means of JarBuilder. I also don't delete test.jar in the test but leave it to jtreg to delete the scratch directory. That helps when analyzing test issues where scratch directory contents shall be retained. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8222440 > Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8222440.0/ > > Thanks in advance > Christoph > > [0] https://openjdk.java.net/jeps/238 > 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 michael at michaelpollmeier.com Wed Apr 17 21:19:34 2019 From: michael at michaelpollmeier.com (Michael Pollmeier) Date: Thu, 18 Apr 2019 09:19:34 +1200 Subject: SoftReference incorrect javadoc? In-Reply-To: References: <3f29d05c-ee18-ed77-6bda-7f6a76fec587@oracle.com> <99718e43-ad0b-ee70-bdfd-fdea85218288@oracle.com> Message-ID: Thanks Per, your detailed insights make sense. On 17/04/19 10:22 pm, Per Liden wrote: > Hi Michael, > > On 04/17/2019 03:59 AM, Michael Pollmeier wrote: >> Hi Per, >> >> While testing different JVMs I realized that it's fixed in openjdk 11, >> e.g. openjdk version "11.0.1" 2018-10-16 LTS (zulu build), maybe by this >> commit: https://hg.openjdk.java.net/jdk/jdk/rev/6464882498b5 > > That bug only affected ZGC (which was introduced in 11), so it didn't > change the behavior of any other GC. > >> That's great to know, but is it worth updating the javadocs of older >> versions? >> >> To reproduce it I attached a simple SoftRefTest.java to easily reproduce >> it. It allocates (only) softly referenced objects that occupy some heap, >> occasionally printing counts (instantiated, finalized, free heap). > > Thanks for the test. The problem with the test is that you have a > finalize() function on Instance. This means the object will be kept > around until it has been finalized. So even if the SoftReference > referring to it is cleared, the memory will not be freed until the > object also has been finalized. In your test, you're simply creating too > many objects, and the Finalizer thread is simply unable to keep up > finalizing them at the same pace as they are created, so the heap fills up. > > I adjusted your test a bit, and removed the use of finalize(). You can > run this test forever without running into OOMEs. By having the same > thread that creates the objects also poll the reference queue, the test > will automatically be throttled. If SoftReferences weren't cleared as > they should, this test would OOME pretty fast. > > import java.lang.ref.Reference; > import java.lang.ref.ReferenceQueue; > import java.lang.ref.SoftReference; > import java.util.HashMap; > > public class SoftRefTest2 { > ? public static void main(String[] args) throws Exception { > ??? final ReferenceQueue queue = new ReferenceQueue<>(); > ??? final HashMap> instances = new > HashMap<>(); > ??? long createdCount = 0; > ??? long clearedCount = 0; > > ??? for (;;) { > ????? SoftReference softref = new SoftReference(new > Instance(), queue); > ????? instances.put(softref, softref); > ????? if (++createdCount % 100000 == 0) { > ??????? System.out.println(createdCount + " instances created; free=" + > Runtime.getRuntime().freeMemory() / 1024 / 1024 + "M"); > ????? } > > ????? // Drain queue > ????? Reference ref; > ????? while ((ref = queue.poll()) != null) { > ????????? instances.remove(ref); > ????????? if (++clearedCount % 100000 == 0) { > ????????????? System.out.println(clearedCount + " instances cleared"); > ????????? } > ????? } > ??? } > ? } > > ? static class Instance { > ??? static int finalizedCount = 0; > ??? String[] occupySomeHeap = new String[50]; > ? } > } > > > cheers, > Per > >> >> Usage: >> javac SoftRefTest.java >> java -Xms256m -Xmx256m SoftRefTest >> >> Output: >> 100000 instances created; free=212M >> 200000 instances created; free=181M >> 300000 instances created; free=152M >> 400000 instances created; free=121M >> 500000 instances created; free=93M >> 600000 instances created; free=61M >> 700000 instances created; free=33M >> Exception in thread "main" java.lang.OutOfMemoryError: Java heap space >> ???????? at Instance.(SoftRefTest.java:27) >> ???????? at SoftRefTest.main(SoftRefTest.java:12) >> >> Interpretation: >> It doesn't free any of the only softly referenced objects, resulting in >> an OutOfMemoryError, contradicting the 'guarantee' in the javadoc. >> >> Workaround: if you additionally configure >> `-XX:SoftRefLRUPolicyMSPerMB=0`, it finalizes them and doesn't run out >> of memory. >> >> Tested with: >> openjdk version "1.8.0_212" >> java version "1.8.0_144" (oracle) >> openjdk version "9.0.4.1" (zulu build) >> openjdk version "10.0.2" 2018-07-17? (zulu build) >> >> Cheers >> Michael >> >> >> On 16/04/19 6:27 pm, Per Liden wrote: >>> Hi Michael, >>> >>> On 4/16/19 4:19 AM, David Holmes wrote: >>>> Hi Michael, >>>> >>>> Re-directing to core-libs-dev and hotspot-gc-dev. >>>> >>>> Thanks, >>>> David >>>> >>>> On 16/04/2019 12:14 pm, Michael Pollmeier wrote: >>>>> Quoting >>>>> https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ref/SoftReference.html >>>>> >>>>> >>>>> >>>>> >>>>>> All soft references to softly-reachable objects are guaranteed to >>>>>> have >>>>> been cleared before the virtual machine throws an OutOfMemoryError >>>>> >>>>> That statement was true when soft references were first introduced in >>>>> java 1.2, but from java 1.3.1 the jvm property >>>>> `-XX:SoftRefLRUPolicyMSPerMB` was introduced. >>> >>> That statement is still true. When the GC gets into a situation where it >>> is having trouble satisfying an allocation, then SoftRefLRUPolicyMSPerMB >>> will be ignored and all soft references will be cleared, before the GC >>> gives up and throws an OOME. >>> >>>>> It defaults to 1000 (milliseconds), meaning that if there?s only 10MB >>>>> available heap, the garbage collector will free references that have >>>>> been used more than 10s ago. I.e. everything else (including young >>>>> softly reachable objects) will *not* be freed, leading to an >>>>> OutOfMemoryError, contradicting the above quoted 'guarantee'. >>>>> >>>>> That's also the behaviour I observed on various JREs. Would you agree, >>>>> i.e. should I propose an updated doc? >>> >>> Could you elaborate on what kind of test you did to come to this >>> conclusion? Preferably provide a re-producer. In OOME situations, if a >>> SoftReference isn't cleared, it is typically because you have >>> unknowingly made it strongly reachable. >>> >>> cheers, >>> Per >>> > From semyon.sadetsky at oracle.com Wed Apr 17 22:18:51 2019 From: semyon.sadetsky at oracle.com (semyon.sadetsky at oracle.com) Date: Wed, 17 Apr 2019 15:18:51 -0700 Subject: RFR: JDK-8219683: Investigate App Image layout on Mac Message-ID: <41ef8bbd-7868-87d4-c473-52c26904a93c@oracle.com> bug: https://bugs.openjdk.java.net/browse/JDK-8219683 webrev: http://cr.openjdk.java.net/~ssadetsky/8219683/webrev.00/ The fix moves Java runtime form Contents/PlugIns/Java.runtime to Contents/Java.runtime. --Semyon From andy.herrick at oracle.com Wed Apr 17 22:33:22 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Wed, 17 Apr 2019 18:33:22 -0400 Subject: RFR: JDK-8219683: Investigate App Image layout on Mac In-Reply-To: <41ef8bbd-7868-87d4-c473-52c26904a93c@oracle.com> References: <41ef8bbd-7868-87d4-c473-52c26904a93c@oracle.com> Message-ID: <40c9c189-c3ab-4a56-9d34-c8e75fd7e367@oracle.com> On 4/17/2019 6:18 PM, semyon.sadetsky at oracle.com wrote: > bug: https://bugs.openjdk.java.net/browse/JDK-8219683 > > webrev: http://cr.openjdk.java.net/~ssadetsky/8219683/webrev.00/ > > > The fix moves Java runtime form Contents/PlugIns/Java.runtime to > Contents/Java.runtime. > > --Semyon > Is there any reason "Java.runtime" shouldn't be just? "runtime" like other platforms ? Please add comment to bug with pointer to webrev. /Andy From andy.herrick at oracle.com Wed Apr 17 22:45:10 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Wed, 17 Apr 2019 18:45:10 -0400 Subject: RFR: JDK-8219683: Investigate App Image layout on Mac In-Reply-To: <40c9c189-c3ab-4a56-9d34-c8e75fd7e367@oracle.com> References: <41ef8bbd-7868-87d4-c473-52c26904a93c@oracle.com> <40c9c189-c3ab-4a56-9d34-c8e75fd7e367@oracle.com> Message-ID: <1957f325-86c7-6257-8091-f724fa20797c@oracle.com> On 4/17/2019 6:33 PM, Andy Herrick wrote: > > > On 4/17/2019 6:18 PM, semyon.sadetsky at oracle.com wrote: >> bug: https://bugs.openjdk.java.net/browse/JDK-8219683 >> >> webrev: http://cr.openjdk.java.net/~ssadetsky/8219683/webrev.00/ >> >> >> The fix moves Java runtime form Contents/PlugIns/Java.runtime to >> Contents/Java.runtime. >> >> --Semyon >> > > Is there any reason "Java.runtime" shouldn't be just? "runtime" like > other platforms ? > Please add comment to bug with pointer to webrev. > > /Andy Do we need to modify code in MacAppImageBuilder.signAppBundle() that treats "Contents/PlugIns" differently than other directories ? /Andy > > From david.holmes at oracle.com Wed Apr 17 23:00:08 2019 From: david.holmes at oracle.com (David Holmes) Date: Thu, 18 Apr 2019 09:00:08 +1000 Subject: [PING2] RFR: 8217338: [Containers] Improve systemd slice memory limit support In-Reply-To: References: <4a1ae4e0e3efd68818bfe868349972aa878de60b.camel@redhat.com> <9a911da4b2a4a8eff42c7c2f1a19c06f6521da8d.camel@redhat.com> <226CB44C-7B3A-42E8-8385-4E85168DBA4E@oracle.com> <254f53446176175689373b346c11aabc26d9b4b0.camel@redhat.com> Message-ID: Hi Severin, I took a look at this (again**) and although I'm not at all familiar with the actual cgroup facilities the changes seem reasonable in that they only look for a hierarchical memory limit if the initial limit is "unlimited". So you can add me as a reviewer. Thanks, David ** I didn't previously review in the hope someone more cgroup knowledgeable would do so. On 18/04/2019 3:32 am, Severin Gehwolf wrote: > Ping? > > On Tue, 2019-04-09 at 11:33 +0200, Severin Gehwolf wrote: >> Hi, >> >> Could I get another reviewer for this, please? Bob Vandette already reviewed it. >> >> Thank you! >> >> Cheers, >> Severin >> >> On Tue, 2019-04-02 at 13:48 +0200, Severin Gehwolf wrote: >>> Could I get a second review, please? >>> >>> Thanks, >>> Severin >>> >>> On Thu, 2019-03-28 at 11:37 -0400, Bob Vandette wrote: >>>> Sorry for the delay. The update looks good. >>>> >>>> Bob. >>>> >>>> >>>>> On Mar 25, 2019, at 1:30 PM, Severin Gehwolf wrote: >>>>> >>>>> On Fri, 2019-03-22 at 14:25 -0400, Bob Vandette wrote: >>>>>> Could you maybe combine subsystem_file_contents with subsystem_file_line_contents >>>>>> by adding an additional argument? >>>>> >>>>> Done: http://cr.openjdk.java.net/~sgehwolf/webrevs/JDK-8217338/05/webrev/ >>>>> >>>>> Thanks, >>>>> Severin >>>>> > From kevin.rushforth at oracle.com Wed Apr 17 23:19:56 2019 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Wed, 17 Apr 2019 16:19:56 -0700 Subject: RFR: JDK-8219683: Investigate App Image layout on Mac In-Reply-To: <1957f325-86c7-6257-8091-f724fa20797c@oracle.com> References: <41ef8bbd-7868-87d4-c473-52c26904a93c@oracle.com> <40c9c189-c3ab-4a56-9d34-c8e75fd7e367@oracle.com> <1957f325-86c7-6257-8091-f724fa20797c@oracle.com> Message-ID: <59b5347e-b48d-4d8c-f3ba-5439f3db06ab@oracle.com> I also would prefer just "runtime", but "Java.runtime" is at least better than anything with "Plugin" in the name... -- Kevin On 4/17/2019 3:45 PM, Andy Herrick wrote: > > > On 4/17/2019 6:33 PM, Andy Herrick wrote: >> >> >> On 4/17/2019 6:18 PM, semyon.sadetsky at oracle.com wrote: >>> bug: https://bugs.openjdk.java.net/browse/JDK-8219683 >>> >>> webrev: http://cr.openjdk.java.net/~ssadetsky/8219683/webrev.00/ >>> >>> >>> The fix moves Java runtime form Contents/PlugIns/Java.runtime to >>> Contents/Java.runtime. >>> >>> --Semyon >>> >> >> Is there any reason "Java.runtime" shouldn't be just? "runtime" like >> other platforms ? >> Please add comment to bug with pointer to webrev. >> >> /Andy > Do we need to modify code in MacAppImageBuilder.signAppBundle() that > treats "Contents/PlugIns" differently than other directories ? > /Andy >> >> > From anthonyv.be at outlook.com Thu Apr 18 07:50:44 2019 From: anthonyv.be at outlook.com (Anthony Vanelverdinghe) Date: Thu, 18 Apr 2019 07:50:44 +0000 Subject: ZipFileSystem performance regression In-Reply-To: <63714ecc-4695-0411-c22f-7cd276cd1435@gmail.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> <680D03D1-9631-45DA-A89A-6EEDBC63EACE@gmail.com> , <63714ecc-4695-0411-c22f-7cd276cd1435@gmail.com> Message-ID: Hi Alan already proposed the following RFEs when NIO2 was introduced: a memory FileSystemProvider [1], and a virtual FileSystemProvider [2] With these, the javac use case could work as follows: 1) create a VirtualFileSystem, with all sources mounted under ?/src?, a MemoryFileSystem mounted at ?/target?, and a ZipFileSystem mounted at ?/dist? 2) from then on, simply work with the VirtualFileSystem: read from /src, write compilation artifacts to /target, and finally assemble a .jar file by copying from /target to /dist I think these providers would elegantly solve most use cases. And those providers could then be enhanced with further features as desired. For example, the memory FileSystem could allow on-the-fly compression, encryption, etc. [1] https://bugs.openjdk.java.net/browse/JDK-8002315 [2] https://bugs.openjdk.java.net/browse/JDK-8002316 Kind regards Anthony ________________________________ From: core-libs-dev on behalf of Peter Levart Sent: Wednesday, April 17, 2019 9:23:08 AM To: Claes Redestad; Lance Andersen; Xueming Shen Cc: core-libs-dev at openjdk.java.net Subject: Re: ZipFileSystem performance regression Just a thought... Would it be feasible to create a brand new "Generic Caching Filesystem" implementation that would delegate to another filesystem for persistent storage (be it ZipFilesystem or any other) and implement interesting caching strategies (lazy flushing, concurrent flushing, etc...) So instead of parameterizing a concrete filesystem (e.g. ZipFilesystem), the filesystems could be layered to achieve the desired performance characteristics. What do you think? Is the existing filesystem API suitable for such layering? Regards, Peter On 4/16/19 11:50 PM, Claes Redestad wrote: > It sounds reasonable to have that as an option, but I'd like to see it > requested by some user first. And at least one (micro-)benchmark where > keeping entries uncompressed in memory actually shows significant > positive impact. > > I can see it might have the opposite effect depending on how often that > memory is inflated/deflated and whether or not the inflated entries > cause high enough memory pressure to make GC activity spike. javac might > be one application where it could be negative as it's tuned to run with > a rather small max heap and already spends significant time doing GCs. > > /Claes > > On 2019-04-16 23:20, Lance Andersen wrote: >> Would it be worth adding a ZIP File System property similar to >> createNew which enables/disables the change that Claes has made >> having the default be the pre-jdk 12 functionality? >> >> >>> On Apr 16, 2019, at 4:50 PM, Xueming Shen >>> wrote: >>> >>> Well, have to admitted I didn't expect your use scenario when made >>> the change. Thought as a >>> >>> filesystem runtime access performance has more weight compared to >>> shutdown performance... >>> >>> basically you are no using zipfs as a filesystem, but another jar >>> tool that happens to have >>> >>> better in/out concurrent performance. Yes, back then I was working >>> on using zipfs as a memory >>> >>> filesystem. One possible usage is that javac to use it as its >>> filesystem (temp?) to write out compiled >>> >>> class files ... so I thought I can have better performance if I can >>> keep those classes uncompressed >>> >>> until the zip/jarfs is closed and written to a "jar" file. >>> >>> That said, regression is a regression, we probably want to get the >>> performance back for your >>> >>> use scenario. Just wanted to give you guys some background what >>> happened back then. >>> >>> >>> -Sherman >>> >>> >>> On 4/16/19 12:54 PM, Lennart B?rjeson wrote: >>>> I?m using the tool I wrote to compress directories with thousands >>>> of log files. The standard zip utility (as well as my utility when >>>> run with JDK 12) takes up to an hour of user time to create the >>>> archive, on our server class 40+ core servers this is reduced to >>>> 1?2 minutes. >>>> >>>> So while I understand the motivation for the change, I don?t get >>>> why you would want to use ZipFs for what in essence is a RAM disk, >>>> *unless* you want it compressed in memory? >>>> >>>> Oh well. Do we need a new option for this? >>>> >>>> /Lennart B?rjeson >>>> >>>> Electrogramma ab iPhono meo missum est >>>> >>>>> 16 apr. 2019 kl. 21:44 skrev Xueming Shen : >>>>> >>>>> One of the motivations back then is to speed up the performance of >>>>> accessing >>>>> >>>>> those entries, means you don't have to deflate/inflate those >>>>> new/updated entries >>>>> >>>>> during the lifetime of that zipfilesystem. Those updated entries >>>>> only get compressed >>>>> >>>>> when go to storage. So the regression is more like a trade off of >>>>> performance of >>>>> >>>>> different usages. (it also simplifies the logic on handing >>>>> different types of entries ...) >>>>> >>>>> >>>>> One idea I experimented long time ago for jartool is to >>>>> concurrently write out >>>>> >>>>> entries when need compression ... it does gain some performance >>>>> improvement >>>>> >>>>> on multi-cores, but not lots, as it ends up coming back to the >>>>> main thread to >>>>> >>>>> write out to the underlying filesystem. >>>>> >>>>> >>>>> -Sherman >>>>> >>>>>> On 4/16/19 5:21 AM, Claes Redestad wrote: >>>>>> Both before and after this regression, it seems the default >>>>>> behavior is >>>>>> not to use a temporary file (until ZFS.sync(), which writes to a >>>>>> temp >>>>>> file and then moves it in place, but that's different from what >>>>>> happens >>>>>> with the useTempFile option enabled). Instead entries (and the >>>>>> backing >>>>>> zip file system) are kept in-memory. >>>>>> >>>>>> The cause of the issue here is instead that no deflation happens >>>>>> until >>>>>> sync(), even when writing to entries in-memory. Previously, the >>>>>> deflation happened eagerly, then the result of that was copied into >>>>>> the zip file during sync(). >>>>>> >>>>>> I've written a proof-of-concept patch that restores the behavior of >>>>>> eagerly compressing entries when the method is METHOD_DEFLATED >>>>>> and the >>>>>> target is to store byte[]s in-memory (the default scenario): >>>>>> >>>>>> http://cr.openjdk.java.net/~redestad/scratch/zfs.eager_deflation.00/ >>>>>> >>>>>> This restores performance of parallel zip to that of 11.0.2 for the >>>>>> default case. It still has a similar regression for the case where >>>>>> useTempFile is enabled, but that should be easily addressed if this >>>>>> looks like a way forward? >>>>>> >>>>>> (I've not yet created a bug as I got too caught up in trying to >>>>>> figure >>>>>> out what was going on here...) >>>>>> >>>>>> Thanks! >>>>>> >>>>>> /Claes >>>>>> >>>>>>> On 2019-04-16 09:29, Alan Bateman wrote: >>>>>>>> On 15/04/2019 14:32, Lennart B?rjeson wrote: >>>>>>>> : >>>>>>>> >>>>>>>> Previously, the deflation was done when in the call to >>>>>>>> Files.copy, thus executed in parallel, and the final >>>>>>>> ZipFileSystem.close() didn't do anything much. >>>>>>>> >>>>>>> Can you submit a bug? When creating/updating a zip file with >>>>>>> zipfs then the closing the file system creates the zip file. >>>>>>> Someone needs to check but it may have been that the temporary >>>>>>> files (on the file system hosting the zip file) were deflated >>>>>>> when writing (which is surprising but may have been the case). >>>>>>> >>>>>>> -Alan >> >> >> >> >> 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 sgehwolf at redhat.com Thu Apr 18 07:52:37 2019 From: sgehwolf at redhat.com (Severin Gehwolf) Date: Thu, 18 Apr 2019 09:52:37 +0200 Subject: [PING2] RFR: 8217338: [Containers] Improve systemd slice memory limit support In-Reply-To: References: <4a1ae4e0e3efd68818bfe868349972aa878de60b.camel@redhat.com> <9a911da4b2a4a8eff42c7c2f1a19c06f6521da8d.camel@redhat.com> <226CB44C-7B3A-42E8-8385-4E85168DBA4E@oracle.com> <254f53446176175689373b346c11aabc26d9b4b0.camel@redhat.com> Message-ID: <6a7fce25a4aae4e64b8ca9f248cdf8d633db4132.camel@redhat.com> Hi, On Thu, 2019-04-18 at 09:00 +1000, David Holmes wrote: > So you can add me as a reviewer. Thank you, David! I appreciate that. Cheers, Severin From adinn at redhat.com Thu Apr 18 09:17:56 2019 From: adinn at redhat.com (Andrew Dinn) Date: Thu, 18 Apr 2019 10:17:56 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> Message-ID: <9218d37f-9820-9216-b125-8f3bc2d19e3d@redhat.com> Hi Alan, The CSR for this issue has been finalized and is awaiting approval. Would it now be possible to proceed with reviews of the implementation? JIRA: https://bugs.openjdk.java.net/browse/JDK-8221696 webrev: http://cr.openjdk.java.net/~adinn/8221696/webrev.01 regards, Andrew Dinn ----------- From naoto.sato at oracle.com Thu Apr 18 15:27:12 2019 From: naoto.sato at oracle.com (naoto.sato at oracle.com) Date: Thu, 18 Apr 2019 08:27:12 -0700 Subject: [13] RFR (XXS): 8222668: Add @since tag to JapaneseEra.REIWA Message-ID: <903ed61e-72a9-2bbc-c18c-fd5a12d624a9@oracle.com> Hello, Please review this trivial change to the following issue: https://bugs.openjdk.java.net/browse/JDK-8222668 Here is the one line change to add the @since tag: --- old/src/java.base/share/classes/java/time/chrono/JapaneseEra.java 2019-04-17 13:38:30.000000000 -0700 +++ new/src/java.base/share/classes/java/time/chrono/JapaneseEra.java 2019-04-17 13:38:29.000000000 -0700 @@ -154,6 +154,8 @@ * The singleton instance for the 'Reiwa' era (2019-05-01 - ) * which has the value 3. The end date of this era is not specified, unless * the Japanese Government defines it. + * + * @since 13 */ public static final JapaneseEra REIWA = new JapaneseEra(3, LocalDate.of(2019, 5, 1)); Naoto From chris.hegarty at oracle.com Thu Apr 18 15:34:27 2019 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Thu, 18 Apr 2019 16:34:27 +0100 Subject: [13] RFR (XXS): 8222668: Add @since tag to JapaneseEra.REIWA In-Reply-To: <903ed61e-72a9-2bbc-c18c-fd5a12d624a9@oracle.com> References: <903ed61e-72a9-2bbc-c18c-fd5a12d624a9@oracle.com> Message-ID: <63599D38-402D-4E27-ACD9-B330F298E5BA@oracle.com> > On 18 Apr 2019, at 16:27, naoto.sato at oracle.com wrote: > > Hello, > > Please review this trivial change to the following issue: > > https://bugs.openjdk.java.net/browse/JDK-8222668 > > Here is the one line change to add the @since tag: > > --- old/src/java.base/share/classes/java/time/chrono/JapaneseEra.java 2019-04-17 13:38:30.000000000 -0700 > +++ new/src/java.base/share/classes/java/time/chrono/JapaneseEra.java 2019-04-17 13:38:29.000000000 -0700 > @@ -154,6 +154,8 @@ > * The singleton instance for the 'Reiwa' era (2019-05-01 - ) > * which has the value 3. The end date of this era is not specified, unless > * the Japanese Government defines it. > + * > + * @since 13 > */ > public static final JapaneseEra REIWA = new JapaneseEra(3, LocalDate.of(2019, 5, 1)); Looks good. -Chris. From lance.andersen at oracle.com Thu Apr 18 15:36:03 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 18 Apr 2019 11:36:03 -0400 Subject: [13] RFR (XXS): 8222668: Add @since tag to JapaneseEra.REIWA In-Reply-To: <903ed61e-72a9-2bbc-c18c-fd5a12d624a9@oracle.com> References: <903ed61e-72a9-2bbc-c18c-fd5a12d624a9@oracle.com> Message-ID: <23D0C5CE-E9FD-4F81-AB4D-E135983358F0@oracle.com> +1 > On Apr 18, 2019, at 11:27 AM, naoto.sato at oracle.com wrote: > > Hello, > > Please review this trivial change to the following issue: > > https://bugs.openjdk.java.net/browse/JDK-8222668 > > Here is the one line change to add the @since tag: > > --- old/src/java.base/share/classes/java/time/chrono/JapaneseEra.java 2019-04-17 13:38:30.000000000 -0700 > +++ new/src/java.base/share/classes/java/time/chrono/JapaneseEra.java 2019-04-17 13:38:29.000000000 -0700 > @@ -154,6 +154,8 @@ > * The singleton instance for the 'Reiwa' era (2019-05-01 - ) > * which has the value 3. The end date of this era is not specified, unless > * the Japanese Government defines it. > + * > + * @since 13 > */ > public static final JapaneseEra REIWA = new JapaneseEra(3, LocalDate.of(2019, 5, 1)); > > Naoto 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 raffaello.giulietti at gmail.com Thu Apr 18 18:44:26 2019 From: raffaello.giulietti at gmail.com (Raffaello Giulietti) Date: Thu, 18 Apr 2019 20:44:26 +0200 Subject: [PATCH] 4511638: Double.toString(double) sometimes produces incorrect results In-Reply-To: <4F722010-2DC8-40FB-97BA-5A69500810A7@oracle.com> References: <4F722010-2DC8-40FB-97BA-5A69500810A7@oracle.com> Message-ID: Hi, here's another revision of the patch. Its purpose is to overcome the test failure observed in [1]. To this end, the patch adds FloatToDecimal.appendTo(float, Appendable) and DoubleToDecimal.appendTo(double, Appendable) static methods to help AbstractStringBuilder in using the corrected algorithm implemented in FloatToDecimal.toString(float) and DoubleToDecimal.toString(double), respectively. The implementation has been jmh tested to make sure there are no performance regressions. As there are now only less than two months left before Rampdown 1 for OpenJDK 13, I beg anybody interested in reviewing this patch to contact me for any question or clarification. Also, you might want to take a look at the CSR [2]. As usual, Brian will make the patch available as webrev in the coming hours. Greetings Raffaello ---- [1] https://mail.openjdk.java.net/pipermail/core-libs-dev/2018-September/055715.html [2] https://bugs.openjdk.java.net/browse/JDK-8202555 ---- # HG changeset patch # User lello # Date 1555510586 -7200 # Wed Apr 17 16:16:26 2019 +0200 # Node ID 5b14d1882518bcbe9cc7ed3e63e3e84c7d324a86 # Parent b36e68b34be3e436846ea09db2ba8a041426a899 Patch to fix JDK-4511638 4511638: Double.toString(double) sometimes produces incorrect results Reviewed-by: TBD Contributed-by: Raffaello Giulietti diff --git a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java --- a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java +++ b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java @@ -25,7 +25,10 @@ package java.lang; -import jdk.internal.math.FloatingDecimal; +import jdk.internal.math.DoubleToDecimal; +import jdk.internal.math.FloatToDecimal; + +import java.io.IOException; import java.util.Arrays; import java.util.Spliterator; import java.util.stream.IntStream; @@ -874,7 +877,11 @@ * @return a reference to this object. */ public AbstractStringBuilder append(float f) { - FloatingDecimal.appendTo(f,this); + try { + FloatToDecimal.appendTo(f, this); + } catch (IOException ignored) { + assert false; + } return this; } @@ -891,7 +898,11 @@ * @return a reference to this object. */ public AbstractStringBuilder append(double d) { - FloatingDecimal.appendTo(d,this); + try { + DoubleToDecimal.appendTo(d, this); + } catch (IOException ignored) { + assert false; + } return this; } diff --git a/src/java.base/share/classes/java/lang/Double.java b/src/java.base/share/classes/java/lang/Double.java --- a/src/java.base/share/classes/java/lang/Double.java +++ b/src/java.base/share/classes/java/lang/Double.java @@ -32,6 +32,7 @@ import jdk.internal.math.FloatingDecimal; import jdk.internal.math.DoubleConsts; +import jdk.internal.math.DoubleToDecimal; import jdk.internal.HotSpotIntrinsicCandidate; /** @@ -145,69 +146,120 @@ public static final Class TYPE = (Class) Class.getPrimitiveClass("double"); /** - * Returns a string representation of the {@code double} - * argument. All characters mentioned below are ASCII characters. - *

          - *
        • If the argument is NaN, the result is the string - * "{@code NaN}". - *
        • Otherwise, the result is a string that represents the sign and - * magnitude (absolute value) of the argument. If the sign is negative, - * the first character of the result is '{@code -}' - * ({@code '\u005Cu002D'}); if the sign is positive, no sign character - * appears in the result. As for the magnitude m: - *
            - *
          • If m is infinity, it is represented by the characters - * {@code "Infinity"}; thus, positive infinity produces the result - * {@code "Infinity"} and negative infinity produces the result - * {@code "-Infinity"}. - * - *
          • If m is zero, it is represented by the characters - * {@code "0.0"}; thus, negative zero produces the result - * {@code "-0.0"} and positive zero produces the result - * {@code "0.0"}. + * Returns a string rendering of the {@code double} argument. * - *
          • If m is greater than or equal to 10-3 but less - * than 107, then it is represented as the integer part of - * m, in decimal form with no leading zeroes, followed by - * '{@code .}' ({@code '\u005Cu002E'}), followed by one or - * more decimal digits representing the fractional part of m. - * - *
          • If m is less than 10-3 or greater than or - * equal to 107, then it is represented in so-called - * "computerized scientific notation." Let n be the unique - * integer such that 10nm {@literal <} - * 10n+1; then let a be the - * mathematically exact quotient of m and - * 10n so that 1 ≤ a {@literal <} 10. The - * magnitude is then represented as the integer part of a, - * as a single decimal digit, followed by '{@code .}' - * ({@code '\u005Cu002E'}), followed by decimal digits - * representing the fractional part of a, followed by the - * letter '{@code E}' ({@code '\u005Cu0045'}), followed - * by a representation of n as a decimal integer, as - * produced by the method {@link Integer#toString(int)}. + *

            The characters of the result are all drawn from the ASCII set. + *

              + *
            • Any NaN, whether quiet or signaling, is rendered as + * {@code "NaN"}, regardless of the sign bit. + *
            • The infinities +∞ and -∞ are rendered as + * {@code "Infinity"} and {@code "-Infinity"}, respectively. + *
            • The positive and negative zeroes are rendered as + * {@code "0.0"} and {@code "-0.0"}, respectively. + *
            • A finite negative {@code v} is rendered as the sign + * '{@code -}' followed by the rendering of the magnitude -{@code v}. + *
            • A finite positive {@code v} is rendered in two stages: + *
                + *
              • Selection of a decimal: A well-defined + * decimal dv is selected + * to represent {@code v}. + *
              • Formatting as a string: The decimal + * dv is formatted as a string, + * either in plain or in computerized scientific notation, + * depending on its value. *
              *
            - * How many digits must be printed for the fractional part of - * m or a? There must be at least one digit to represent - * the fractional part, and beyond that as many, but only as many, more - * digits as are needed to uniquely distinguish the argument value from - * adjacent values of type {@code double}. That is, suppose that - * x is the exact mathematical value represented by the decimal - * representation produced by this method for a finite nonzero argument - * d. Then d must be the {@code double} value nearest - * to x; or if two {@code double} values are equally close - * to x, then d must be one of them and the least - * significant bit of the significand of d must be {@code 0}. + * + *

            A decimal is a number of the form + * d×10i + * for some (unique) integers d > 0 and i such that + * d is not a multiple of 10. + * These integers are the significand and + * the exponent, respectively, of the decimal. + * The length of the decimal is the (unique) + * integer n meeting + * 10n-1d < 10n. + * + *

            The decimal dv + * for a finite positive {@code v} is defined as follows: + *

              + *
            • Let R be the set of all decimals that round to {@code v} + * according to the usual round-to-closest rule of + * IEEE 754 floating-point arithmetic. + *
            • Let m be the minimal length over all decimals in R. + *
            • When m ≥ 2, let T be the set of all decimals + * in R with length m. + * Otherwise, let T be the set of all decimals + * in R with length 1 or 2. + *
            • Define dv as + * the decimal in T that is closest to {@code v}. + * Or if there are two such decimals in T, + * select the one with the even significand (there is exactly one). + *
            + * + *

            The (uniquely) selected decimal dv + * is then formatted. * - *

            To create localized string representations of a floating-point - * value, use subclasses of {@link java.text.NumberFormat}. + *

            Let d, i and n be the significand, exponent and + * length of dv, respectively. + * Further, let e = n + i - 1 and let + * d1dn + * be the usual decimal expansion of the significand. + * Note that d1 ≠ 0 ≠ dn. + *

              + *
            • Case -3 ≤ e < 0: + * dv is formatted as + * 0.00d1dn, + * where there are exactly -(n + i) zeroes between + * the decimal point and d1. + * For example, 123 × 10-4 is formatted as + * {@code 0.0123}. + *
            • Case 0 ≤ e < 7: + *
                + *
              • Subcase i ≥ 0: + * dv is formatted as + * d1dn00.0, + * where there are exactly i zeroes + * between dn and the decimal point. + * For example, 123 × 102 is formatted as + * {@code 12300.0}. + *
              • Subcase i < 0: + * dv is formatted as + * d1dn+i.dn+i+1dn. + * There are exactly -i digits to the right of + * the decimal point. + * For example, 123 × 10-1 is formatted as + * {@code 12.3}. + *
              + *
            • Case e < -3 or e ≥ 7: + * computerized scientific notation is used to format + * dv. + * Here e is formatted as by {@link Integer#toString(int)}. + *
                + *
              • Subcase n = 1: + * dv is formatted as + * d1.0Ee. + * For example, 1 × 1023 is formatted as + * {@code 1.0E23}. + *
              • Subcase n > 1: + * dv is formatted as + * d1.d2dnEe. + * For example, 123 × 10-21 is formatted as + * {@code 1.23E-19}. + *
              + *
            * - * @param d the {@code double} to be converted. - * @return a string representation of the argument. + * @param v the {@code double} to be rendered. + * @return a string rendering of the argument. */ - public static String toString(double d) { - return FloatingDecimal.toJavaFormatString(d); + public static String toString(double v) { + return DoubleToDecimal.toString(v); } /** diff --git a/src/java.base/share/classes/java/lang/Float.java b/src/java.base/share/classes/java/lang/Float.java --- a/src/java.base/share/classes/java/lang/Float.java +++ b/src/java.base/share/classes/java/lang/Float.java @@ -31,6 +31,7 @@ import java.util.Optional; import jdk.internal.math.FloatingDecimal; +import jdk.internal.math.FloatToDecimal; import jdk.internal.HotSpotIntrinsicCandidate; /** @@ -142,73 +143,120 @@ public static final Class TYPE = (Class) Class.getPrimitiveClass("float"); /** - * Returns a string representation of the {@code float} - * argument. All characters mentioned below are ASCII characters. - *
              - *
            • If the argument is NaN, the result is the string - * "{@code NaN}". - *
            • Otherwise, the result is a string that represents the sign and - * magnitude (absolute value) of the argument. If the sign is - * negative, the first character of the result is - * '{@code -}' ({@code '\u005Cu002D'}); if the sign is - * positive, no sign character appears in the result. As for - * the magnitude m: + * Returns a string rendering of the {@code float} argument. + * + *

              The characters of the result are all drawn from the ASCII set. *

                - *
              • If m is infinity, it is represented by the characters - * {@code "Infinity"}; thus, positive infinity produces - * the result {@code "Infinity"} and negative infinity - * produces the result {@code "-Infinity"}. - *
              • If m is zero, it is represented by the characters - * {@code "0.0"}; thus, negative zero produces the result - * {@code "-0.0"} and positive zero produces the result - * {@code "0.0"}. - *
              • If m is greater than or equal to 10-3 but - * less than 107, then it is represented as the - * integer part of m, in decimal form with no leading - * zeroes, followed by '{@code .}' - * ({@code '\u005Cu002E'}), followed by one or more - * decimal digits representing the fractional part of - * m. - *
              • If m is less than 10-3 or greater than or - * equal to 107, then it is represented in - * so-called "computerized scientific notation." Let n - * be the unique integer such that 10n ≤ - * m {@literal <} 10n+1; then let a - * be the mathematically exact quotient of m and - * 10n so that 1 ≤ a {@literal <} 10. - * The magnitude is then represented as the integer part of - * a, as a single decimal digit, followed by - * '{@code .}' ({@code '\u005Cu002E'}), followed by - * decimal digits representing the fractional part of - * a, followed by the letter '{@code E}' - * ({@code '\u005Cu0045'}), followed by a representation - * of n as a decimal integer, as produced by the - * method {@link java.lang.Integer#toString(int)}. - * + *
              • Any NaN, whether quiet or signaling, is rendered as + * {@code "NaN"}, regardless of the sign bit. + *
              • The infinities +∞ and -∞ are rendered as + * {@code "Infinity"} and {@code "-Infinity"}, respectively. + *
              • The positive and negative zeroes are rendered as + * {@code "0.0"} and {@code "-0.0"}, respectively. + *
              • A finite negative {@code v} is rendered as the sign + * '{@code -}' followed by the rendering of the magnitude -{@code v}. + *
              • A finite positive {@code v} is rendered in two stages: + *
                  + *
                • Selection of a decimal: A well-defined + * decimal dv is selected + * to represent {@code v}. + *
                • Formatting as a string: The decimal + * dv is formatted as a string, + * either in plain or in computerized scientific notation, + * depending on its value. *
                *
              - * How many digits must be printed for the fractional part of - * m or a? There must be at least one digit - * to represent the fractional part, and beyond that as many, but - * only as many, more digits as are needed to uniquely distinguish - * the argument value from adjacent values of type - * {@code float}. That is, suppose that x is the - * exact mathematical value represented by the decimal - * representation produced by this method for a finite nonzero - * argument f. Then f must be the {@code float} - * value nearest to x; or, if two {@code float} values are - * equally close to x, then f must be one of - * them and the least significant bit of the significand of - * f must be {@code 0}. + * + *

              A decimal is a number of the form + * d×10i + * for some (unique) integers d > 0 and i such that + * d is not a multiple of 10. + * These integers are the significand and + * the exponent, respectively, of the decimal. + * The length of the decimal is the (unique) + * integer n meeting + * 10n-1d < 10n. + * + *

              The decimal dv + * for a finite positive {@code v} is defined as follows: + *

                + *
              • Let R be the set of all decimals that round to {@code v} + * according to the usual round-to-closest rule of + * IEEE 754 floating-point arithmetic. + *
              • Let m be the minimal length over all decimals in R. + *
              • When m ≥ 2, let T be the set of all decimals + * in R with length m. + * Otherwise, let T be the set of all decimals + * in R with length 1 or 2. + *
              • Define dv as + * the decimal in T that is closest to {@code v}. + * Or if there are two such decimals in T, + * select the one with the even significand (there is exactly one). + *
              + * + *

              The (uniquely) selected decimal dv + * is then formatted. * - *

              To create localized string representations of a floating-point - * value, use subclasses of {@link java.text.NumberFormat}. + *

              Let d, i and n be the significand, exponent and + * length of dv, respectively. + * Further, let e = n + i - 1 and let + * d1dn + * be the usual decimal expansion of the significand. + * Note that d1 ≠ 0 ≠ dn. + *

                + *
              • Case -3 ≤ e < 0: + * dv is formatted as + * 0.00d1dn, + * where there are exactly -(n + i) zeroes between + * the decimal point and d1. + * For example, 123 × 10-4 is formatted as + * {@code 0.0123}. + *
              • Case 0 ≤ e < 7: + *
                  + *
                • Subcase i ≥ 0: + * dv is formatted as + * d1dn00.0, + * where there are exactly i zeroes + * between dn and the decimal point. + * For example, 123 × 102 is formatted as + * {@code 12300.0}. + *
                • Subcase i < 0: + * dv is formatted as + * d1dn+i.dn+i+1dn. + * There are exactly -i digits to the right of + * the decimal point. + * For example, 123 × 10-1 is formatted as + * {@code 12.3}. + *
                + *
              • Case e < -3 or e ≥ 7: + * computerized scientific notation is used to format + * dv. + * Here e is formatted as by {@link Integer#toString(int)}. + *
                  + *
                • Subcase n = 1: + * dv is formatted as + * d1.0Ee. + * For example, 1 × 1023 is formatted as + * {@code 1.0E23}. + *
                • Subcase n > 1: + * dv is formatted as + * d1.d2dnEe. + * For example, 123 × 10-21 is formatted as + * {@code 1.23E-19}. + *
                + *
              * - * @param f the float to be converted. - * @return a string representation of the argument. + * @param v the {@code float} to be rendered. + * @return a string rendering of the argument. */ - public static String toString(float f) { - return FloatingDecimal.toJavaFormatString(f); + public static String toString(float v) { + return FloatToDecimal.toString(v); } /** diff --git a/src/java.base/share/classes/jdk/internal/math/DoubleToDecimal.java b/src/java.base/share/classes/jdk/internal/math/DoubleToDecimal.java new file mode 100644 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/math/DoubleToDecimal.java @@ -0,0 +1,642 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +import java.io.IOException; + +import static java.lang.Double.*; +import static java.lang.Long.*; +import static java.lang.Math.multiplyHigh; +import static jdk.internal.math.MathUtils.*; + +/** + * This class exposes a method to render a {@code double} as a string. + * + * @author Raffaello Giulietti + */ +final public class DoubleToDecimal { + /* + For full details about this code see the following references: + + [1] Giulietti, "The Schubfach way to render doubles", + https://drive.google.com/open?id=1KLtG_LaIbK9ETXI290zqCxvBW94dj058 + + [2] IEEE Computer Society, "IEEE Standard for Floating-Point Arithmetic" + + [3] Bouvier & Zimmermann, "Division-Free Binary-to-Decimal Conversion" + + Divisions are avoided for the benefit of those architectures that do not + provide specific machine instructions or where they are slow. + This is discussed in section 10 of [1]. + */ + + // The precision in bits. + static final int P = 53; + + // H is as in section 8 of [1]. + static final int H = 17; + + // 10^(MIN_EXP - 1) <= MIN_VALUE < 10^MIN_EXP + static final int MIN_EXP = -323; + + // 10^(MAX_EXP - 1) <= MAX_VALUE < 10^MAX_EXP + static final int MAX_EXP = 309; + + // Exponent width in bits. + private static final int W = (Double.SIZE - 1) - (P - 1); + + // Minimum value of the exponent: -(2^(W-1)) - P + 3. + private static final int Q_MIN = (-1 << W - 1) - P + 3; + + // Minimum value of the significand of a normal value: 2^(P-1). + private static final long C_MIN = 1L << P - 1; + + // Mask to extract the biased exponent. + private static final int BQ_MASK = (1 << W) - 1; + + // Mask to extract the fraction bits. + private static final long T_MASK = (1L << P - 1) - 1; + + // Used in rop(). + private static final long MASK_63 = (1L << 63) - 1; + + // Used for left-to-tight digit extraction. + private static final int MASK_28 = (1 << 28) - 1; + + private static final int NON_SPECIAL = 0; + private static final int PLUS_ZERO = 1; + private static final int MINUS_ZERO = 2; + private static final int PLUS_INF = 3; + private static final int MINUS_INF = 4; + private static final int NAN = 5; + + // For thread-safety, each thread gets its own instance of this class. + private static final ThreadLocal threadLocal = + ThreadLocal.withInitial(DoubleToDecimal::new); + + /* + Room for the longer of the forms + -ddddd.dddddddddddd H + 2 characters + -0.00ddddddddddddddddd H + 5 characters + -d.ddddddddddddddddE-eee H + 7 characters + -Infinity + NaN + where there are H digits d + */ + public final int MAX_CHARS = H + 7; + + // Numerical results are created here... + private final byte[] bytes = new byte[MAX_CHARS]; + + // ... and copied here in appendTo() + private final char[] chars = new char[MAX_CHARS]; + + // Index into bytes of rightmost valid character. + private int index; + + private DoubleToDecimal() { + } + + /** + * Returns a string rendering of the {@code double} argument. + * + *

              The characters of the result are all drawn from the ASCII set. + *

                + *
              • Any NaN, whether quiet or signaling, is rendered as + * {@code "NaN"}, regardless of the sign bit. + *
              • The infinities +∞ and -∞ are rendered as + * {@code "Infinity"} and {@code "-Infinity"}, respectively. + *
              • The positive and negative zeroes are rendered as + * {@code "0.0"} and {@code "-0.0"}, respectively. + *
              • A finite negative {@code v} is rendered as the sign + * '{@code -}' followed by the rendering of the magnitude -{@code v}. + *
              • A finite positive {@code v} is rendered in two stages: + *
                  + *
                • Selection of a decimal: A well-defined + * decimal dv is selected + * to represent {@code v}. + *
                • Formatting as a string: The decimal + * dv is formatted as a string, + * either in plain or in computerized scientific notation, + * depending on its value. + *
                + *
              + * + *

              A decimal is a number of the form + * d×10i + * for some (unique) integers d > 0 and i such that + * d is not a multiple of 10. + * These integers are the significand and + * the exponent, respectively, of the decimal. + * The length of the decimal is the (unique) + * integer n meeting + * 10n-1d < 10n. + * + *

              The decimal dv + * for a finite positive {@code v} is defined as follows: + *

                + *
              • Let R be the set of all decimals that round to {@code v} + * according to the usual round-to-closest rule of + * IEEE 754 floating-point arithmetic. + *
              • Let m be the minimal length over all decimals in R. + *
              • When m ≥ 2, let T be the set of all decimals + * in R with length m. + * Otherwise, let T be the set of all decimals + * in R with length 1 or 2. + *
              • Define dv as + * the decimal in T that is closest to {@code v}. + * Or if there are two such decimals in T, + * select the one with the even significand (there is exactly one). + *
              + * + *

              The (uniquely) selected decimal dv + * is then formatted. + * + *

              Let d, i and n be the significand, exponent and + * length of dv, respectively. + * Further, let e = n + i - 1 and let + * d1dn + * be the usual decimal expansion of the significand. + * Note that d1 ≠ 0 ≠ dn. + *

                + *
              • Case -3 ≤ e < 0: + * dv is formatted as + * 0.00d1dn, + * where there are exactly -(n + i) zeroes between + * the decimal point and d1. + * For example, 123 × 10-4 is formatted as + * {@code 0.0123}. + *
              • Case 0 ≤ e < 7: + *
                  + *
                • Subcase i ≥ 0: + * dv is formatted as + * d1dn00.0, + * where there are exactly i zeroes + * between dn and the decimal point. + * For example, 123 × 102 is formatted as + * {@code 12300.0}. + *
                • Subcase i < 0: + * dv is formatted as + * d1dn+i.dn+i+1dn. + * There are exactly -i digits to the right of + * the decimal point. + * For example, 123 × 10-1 is formatted as + * {@code 12.3}. + *
                + *
              • Case e < -3 or e ≥ 7: + * computerized scientific notation is used to format + * dv. + * Here e is formatted as by {@link Integer#toString(int)}. + *
                  + *
                • Subcase n = 1: + * dv is formatted as + * d1.0Ee. + * For example, 1 × 1023 is formatted as + * {@code 1.0E23}. + *
                • Subcase n > 1: + * dv is formatted as + * d1.d2dnEe. + * For example, 123 × 10-21 is formatted as + * {@code 1.23E-19}. + *
                + *
              + * + * @param v the {@code double} to be rendered. + * @return a string rendering of the argument. + */ + public static String toString(double v) { + return threadLocalInstance().toDecimalString(v); + } + + /** + * Appends the rendering of the {@code v} to {@code app}. + * + *

              The outcome is the same as if {@code v} were first + * {@link #toString(double) rendered} and the resulting string were then + * {@link Appendable#append(CharSequence) appended} to {@code app}. + * + * @param v the {@code double} whose rendering is appended. + * @param app the {@link Appendable} to append to. + * @throws IOException If an I/O error occurs + */ + public static Appendable appendTo(double v, Appendable app) + throws IOException { + return threadLocalInstance().appendDecimalTo(v, app); + } + + private static DoubleToDecimal threadLocalInstance() { + return threadLocal.get(); + } + + private String toDecimalString(double v) { + switch (toDecimal(v)) { + case NON_SPECIAL: return charsToString(); + case PLUS_ZERO: return "0.0"; + case MINUS_ZERO: return "-0.0"; + case PLUS_INF: return "Infinity"; + case MINUS_INF: return "-Infinity"; + default: return "NaN"; + } + } + + private Appendable appendDecimalTo(double v, Appendable app) + throws IOException { + switch (toDecimal(v)) { + case NON_SPECIAL: + for (int i = 0; i <= index; ++i) { + chars[i] = (char) bytes[i]; + } + if (app instanceof StringBuilder) { + return ((StringBuilder) app).append(chars, 0, index + 1); + } + if (app instanceof StringBuffer) { + return ((StringBuffer) app).append(chars, 0, index + 1); + } + for (int i = 0; i <= index; ++i) { + app.append(chars[i]); + } + return app; + case PLUS_ZERO: return app.append("0.0"); + case MINUS_ZERO: return app.append("-0.0"); + case PLUS_INF: return app.append("Infinity"); + case MINUS_INF: return app.append("-Infinity"); + default: return app.append("NaN"); + } + } + + private int toDecimal(double v) { + /* + For full details see references [2] and [1]. + + Let + Q_MAX = 2^(W-1) - P + For finite v != 0, determine integers c and q such that + |v| = c 2^q and + Q_MIN <= q <= Q_MAX and + either 2^(P-1) <= c < 2^P (normal) + or 0 < c < 2^(P-1) and q = Q_MIN (subnormal) + */ + long bits = doubleToRawLongBits(v); + long t = bits & T_MASK; + int bq = (int) (bits >>> P - 1) & BQ_MASK; + if (bq < BQ_MASK) { + index = -1; + if (bits < 0) { + append('-'); + } + if (bq != 0) { + // normal value. Here mq = -q + int mq = -Q_MIN + 1 - bq; + long c = C_MIN | t; + // The fast path discussed in section 8.3 of [1]. + if (0 < mq & mq < P) { + long f = c >> mq; + if (f << mq == c) { + return toChars(f, 0); + } + } + return toDecimal(-mq, c); + } + if (t != 0) { + // subnormal value + return toDecimal(Q_MIN, t); + } + return bits == 0 ? PLUS_ZERO : MINUS_ZERO; + } + if (t != 0) { + return NAN; + } + return bits > 0 ? PLUS_INF : MINUS_INF; + } + + private int toDecimal(int q, long c) { + /* + The skeleton corresponds to figure 4 of [1]. + The efficient computations are those summarized in figure 7. + + Here's a correspondence between Java names and names in [1], + expressed as approximate LaTeX source code and informally. + Other names are identical. + cb: \bar{c} "c-bar" + cbr: \bar{c}_r "c-bar-r" + cbl: \bar{c}_l "c-bar-l" + + vb: \bar{v} "v-bar" + vbr: \bar{v}_r "v-bar-r" + vbl: \bar{v}_l "v-bar-l" + + rop: r_o' "r-o-prime" + */ + int out = (int) c & 0x1; + long cb; + long cbr; + long cbl; + int k; + int h; + /* + flog10pow2(e) = floor(log_10(2^e)) + flog10threeQuartersPow2(e) = floor(log_10(3/4 2^e)) + flog2pow10(e) = floor(log_2(10^e)) + */ + if (c != C_MIN | q == Q_MIN) { + // regular spacing + cb = c << 1; + cbr = cb + 1; + k = flog10pow2(q); + h = q + flog2pow10(-k) + 3; + } else { + // irregular spacing + cb = c << 2; + cbr = cb + 2; + k = flog10threeQuartersPow2(q); + h = q + flog2pow10(-k) + 2; + } + cbl = cb - 1; + + // g1 and g0 are as in section 9.8.3, so g = g1 2^63 + g0 + long g1 = g1(-k); + long g0 = g0(-k); + + long vb = rop(g1, g0, cb << h); + long vbl = rop(g1, g0, cbl << h); + long vbr = rop(g1, g0, cbr << h); + + long s = vb >> 2; + if (s >= 100) { + /* + For n = 17, m = 1 the table in section 10 of [1] shows + s' = + floor(s / 10) = floor(s 115'292'150'460'684'698 / 2^60) = + floor(s 115'292'150'460'684'698 2^4 / 2^64) + + sp10 = 10 s', tp10 = 10 t' = sp10 + 10 + upin iff u' = sp10 10^k in Rv + wpin iff w' = tp10 10^k in Rv + See section 9.3. + */ + long sp10 = 10 * multiplyHigh(s, 115_292_150_460_684_698L << 4); + long tp10 = sp10 + 10; + boolean upin = vbl + out <= sp10 << 2; + boolean wpin = (tp10 << 2) + out <= vbr; + if (upin != wpin) { + return toChars(upin ? sp10 : tp10, k); + } + } else if (s < 10) { + switch ((int) s) { + case 4: + return toChars(49, -325); // 4.9 10^(-324) + case 9: + return toChars(99, -325); // 9.9 10^(-324) + } + } + + /* + 10 <= s < 100 or s >= 100 and u', w' not in Rv + uin iff u = s 10^k in Rv + win iff w = t 10^k in Rv + See section 9.3. + */ + long t = s + 1; + boolean uin = vbl + out <= s << 2; + boolean win = (t << 2) + out <= vbr; + if (uin != win) { + // Exactly one of u or w lies in Rv. + return toChars(uin ? s : t, k); + } + /* + Both u and w lie in Rv: determine the one closest to v. + See section 9.3. + */ + long cmp = vb - (s + t << 1); + return toChars(cmp < 0 || cmp == 0 && (s & 0x1) == 0 ? s : t, k); + } + + /* + Computes rop(cp g 2^(-127)), where g = g1 2^63 + g0 + See section 9.9 and figure 6 of [1]. + */ + private static long rop(long g1, long g0, long cp) { + long x1 = multiplyHigh(g0, cp); + long y0 = g1 * cp; + long y1 = multiplyHigh(g1, cp); + long z = (y0 >>> 1) + x1; + long vbp = y1 + (z >>> 63); + return vbp | (z & MASK_63) + MASK_63 >>> 63; + } + + /* + Formats the decimal f 10^e. + */ + private int toChars(long f, int e) { + /* + For details not discussed here see section 10 of [1]. + + Determine len such that + 10^(len-1) <= f < 10^len + */ + int len = flog10pow2(Long.SIZE - numberOfLeadingZeros(f)); + if (f >= pow10(len)) { + len += 1; + } + + /* + Let fp and ep be the original f and e, respectively. + Transform f and e to ensure + 10^(H-1) <= f < 10^H + fp 10^ep = f 10^(e-H) = 0.f 10^e + */ + f *= pow10(H - len); + e += len; + + /* + The toChars?() methods perform left-to-right digits extraction + using ints, provided that the arguments are limited to 8 digits. + Therefore, split the H = 17 digits of f into: + h = the most significant digit of f + m = the next 8 most significant digits of f + l = the last 8, least significant digits of f + + For n = 17, m = 8 the table in section 10 of [1] shows + floor(f / 10^8) = floor(193'428'131'138'340'668 f / 2^84) = + floor(floor(193'428'131'138'340'668 f / 2^64) / 2^20) + and for n = 9, m = 8 + floor(hm / 10^8) = floor(1'441'151'881 hm / 2^57) + */ + long hm = multiplyHigh(f, 193_428_131_138_340_668L) >>> 20; + int l = (int) (f - 100_000_000L * hm); + int h = (int) (hm * 1_441_151_881L >>> 57); + int m = (int) (hm - 100_000_000 * h); + + if (0 < e && e <= 7) { + return toChars1(h, m, l, e); + } + if (-3 < e && e <= 0) { + return toChars2(h, m, l, e); + } + return toChars3(h, m, l, e); + } + + private int toChars1(int h, int m, int l, int e) { + /* + 0 < e <= 7: plain format without leading zeroes. + Left-to-right digits extraction: + algorithm 1 in [3], with b = 10, k = 8, n = 28. + */ + appendDigit(h); + int y = y(m); + int t; + int i = 1; + for (; i < e; ++i) { + t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + append('.'); + for (; i <= 8; ++i) { + t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + lowDigits(l); + return NON_SPECIAL; + } + + private int toChars2(int h, int m, int l, int e) { + // -3 < e <= 0: plain format with leading zeroes. + appendDigit(0); + append('.'); + for (; e < 0; ++e) { + appendDigit(0); + } + appendDigit(h); + append8Digits(m); + lowDigits(l); + return NON_SPECIAL; + } + + private int toChars3(int h, int m, int l, int e) { + // -3 >= e | e > 7: computerized scientific notation + appendDigit(h); + append('.'); + append8Digits(m); + lowDigits(l); + exponent(e - 1); + return NON_SPECIAL; + } + + private void lowDigits(int l) { + if (l != 0) { + append8Digits(l); + } + removeTrailingZeroes(); + } + + private void append8Digits(int m) { + /* + Left-to-right digits extraction: + algorithm 1 in [3], with b = 10, k = 8, n = 28. + */ + int y = y(m); + for (int i = 0; i < 8; ++i) { + int t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + } + + private void removeTrailingZeroes() { + while (bytes[index] == '0') { + --index; + } + // ... but do not remove the one directly to the right of '.' + if (bytes[index] == '.') { + ++index; + } + } + + private int y(int a) { + /* + Algorithm 1 in [3] needs computation of + floor((a + 1) 2^n / b^k) - 1 + with a < 10^8, b = 10, k = 8, n = 28. + Noting that + (a + 1) 2^n <= 10^8 2^28 < 10^17 + For n = 17, m = 8 the table in section 10 of [1] leads to: + */ + return (int) (multiplyHigh( + (long) (a + 1) << 28, + 193_428_131_138_340_668L) >>> 20) - 1; + } + + private void exponent(int e) { + append('E'); + if (e < 0) { + append('-'); + e = -e; + } + if (e < 10) { + appendDigit(e); + return; + } + int d; + if (e >= 100) { + /* + For n = 3, m = 2 the table in section 10 of [1] shows + floor(e / 100) = floor(1'311 e / 2^17) + */ + d = e * 1_311 >>> 17; + appendDigit(d); + e -= 100 * d; + } + /* + For n = 2, m = 1 the table in section 10 of [1] shows + floor(e / 10) = floor(103 e / 2^10) + */ + d = e * 103 >>> 10; + appendDigit(d); + appendDigit(e - 10 * d); + } + + private void append(int c) { + bytes[++index] = (byte) c; + } + + private void appendDigit(int d) { + bytes[++index] = (byte) ('0' + d); + } + + /* + Using the deprecated constructor enhances performance. + */ + @SuppressWarnings("deprecation") + private String charsToString() { + return new String(bytes, 0, 0, index + 1); + } + +} diff --git a/src/java.base/share/classes/jdk/internal/math/FloatToDecimal.java b/src/java.base/share/classes/jdk/internal/math/FloatToDecimal.java new file mode 100644 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/math/FloatToDecimal.java @@ -0,0 +1,618 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +import java.io.IOException; + +import static java.lang.Float.*; +import static java.lang.Integer.*; +import static java.lang.Math.multiplyHigh; +import static jdk.internal.math.MathUtils.*; + +/** + * This class exposes a method to render a {@code float} as a string. + * + * @author Raffaello Giulietti + */ +final public class FloatToDecimal { + /* + For full details about this code see the following references: + + [1] Giulietti, "The Schubfach way to render doubles", + https://drive.google.com/open?id=1KLtG_LaIbK9ETXI290zqCxvBW94dj058 + + [2] IEEE Computer Society, "IEEE Standard for Floating-Point Arithmetic" + + [3] Bouvier & Zimmermann, "Division-Free Binary-to-Decimal Conversion" + + Divisions are avoided for the benefit of those architectures that do not + provide specific machine instructions or where they are slow. + This is discussed in section 10 of [1]. + */ + + // The precision in bits. + static final int P = 24; + + // H is as in section 8 of [1]. + static final int H = 9; + + // 10^(MIN_EXP - 1) <= MIN_VALUE < 10^MIN_EXP + static final int MIN_EXP = -44; + + // 10^(MAX_EXP - 1) <= MAX_VALUE < 10^MAX_EXP + static final int MAX_EXP = 39; + + // Exponent width in bits. + private static final int W = (Float.SIZE - 1) - (P - 1); + + // Minimum value of the exponent: -(2^(W-1)) - P + 3. + private static final int Q_MIN = (-1 << W - 1) - P + 3; + + // Minimum value of the significand of a normal value: 2^(P-1). + private static final int C_MIN = 1 << P - 1; + + // Mask to extract the biased exponent. + private static final int BQ_MASK = (1 << W) - 1; + + // Mask to extract the fraction bits. + private static final int T_MASK = (1 << P - 1) - 1; + + // Used in rop(). + private static final long MASK_32 = (1L << 32) - 1; + + // Used for left-to-tight digit extraction. + private static final int MASK_28 = (1 << 28) - 1; + + private static final int NON_SPECIAL = 0; + private static final int PLUS_ZERO = 1; + private static final int MINUS_ZERO = 2; + private static final int PLUS_INF = 3; + private static final int MINUS_INF = 4; + private static final int NAN = 5; + + // For thread-safety, each thread gets its own instance of this class. + private static final ThreadLocal threadLocal = + ThreadLocal.withInitial(FloatToDecimal::new); + + /* + Room for the longer of + -ddddd.dddd H + 2 characters + -0.00ddddddddd H + 5 characters + -d.ddddddddE-ee H + 6 characters + -Infinity + NaN + where there are H digits d + */ + public final int MAX_CHARS = H + 6; + + // Numerical results are created here... + private final byte[] bytes = new byte[MAX_CHARS]; + + // ... and copied here in appendTo() + private final char[] chars = new char[MAX_CHARS]; + + // Index into bytes of rightmost valid character. + private int index; + + private FloatToDecimal() { + } + + /** + * Returns a string rendering of the {@code float} argument. + * + *

              The characters of the result are all drawn from the ASCII set. + *

                + *
              • Any NaN, whether quiet or signaling, is rendered as + * {@code "NaN"}, regardless of the sign bit. + *
              • The infinities +∞ and -∞ are rendered as + * {@code "Infinity"} and {@code "-Infinity"}, respectively. + *
              • The positive and negative zeroes are rendered as + * {@code "0.0"} and {@code "-0.0"}, respectively. + *
              • A finite negative {@code v} is rendered as the sign + * '{@code -}' followed by the rendering of the magnitude -{@code v}. + *
              • A finite positive {@code v} is rendered in two stages: + *
                  + *
                • Selection of a decimal: A well-defined + * decimal dv is selected + * to represent {@code v}. + *
                • Formatting as a string: The decimal + * dv is formatted as a string, + * either in plain or in computerized scientific notation, + * depending on its value. + *
                + *
              + * + *

              A decimal is a number of the form + * d×10i + * for some (unique) integers d > 0 and i such that + * d is not a multiple of 10. + * These integers are the significand and + * the exponent, respectively, of the decimal. + * The length of the decimal is the (unique) + * integer n meeting + * 10n-1d < 10n. + * + *

              The decimal dv + * for a finite positive {@code v} is defined as follows: + *

                + *
              • Let R be the set of all decimals that round to {@code v} + * according to the usual round-to-closest rule of + * IEEE 754 floating-point arithmetic. + *
              • Let m be the minimal length over all decimals in R. + *
              • When m ≥ 2, let T be the set of all decimals + * in R with length m. + * Otherwise, let T be the set of all decimals + * in R with length 1 or 2. + *
              • Define dv as + * the decimal in T that is closest to {@code v}. + * Or if there are two such decimals in T, + * select the one with the even significand (there is exactly one). + *
              + * + *

              The (uniquely) selected decimal dv + * is then formatted. + * + *

              Let d, i and n be the significand, exponent and + * length of dv, respectively. + * Further, let e = n + i - 1 and let + * d1dn + * be the usual decimal expansion of the significand. + * Note that d1 ≠ 0 ≠ dn. + *

                + *
              • Case -3 ≤ e < 0: + * dv is formatted as + * 0.00d1dn, + * where there are exactly -(n + i) zeroes between + * the decimal point and d1. + * For example, 123 × 10-4 is formatted as + * {@code 0.0123}. + *
              • Case 0 ≤ e < 7: + *
                  + *
                • Subcase i ≥ 0: + * dv is formatted as + * d1dn00.0, + * where there are exactly i zeroes + * between dn and the decimal point. + * For example, 123 × 102 is formatted as + * {@code 12300.0}. + *
                • Subcase i < 0: + * dv is formatted as + * d1dn+i.dn+i+1dn. + * There are exactly -i digits to the right of + * the decimal point. + * For example, 123 × 10-1 is formatted as + * {@code 12.3}. + *
                + *
              • Case e < -3 or e ≥ 7: + * computerized scientific notation is used to format + * dv. + * Here e is formatted as by {@link Integer#toString(int)}. + *
                  + *
                • Subcase n = 1: + * dv is formatted as + * d1.0Ee. + * For example, 1 × 1023 is formatted as + * {@code 1.0E23}. + *
                • Subcase n > 1: + * dv is formatted as + * d1.d2dnEe. + * For example, 123 × 10-21 is formatted as + * {@code 1.23E-19}. + *
                + *
              + * + * @param v the {@code float} to be rendered. + * @return a string rendering of the argument. + */ + public static String toString(float v) { + return threadLocalInstance().toDecimalString(v); + } + + /** + * Appends the rendering of the {@code v} to {@code app}. + * + *

              The outcome is the same as if {@code v} were first + * {@link #toString(float) rendered} and the resulting string were then + * {@link Appendable#append(CharSequence) appended} to {@code app}. + * + * @param v the {@code float} whose rendering is appended. + * @param app the {@link Appendable} to append to. + * @throws IOException If an I/O error occurs + */ + public static Appendable appendTo(float v, Appendable app) + throws IOException { + return threadLocalInstance().appendDecimalTo(v, app); + } + + private static FloatToDecimal threadLocalInstance() { + return threadLocal.get(); + } + + private String toDecimalString(float v) { + switch (toDecimal(v)) { + case NON_SPECIAL: return charsToString(); + case PLUS_ZERO: return "0.0"; + case MINUS_ZERO: return "-0.0"; + case PLUS_INF: return "Infinity"; + case MINUS_INF: return "-Infinity"; + default: return "NaN"; + } + } + + private Appendable appendDecimalTo(float v, Appendable app) + throws IOException { + switch (toDecimal(v)) { + case NON_SPECIAL: + for (int i = 0; i <= index; ++i) { + chars[i] = (char) bytes[i]; + } + if (app instanceof StringBuilder) { + return ((StringBuilder) app).append(chars, 0, index + 1); + } + if (app instanceof StringBuffer) { + return ((StringBuffer) app).append(chars, 0, index + 1); + } + for (int i = 0; i <= index; ++i) { + app.append(chars[i]); + } + return app; + case PLUS_ZERO: return app.append("0.0"); + case MINUS_ZERO: return app.append("-0.0"); + case PLUS_INF: return app.append("Infinity"); + case MINUS_INF: return app.append("-Infinity"); + default: return app.append("NaN"); + } + } + + private int toDecimal(float v) { + /* + For full details see references [2] and [1]. + + Let + Q_MAX = 2^(W-1) - P + For finite v != 0, determine integers c and q such that + |v| = c 2^q and + Q_MIN <= q <= Q_MAX and + either 2^(P-1) <= c < 2^P (normal) + or 0 < c < 2^(P-1) and q = Q_MIN (subnormal) + */ + int bits = floatToRawIntBits(v); + int t = bits & T_MASK; + int bq = (bits >>> P - 1) & BQ_MASK; + if (bq < BQ_MASK) { + index = -1; + if (bits < 0) { + append('-'); + } + if (bq != 0) { + // normal value. Here mq = -q + int mq = -Q_MIN + 1 - bq; + int c = C_MIN | t; + // The fast path discussed in section 8.3 of [1]. + if (0 < mq & mq < P) { + int f = c >> mq; + if (f << mq == c) { + return toChars(f, 0); + } + } + return toDecimal(-mq, c); + } + if (t != 0) { + // subnormal value + return toDecimal(Q_MIN, t); + } + return bits == 0 ? PLUS_ZERO : MINUS_ZERO; + } + if (t != 0) { + return NAN; + } + return bits > 0 ? PLUS_INF : MINUS_INF; + } + + private int toDecimal(int q, int c) { + /* + The skeleton corresponds to figure 4 of [1]. + The efficient computations are those summarized in figure 7. + Also check the appendix. + + Here's a correspondence between Java names and names in [1], + expressed as approximate LaTeX source code and informally. + Other names are identical. + cb: \bar{c} "c-bar" + cbr: \bar{c}_r "c-bar-r" + cbl: \bar{c}_l "c-bar-l" + + vb: \bar{v} "v-bar" + vbr: \bar{v}_r "v-bar-r" + vbl: \bar{v}_l "v-bar-l" + + rop: r_o' "r-o-prime" + */ + int out = c & 0x1; + long cb; + long cbr; + long cbl; + int k; + int h; + /* + flog10pow2(e) = floor(log_10(2^e)) + flog10threeQuartersPow2(e) = floor(log_10(3/4 2^e)) + flog2pow10(e) = floor(log_2(10^e)) + */ + if (c != C_MIN | q == Q_MIN) { + // regular spacing + cb = c << 1; + cbr = cb + 1; + k = flog10pow2(q); + h = q + flog2pow10(-k) + 34; + } else { + // irregular spacing + cb = c << 2; + cbr = cb + 2; + k = flog10threeQuartersPow2(q); + h = q + flog2pow10(-k) + 33; + } + cbl = cb - 1; + + // g is as in the appendix + long g = g1(-k) + 1; + + int vb = rop(g, cb << h); + int vbl = rop(g, cbl << h); + int vbr = rop(g, cbr << h); + + int s = vb >> 2; + if (s >= 100) { + /* + For n = 9, m = 1 the table in section 10 of [1] shows + s' = + floor(s / 10) = floor(s 1'717'986'919 / 2^34) + + sp10 = 10 s', tp10 = 10 t' = sp10 + 10 + upin iff u' = sp10 10^k in Rv + wpin iff w' = tp10 10^k in Rv + See section 9.3. + */ + int sp10 = 10 * (int) (s * 1_717_986_919L >>> 34); + int tp10 = sp10 + 10; + boolean upin = vbl + out <= sp10 << 2; + boolean wpin = (tp10 << 2) + out <= vbr; + if (upin != wpin) { + return toChars(upin ? sp10 : tp10, k); + } + } else if (s < 10) { + switch (s) { + case 1: return toChars(14, -46); // 1.4 * 10^-45 + case 2: return toChars(28, -46); // 2.8 * 10^-45 + case 4: return toChars(42, -46); // 4.2 * 10^-45 + case 5: return toChars(56, -46); // 5.6 * 10^-45 + case 7: return toChars(70, -46); // 7.0 * 10^-45 + case 8: return toChars(84, -46); // 8.4 * 10^-45 + case 9: return toChars(98, -46); // 9.8 * 10^-45 + } + } + + /* + 10 <= s < 100 or s >= 100 and u', w' not in Rv + uin iff u = s 10^k in Rv + win iff w = t 10^k in Rv + See section 9.3. + */ + int t = s + 1; + boolean uin = vbl + out <= s << 2; + boolean win = (t << 2) + out <= vbr; + if (uin != win) { + // Exactly one of u or w lies in Rv. + return toChars(uin ? s : t, k); + } + /* + Both u and w lie in Rv: determine the one closest to v. + See section 9.3. + */ + int cmp = vb - (s + t << 1); + return toChars(cmp < 0 || cmp == 0 && (s & 0x1) == 0 ? s : t, k); + } + + /* + Computes rop(cp g 2^(-95)) + See appendix and figure 9 of [1]. + */ + private static int rop(long g, long cp) { + long x1 = multiplyHigh(g, cp); + long vbp = x1 >>> 31; + return (int) (vbp | (x1 & MASK_32) + MASK_32 >>> 32); + } + + /* + Formats the decimal f 10^e. + */ + private int toChars(int f, int e) { + /* + For details not discussed here see section 10 of [1]. + + Determine len such that + 10^(len-1) <= f < 10^len + */ + int len = flog10pow2(Integer.SIZE - numberOfLeadingZeros(f)); + if (f >= pow10(len)) { + len += 1; + } + + /* + Let fp and ep be the original f and e, respectively. + Transform f and e to ensure + 10^(H-1) <= f < 10^H + fp 10^ep = f 10^(e-H) = 0.f 10^e + */ + f *= pow10(H - len); + e += len; + + /* + The toChars?() methods perform left-to-right digits extraction + using ints, provided that the arguments are limited to 8 digits. + Therefore, split the H = 9 digits of f into: + h = the most significant digit of f + l = the last 8, least significant digits of f + + For n = 9, m = 8 the table in section 10 of [1] shows + floor(f / 10^8) = floor(1'441'151'881 f / 2^57) + */ + int h = (int) (f * 1_441_151_881L >>> 57); + int l = f - 100_000_000 * h; + + if (0 < e && e <= 7) { + return toChars1(h, l, e); + } + if (-3 < e && e <= 0) { + return toChars2(h, l, e); + } + return toChars3(h, l, e); + } + + private int toChars1(int h, int l, int e) { + /* + 0 < e <= 7: plain format without leading zeroes. + Left-to-right digits extraction: + algorithm 1 in [3], with b = 10, k = 8, n = 28. + */ + appendDigit(h); + int y = y(l); + int t; + int i = 1; + for (; i < e; ++i) { + t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + append('.'); + for (; i <= 8; ++i) { + t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + removeTrailingZeroes(); + return NON_SPECIAL; + } + + private int toChars2(int h, int l, int e) { + // -3 < e <= 0: plain format with leading zeroes. + appendDigit(0); + append('.'); + for (; e < 0; ++e) { + appendDigit(0); + } + appendDigit(h); + append8Digits(l); + removeTrailingZeroes(); + return NON_SPECIAL; + } + + private int toChars3(int h, int l, int e) { + // -3 >= e | e > 7: computerized scientific notation + appendDigit(h); + append('.'); + append8Digits(l); + removeTrailingZeroes(); + exponent(e - 1); + return NON_SPECIAL; + } + + private void append8Digits(int m) { + /* + Left-to-right digits extraction: + algorithm 1 in [3], with b = 10, k = 8, n = 28. + */ + int y = y(m); + for (int i = 0; i < 8; ++i) { + int t = 10 * y; + appendDigit(t >>> 28); + y = t & MASK_28; + } + } + + private void removeTrailingZeroes() { + while (bytes[index] == '0') { + --index; + } + // ... but do not remove the one directly to the right of '.' + if (bytes[index] == '.') { + ++index; + } + } + + private int y(int a) { + /* + Algorithm 1 in [3] needs computation of + floor((a + 1) 2^n / b^k) - 1 + with a < 10^8, b = 10, k = 8, n = 28. + Noting that + (a + 1) 2^n <= 10^8 2^28 < 10^17 + For n = 17, m = 8 the table in section 10 of [1] leads to: + */ + return (int) (multiplyHigh( + (long) (a + 1) << 28, + 193_428_131_138_340_668L) >>> 20) - 1; + } + + private void exponent(int e) { + append('E'); + if (e < 0) { + append('-'); + e = -e; + } + if (e < 10) { + appendDigit(e); + return; + } + /* + For n = 2, m = 1 the table in section 10 of [1] shows + floor(e / 10) = floor(103 e / 2^10) + */ + int d = e * 103 >>> 10; + appendDigit(d); + appendDigit(e - 10 * d); + } + + private void append(int c) { + bytes[++index] = (byte) c; + } + + private void appendDigit(int d) { + bytes[++index] = (byte) ('0' + d); + } + + /* + Using the deprecated constructor enhances performance. + */ + @SuppressWarnings("deprecation") + private String charsToString() { + return new String(bytes, 0, 0, index + 1); + } + +} diff --git a/src/java.base/share/classes/jdk/internal/math/MathUtils.java b/src/java.base/share/classes/jdk/internal/math/MathUtils.java new file mode 100644 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/math/MathUtils.java @@ -0,0 +1,799 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +/** + * This class exposes package private utilities for other classes. Thus, + * all methods are assumed to be invoked with correct arguments, so they are + * not checked at all. + * + * @author Raffaello Giulietti + */ +final class MathUtils { + /* + For full details about this code see the following reference: + + Giulietti, "The Schubfach way to render doubles", + https://drive.google.com/open?id=1KLtG_LaIbK9ETXI290zqCxvBW94dj058 + */ + + // The minimum and maximum k + static final int MIN_K = -324; + static final int MAX_K = 292; + + // C_10 = floor(log10(2) * 2^Q_10), A_10 = floor(log10(3/4) * 2^Q_10) + private static final int Q_10 = 41; + private static final long C_10 = 661_971_961_083L; + private static final long A_10 = -274_743_187_321L; + + // C_2 = floor(log2(10) * 2^Q_2) + private static final int Q_2 = 38; + private static final long C_2 = 913_124_641_741L; + + private MathUtils() { + } + + private static final long[] pow10 = { + 1L, + 10L, + 100L, + 1_000L, + 10_000L, + 100_000L, + 1_000_000L, + 10_000_000L, + 100_000_000L, + 1_000_000_000L, + 10_000_000_000L, + 100_000_000_000L, + 1_000_000_000_000L, + 10_000_000_000_000L, + 100_000_000_000_000L, + 1_000_000_000_000_000L, + 10_000_000_000_000_000L, + 100_000_000_000_000_000L, + }; + + /** + * Returns 10{@code e}. + * + * @param e The exponent which must meet + * 0 ≤ {@code e} ≤ {@link DoubleToDecimal#H}. + * @return 10{@code e}. + */ + static long pow10(int e) { + return pow10[e]; + } + + /** + * Returns the unique integer k such that + * 10k ≤ 2{@code e} + * < 10k+1. + *

              + * The result is correct when |{@code e}| ≤ 5_456_721. + * Otherwise the result is undefined. + * + * @param e The exponent of 2, which should meet + * |{@code e}| ≤ 5_456_721 for safe results. + * @return ⌊log102{@code e}⌋. + */ + static int flog10pow2(int e) { + return (int) (e * C_10 >> Q_10); + } + + /** + * Returns the unique integer k such that + * 10k ≤ 3/4 · 2{@code e} + * < 10k+1. + *

              + * The result is correct when + * -2_956_395 ≤ {@code e} ≤ 2_500_325. + * Otherwise the result is undefined. + * + * @param e The exponent of 2, which should meet + * -2_956_395 ≤ {@code e} ≤ 2_500_325 for safe results. + * @return ⌊log10(3/4 · + * 2{@code e})⌋. + */ + static int flog10threeQuartersPow2(int e) { + return (int) (e * C_10 + A_10 >> Q_10); + } + + /** + * Returns the unique integer k such that + * 2k ≤ 10{@code e} + * < 2k+1. + *

              + * The result is correct when |{@code e}| ≤ 1_838_394. + * Otherwise the result is undefined. + * + * @param e The exponent of 10, which should meet + * |{@code e}| ≤ 1_838_394 for safe results. + * @return ⌊log210{@code e}⌋. + */ + static int flog2pow10(int e) { + return (int) (e * C_2 >> Q_2); + } + + /** + * Let 10{@code e} = β 2r, + * for the unique pair of integer r and real β meeting + * 2125β < 2126. + * Further, let g = ⌊β⌋ + 1. + * Split g into the higher 63 bits g1 and + * the lower 63 bits g0. Thus, + * g1 = + * ⌊g 2-63⌋ + * and + * g0 = + * g - g1 263. + *

              + * This method returns g1 while + * {@link #g0(int)} returns g0. + *

              + * If needed, the exponent r can be computed as + * r = {@code flog2pow10(e)} - 125 (see {@link #flog2pow10(int)}). + * + * @param e The exponent of 10. + * @return g1 as described above. + */ + static long g1(int e) { + return g[e + MAX_K << 1]; + } + + /** + * Returns g0 as described in + * {@link #g1(int)}. + * + * @param e The exponent of 10. + * @return g0 as described in + * {@link #g1(int)}. + */ + static long g0(int e) { + return g[e + MAX_K << 1 | 1]; + } + + /** + * The precomputed values for {@link #g1(int)} and {@link #g0(int)}. + */ + private static final long[] g = { + /* -292 */ 0x7FBB_D8FE_5F5E_6E27L, 0x497A_3A27_04EE_C3DFL, + /* -291 */ 0x4FD5_679E_FB9B_04D8L, 0x5DEC_6458_6315_3A6CL, + /* -290 */ 0x63CA_C186_BA81_C60EL, 0x7567_7D6E_7BDA_8906L, + /* -289 */ 0x7CBD_71E8_6922_3792L, 0x52C1_5CCA_1AD1_2B48L, + /* -288 */ 0x4DF6_6731_41B5_62BBL, 0x53B8_D9FE_50C2_BB0DL, + /* -287 */ 0x6174_00FD_9222_BB6AL, 0x48A7_107D_E4F3_69D0L, + /* -286 */ 0x79D1_013C_F6AB_6A45L, 0x1AD0_D49D_5E30_4444L, + /* -285 */ 0x4C22_A0C6_1A2B_226BL, 0x20C2_84E2_5ADE_2AABL, + /* -284 */ 0x5F2B_48F7_A0B5_EB06L, 0x08F3_261A_F195_B555L, + /* -283 */ 0x76F6_1B35_88E3_65C7L, 0x4B2F_EFA1_ADFB_22ABL, + /* -282 */ 0x4A59_D101_758E_1F9CL, 0x5EFD_F5C5_0CBC_F5ABL, + /* -281 */ 0x5CF0_4541_D2F1_A783L, 0x76BD_7336_4FEC_3315L, + /* -280 */ 0x742C_5692_47AE_1164L, 0x746C_D003_E3E7_3FDBL, + /* -279 */ 0x489B_B61B_6CCC_CADFL, 0x08C4_0202_6E70_87E9L, + /* -278 */ 0x5AC2_A3A2_47FF_FD96L, 0x6AF5_0283_0A0C_A9E3L, + /* -277 */ 0x7173_4C8A_D9FF_FCFCL, 0x45B2_4323_CC8F_D45CL, + /* -276 */ 0x46E8_0FD6_C83F_FE1DL, 0x6B8F_69F6_5FD9_E4B9L, + /* -275 */ 0x58A2_13CC_7A4F_FDA5L, 0x2673_4473_F7D0_5DE8L, + /* -274 */ 0x6ECA_98BF_98E3_FD0EL, 0x5010_1590_F5C4_7561L, + /* -273 */ 0x453E_9F77_BF8E_7E29L, 0x120A_0D7A_999A_C95DL, + /* -272 */ 0x568E_4755_AF72_1DB3L, 0x368C_90D9_4001_7BB4L, + /* -271 */ 0x6C31_D92B_1B4E_A520L, 0x242F_B50F_9001_DAA1L, + /* -270 */ 0x439F_27BA_F111_2734L, 0x169D_D129_BA01_28A5L, + /* -269 */ 0x5486_F1A9_AD55_7101L, 0x1C45_4574_2881_72CEL, + /* -268 */ 0x69A8_AE14_18AA_CD41L, 0x4356_96D1_32A1_CF81L, + /* -267 */ 0x4209_6CCC_8F6A_C048L, 0x7A16_1E42_BFA5_21B1L, + /* -266 */ 0x528B_C7FF_B345_705BL, 0x189B_A5D3_6F8E_6A1DL, + /* -265 */ 0x672E_B9FF_A016_CC71L, 0x7EC2_8F48_4B72_04A4L, + /* -264 */ 0x407D_343F_C40E_3FC7L, 0x1F39_998D_2F27_42E7L, + /* -263 */ 0x509C_814F_B511_CFB9L, 0x0707_FFF0_7AF1_13A1L, + /* -262 */ 0x64C3_A1A3_A256_43A7L, 0x28C9_FFEC_99AD_5889L, + /* -261 */ 0x7DF4_8A0C_8AEB_D491L, 0x12FC_7FE7_C018_AEABL, + /* -260 */ 0x4EB8_D647_D6D3_64DAL, 0x5BDD_CFF0_D80F_6D2BL, + /* -259 */ 0x6267_0BD9_CC88_3E11L, 0x32D5_43ED_0E13_4875L, + /* -258 */ 0x7B00_CED0_3FAA_4D95L, 0x5F8A_94E8_5198_1A93L, + /* -257 */ 0x4CE0_8142_27CA_707DL, 0x4BB6_9D11_32FF_109CL, + /* -256 */ 0x6018_A192_B1BD_0C9CL, 0x7EA4_4455_7FBE_D4C3L, + /* -255 */ 0x781E_C9F7_5E2C_4FC4L, 0x1E4D_556A_DFAE_89F3L, + /* -254 */ 0x4B13_3E3A_9ADB_B1DAL, 0x52F0_5562_CBCD_1638L, + /* -253 */ 0x5DD8_0DC9_4192_9E51L, 0x27AC_6ABB_7EC0_5BC6L, + /* -252 */ 0x754E_113B_91F7_45E5L, 0x5197_856A_5E70_72B8L, + /* -251 */ 0x4950_CAC5_3B3A_8BAFL, 0x42FE_B362_7B06_47B3L, + /* -250 */ 0x5BA4_FD76_8A09_2E9BL, 0x33BE_603B_19C7_D99FL, + /* -249 */ 0x728E_3CD4_2C8B_7A42L, 0x20AD_F849_E039_D007L, + /* -248 */ 0x4798_E604_9BD7_2C69L, 0x346C_BB2E_2C24_2205L, + /* -247 */ 0x597F_1F85_C2CC_F783L, 0x6187_E9F9_B72D_2A86L, + /* -246 */ 0x6FDE_E767_3380_3564L, 0x59E9_E478_24F8_7527L, + /* -245 */ 0x45EB_50A0_8030_215EL, 0x7832_2ECB_171B_4939L, + /* -244 */ 0x5766_24C8_A03C_29B6L, 0x563E_BA7D_DCE2_1B87L, + /* -243 */ 0x6D3F_ADFA_C84B_3424L, 0x2BCE_691D_541A_A268L, + /* -242 */ 0x4447_CCBC_BD2F_0096L, 0x5B61_01B2_5490_A581L, + /* -241 */ 0x5559_BFEB_EC7A_C0BCL, 0x3239_421E_E9B4_CEE1L, + /* -240 */ 0x6AB0_2FE6_E799_70EBL, 0x3EC7_92A6_A422_029AL, + /* -239 */ 0x42AE_1DF0_50BF_E693L, 0x173C_BBA8_2695_41A0L, + /* -238 */ 0x5359_A56C_64EF_E037L, 0x7D0B_EA92_303A_9208L, + /* -237 */ 0x6830_0EC7_7E2B_D845L, 0x7C4E_E536_BC49_368AL, + /* -236 */ 0x411E_093C_AEDB_672BL, 0x5DB1_4F42_35AD_C217L, + /* -235 */ 0x5165_8B8B_DA92_40F6L, 0x551D_A312_C319_329CL, + /* -234 */ 0x65BE_EE6E_D136_D134L, 0x2A65_0BD7_73DF_7F43L, + /* -233 */ 0x7F2E_AA0A_8584_8581L, 0x34FE_4ECD_50D7_5F14L, + /* -232 */ 0x4F7D_2A46_9372_D370L, 0x711E_F140_5286_9B6CL, + /* -231 */ 0x635C_74D8_384F_884DL, 0x0D66_AD90_6728_4247L, + /* -230 */ 0x7C33_920E_4663_6A60L, 0x30C0_58F4_80F2_52D9L, + /* -229 */ 0x4DA0_3B48_EBFE_227CL, 0x1E78_3798_D097_73C8L, + /* -228 */ 0x6108_4A1B_26FD_AB1BL, 0x2616_457F_04BD_50BAL, + /* -227 */ 0x794A_5CA1_F0BD_15E2L, 0x0F9B_D6DE_C5EC_A4E8L, + /* -226 */ 0x4BCE_79E5_3676_2DADL, 0x29C1_664B_3BB3_E711L, + /* -225 */ 0x5EC2_185E_8413_B918L, 0x5431_BFDE_0AA0_E0D5L, + /* -224 */ 0x7672_9E76_2518_A75EL, 0x693E_2FD5_8D49_190BL, + /* -223 */ 0x4A07_A309_D72F_689BL, 0x21C6_DDE5_784D_AFA7L, + /* -222 */ 0x5C89_8BCC_4CFB_42C2L, 0x0A38_955E_D661_1B90L, + /* -221 */ 0x73AB_EEBF_603A_1372L, 0x4CC6_BAB6_8BF9_6274L, + /* -220 */ 0x484B_7537_9C24_4C27L, 0x4FFC_34B2_177B_DD89L, + /* -219 */ 0x5A5E_5285_832D_5F31L, 0x43FB_41DE_9D5A_D4EBL, + /* -218 */ 0x70F5_E726_E3F8_B6FDL, 0x74FA_1256_44B1_8A26L, + /* -217 */ 0x4699_B078_4E7B_725EL, 0x591C_4B75_EAEE_F658L, + /* -216 */ 0x5840_1C96_621A_4EF6L, 0x2F63_5E53_65AA_B3EDL, + /* -215 */ 0x6E50_23BB_FAA0_E2B3L, 0x7B3C_35E8_3F15_60E9L, + /* -214 */ 0x44F2_1655_7CA4_8DB0L, 0x3D05_A1B1_276D_5C92L, + /* -213 */ 0x562E_9BEA_DBCD_B11CL, 0x4C47_0A1D_7148_B3B6L, + /* -212 */ 0x6BBA_42E5_92C1_1D63L, 0x5F58_CCA4_CD9A_E0A3L, + /* -211 */ 0x4354_69CF_7BB8_B25EL, 0x2B97_7FE7_0080_CC66L, + /* -210 */ 0x5429_8443_5AA6_DEF5L, 0x767D_5FE0_C0A0_FF80L, + /* -209 */ 0x6933_E554_3150_96B3L, 0x341C_B7D8_F0C9_3F5FL, + /* -208 */ 0x41C0_6F54_9ED2_5E30L, 0x1091_F2E7_967D_C79CL, + /* -207 */ 0x5230_8B29_C686_F5BCL, 0x14B6_6FA1_7C1D_3983L, + /* -206 */ 0x66BC_ADF4_3828_B32BL, 0x19E4_0B89_DB24_87E3L, + /* -205 */ 0x4035_ECB8_A319_6FFBL, 0x002E_8736_28F6_D4EEL, + /* -204 */ 0x5043_67E6_CBDF_CBF9L, 0x603A_2903_B334_8A2AL, + /* -203 */ 0x6454_41E0_7ED7_BEF8L, 0x1848_B344_A001_ACB4L, + /* -202 */ 0x7D69_5258_9E8D_AEB6L, 0x1E5A_E015_C802_17E1L, + /* -201 */ 0x4E61_D377_6318_8D31L, 0x72F8_CC0D_9D01_4EEDL, + /* -200 */ 0x61FA_4855_3BDE_B07EL, 0x2FB6_FF11_0441_A2A8L, + /* -199 */ 0x7A78_DA6A_8AD6_5C9DL, 0x7BA4_BED5_4552_0B52L, + /* -198 */ 0x4C8B_8882_96C5_F9E2L, 0x5D46_F745_4B53_4713L, + /* -197 */ 0x5FAE_6AA3_3C77_785BL, 0x3498_B516_9E28_18D8L, + /* -196 */ 0x779A_054C_0B95_5672L, 0x21BE_E25C_45B2_1F0EL, + /* -195 */ 0x4AC0_434F_873D_5607L, 0x3517_4D79_AB8F_5369L, + /* -194 */ 0x5D70_5423_690C_AB89L, 0x225D_20D8_1673_2843L, + /* -193 */ 0x74CC_692C_434F_D66BL, 0x4AF4_690E_1C0F_F253L, + /* -192 */ 0x48FF_C1BB_AA11_E603L, 0x1ED8_C1A8_D189_F774L, + /* -191 */ 0x5B3F_B22A_9496_5F84L, 0x068E_F213_05EC_7551L, + /* -190 */ 0x720F_9EB5_39BB_F765L, 0x0832_AE97_C767_92A5L, + /* -189 */ 0x4749_C331_4415_7A9FL, 0x151F_AD1E_DCA0_BBA8L, + /* -188 */ 0x591C_33FD_951A_D946L, 0x7A67_9866_93C8_EA91L, + /* -187 */ 0x6F63_40FC_FA61_8F98L, 0x5901_7E80_38BB_2536L, + /* -186 */ 0x459E_089E_1C7C_F9BFL, 0x37A0_EF10_2374_F742L, + /* -185 */ 0x5705_8AC5_A39C_382FL, 0x2589_2AD4_2C52_3512L, + /* -184 */ 0x6CC6_ED77_0C83_463BL, 0x0EEB_7589_3766_C256L, + /* -183 */ 0x43FC_546A_67D2_0BE4L, 0x7953_2975_C2A0_3976L, + /* -182 */ 0x54FB_6985_01C6_8EDEL, 0x17A7_F3D3_3348_47D4L, + /* -181 */ 0x6A3A_43E6_4238_3295L, 0x5D91_F0C8_001A_59C8L, + /* -180 */ 0x4264_6A6F_E963_1F9DL, 0x4A7B_367D_0010_781DL, + /* -179 */ 0x52FD_850B_E3BB_E784L, 0x7D1A_041C_4014_9625L, + /* -178 */ 0x67BC_E64E_DCAA_E166L, 0x1C60_8523_5019_BBAEL, + /* -177 */ 0x40D6_0FF1_49EA_CCDFL, 0x71BC_5336_1210_154DL, + /* -176 */ 0x510B_93ED_9C65_8017L, 0x6E2B_6803_9694_1AA0L, + /* -175 */ 0x654E_78E9_037E_E01DL, 0x69B6_4204_7C39_2148L, + /* -174 */ 0x7EA2_1723_445E_9825L, 0x2423_D285_9B47_6999L, + /* -173 */ 0x4F25_4E76_0ABB_1F17L, 0x2696_6393_810C_A200L, + /* -172 */ 0x62EE_A213_8D69_E6DDL, 0x103B_FC78_614F_CA80L, + /* -171 */ 0x7BAA_4A98_70C4_6094L, 0x344A_FB96_79A3_BD20L, + /* -170 */ 0x4D4A_6E9F_467A_BC5CL, 0x60AE_DD3E_0C06_5634L, + /* -169 */ 0x609D_0A47_1819_6B73L, 0x78DA_948D_8F07_EBC1L, + /* -168 */ 0x78C4_4CD8_DE1F_C650L, 0x7711_39B0_F2C9_E6B1L, + /* -167 */ 0x4B7A_B007_8AD3_DBF2L, 0x4A6A_C40E_97BE_302FL, + /* -166 */ 0x5E59_5C09_6D88_D2EFL, 0x1D05_7512_3DAD_BC3AL, + /* -165 */ 0x75EF_B30B_C8EB_07ABL, 0x0446_D256_CD19_2B49L, + /* -164 */ 0x49B5_CFE7_5D92_E4CAL, 0x72AC_4376_402F_BB0EL, + /* -163 */ 0x5C23_43E1_34F7_9DFDL, 0x4F57_5453_D03B_A9D1L, + /* -162 */ 0x732C_14D9_8235_857DL, 0x032D_2968_C44A_9445L, + /* -161 */ 0x47FB_8D07_F161_736EL, 0x11FC_39E1_7AAE_9CABL, + /* -160 */ 0x59FA_7049_EDB9_D049L, 0x567B_4859_D95A_43D6L, + /* -159 */ 0x7079_0C5C_6928_445CL, 0x0C1A_1A70_4FB0_D4CCL, + /* -158 */ 0x464B_A7B9_C1B9_2AB9L, 0x4790_5086_31CE_84FFL, + /* -157 */ 0x57DE_91A8_3227_7567L, 0x7974_64A7_BE42_263FL, + /* -156 */ 0x6DD6_3612_3EB1_52C1L, 0x77D1_7DD1_ADD2_AFCFL, + /* -155 */ 0x44A5_E1CB_672E_D3B9L, 0x1AE2_EEA3_0CA3_ADE1L, + /* -154 */ 0x55CF_5A3E_40FA_88A7L, 0x419B_AA4B_CFCC_995AL, + /* -153 */ 0x6B43_30CD_D139_2AD1L, 0x3202_94DE_C3BF_BFB0L, + /* -152 */ 0x4309_FE80_A2C3_BAC2L, 0x6F41_9D0B_3A57_D7CEL, + /* -151 */ 0x53CC_7E20_CB74_A973L, 0x4B12_044E_08ED_CDC2L, + /* -150 */ 0x68BF_9DA8_FE51_D3D0L, 0x3DD6_8561_8B29_4132L, + /* -149 */ 0x4177_C289_9EF3_2462L, 0x26A6_135C_F6F9_C8BFL, + /* -148 */ 0x51D5_B32C_06AF_ED7AL, 0x704F_9834_34B8_3AEFL, + /* -147 */ 0x664B_1FF7_085B_E8D9L, 0x4C63_7E41_41E6_49ABL, + /* -146 */ 0x7FDD_E7F4_CA72_E30FL, 0x7F7C_5DD1_925F_DC15L, + /* -145 */ 0x4FEA_B0F8_FE87_CDE9L, 0x7FAD_BAA2_FB7B_E98DL, + /* -144 */ 0x63E5_5D37_3E29_C164L, 0x3F99_294B_BA5A_E3F1L, + /* -143 */ 0x7CDE_B485_0DB4_31BDL, 0x4F7F_739E_A8F1_9CEDL, + /* -142 */ 0x4E0B_30D3_2890_9F16L, 0x41AF_A843_2997_0214L, + /* -141 */ 0x618D_FD07_F2B4_C6DCL, 0x121B_9253_F3FC_C299L, + /* -140 */ 0x79F1_7C49_EF61_F893L, 0x16A2_76E8_F0FB_F33FL, + /* -139 */ 0x4C36_EDAE_359D_3B5BL, 0x7E25_8A51_969D_7808L, + /* -138 */ 0x5F44_A919_C304_8A32L, 0x7DAE_ECE5_FC44_D609L, + /* -137 */ 0x7715_D360_33C5_ACBFL, 0x5D1A_A81F_7B56_0B8CL, + /* -136 */ 0x4A6D_A41C_205B_8BF7L, 0x6A30_A913_AD15_C738L, + /* -135 */ 0x5D09_0D23_2872_6EF5L, 0x64BC_D358_985B_3905L, + /* -134 */ 0x744B_506B_F28F_0AB3L, 0x1DEC_082E_BE72_0746L, + /* -133 */ 0x48AF_1243_7799_66B0L, 0x02B3_851D_3707_448CL, + /* -132 */ 0x5ADA_D6D4_557F_C05CL, 0x0360_6664_84C9_15AFL, + /* -131 */ 0x7191_8C89_6ADF_B073L, 0x0438_7FFD_A5FB_5B1BL, + /* -130 */ 0x46FA_F7D5_E2CB_CE47L, 0x72A3_4FFE_87BD_18F1L, + /* -129 */ 0x58B9_B5CB_5B7E_C1D9L, 0x6F4C_23FE_29AC_5F2DL, + /* -128 */ 0x6EE8_233E_325E_7250L, 0x2B1F_2CFD_B417_76F8L, + /* -127 */ 0x4551_1606_DF7B_0772L, 0x1AF3_7C1E_908E_AA5BL, + /* -126 */ 0x56A5_5B88_9759_C94EL, 0x61B0_5B26_34B2_54F2L, + /* -125 */ 0x6C4E_B26A_BD30_3BA2L, 0x3A1C_71EF_C1DE_EA2EL, + /* -124 */ 0x43B1_2F82_B63E_2545L, 0x4451_C735_D92B_525DL, + /* -123 */ 0x549D_7B63_63CD_AE96L, 0x7566_3903_4F76_26F4L, + /* -122 */ 0x69C4_DA3C_3CC1_1A3CL, 0x52BF_C744_2353_B0B1L, + /* -121 */ 0x421B_0865_A5F8_B065L, 0x73B7_DC8A_9614_4E6FL, + /* -120 */ 0x52A1_CA7F_0F76_DC7FL, 0x30A5_D3AD_3B99_620BL, + /* -119 */ 0x674A_3D1E_D354_939FL, 0x1CCF_4898_8A7F_BA8DL, + /* -118 */ 0x408E_6633_4414_DC43L, 0x4201_8D5F_568F_D498L, + /* -117 */ 0x50B1_FFC0_151A_1354L, 0x3281_F0B7_2C33_C9BEL, + /* -116 */ 0x64DE_7FB0_1A60_9829L, 0x3F22_6CE4_F740_BC2EL, + /* -115 */ 0x7E16_1F9C_20F8_BE33L, 0x6EEB_081E_3510_EB39L, + /* -114 */ 0x4ECD_D3C1_949B_76E0L, 0x3552_E512_E12A_9304L, + /* -113 */ 0x6281_48B1_F9C2_5498L, 0x42A7_9E57_9975_37C5L, + /* -112 */ 0x7B21_9ADE_7832_E9BEL, 0x5351_85ED_7FD2_85B6L, + /* -111 */ 0x4CF5_00CB_0B1F_D217L, 0x1412_F3B4_6FE3_9392L, + /* -110 */ 0x6032_40FD_CDE7_C69CL, 0x7917_B0A1_8BDC_7876L, + /* -109 */ 0x783E_D13D_4161_B844L, 0x175D_9CC9_EED3_9694L, + /* -108 */ 0x4B27_42C6_48DD_132AL, 0x4E9A_81FE_3544_3E1CL, + /* -107 */ 0x5DF1_1377_DB14_57F5L, 0x2241_227D_C295_4DA3L, + /* -106 */ 0x756D_5855_D1D9_6DF2L, 0x4AD1_6B1D_333A_A10CL, + /* -105 */ 0x4964_5735_A327_E4B7L, 0x4EC2_E2F2_4004_A4A8L, + /* -104 */ 0x5BBD_6D03_0BF1_DDE5L, 0x4273_9BAE_D005_CDD2L, + /* -103 */ 0x72AC_C843_CEEE_555EL, 0x7310_829A_8407_4146L, + /* -102 */ 0x47AB_FD2A_6154_F55BL, 0x27EA_51A0_9284_88CCL, + /* -101 */ 0x5996_FC74_F9AA_32B2L, 0x11E4_E608_B725_AAFFL, + /* -100 */ 0x6FFC_BB92_3814_BF5EL, 0x565E_1F8A_E4EF_15BEL, + /* -99 */ 0x45FD_F53B_630C_F79BL, 0x15FA_D3B6_CF15_6D97L, + /* -98 */ 0x577D_728A_3BD0_3581L, 0x7B79_88A4_82DA_C8FDL, + /* -97 */ 0x6D5C_CF2C_CAC4_42E2L, 0x3A57_EACD_A391_7B3CL, + /* -96 */ 0x445A_017B_FEBA_A9CDL, 0x4476_F2C0_863A_ED06L, + /* -95 */ 0x5570_81DA_FE69_5440L, 0x7594_AF70_A7C9_A847L, + /* -94 */ 0x6ACC_A251_BE03_A951L, 0x12F9_DB4C_D1BC_1258L, + /* -93 */ 0x42BF_E573_16C2_49D2L, 0x5BDC_2910_0315_8B77L, + /* -92 */ 0x536F_DECF_DC72_DC47L, 0x32D3_3354_03DA_EE55L, + /* -91 */ 0x684B_D683_D38F_9359L, 0x1F88_0029_04D1_A9EAL, + /* -90 */ 0x412F_6612_6439_BC17L, 0x63B5_0019_A303_0A33L, + /* -89 */ 0x517B_3F96_FD48_2B1DL, 0x5CA2_4020_0BC3_CCBFL, + /* -88 */ 0x65DA_0F7C_BC9A_35E5L, 0x13CA_D028_0EB4_BFEFL, + /* -87 */ 0x7F50_935B_EBC0_C35EL, 0x38BD_8432_1261_EFEBL, + /* -86 */ 0x4F92_5C19_7358_7A1BL, 0x0376_729F_4B7D_35F3L, + /* -85 */ 0x6376_F31F_D02E_98A1L, 0x6454_0F47_1E5C_836FL, + /* -84 */ 0x7C54_AFE7_C43A_3ECAL, 0x1D69_1318_E5F3_A44BL, + /* -83 */ 0x4DB4_EDF0_DAA4_673EL, 0x3261_ABEF_8FB8_46AFL, + /* -82 */ 0x6122_296D_114D_810DL, 0x7EFA_16EB_73A6_585BL, + /* -81 */ 0x796A_B3C8_55A0_E151L, 0x3EB8_9CA6_508F_EE71L, + /* -80 */ 0x4BE2_B05D_3584_8CD2L, 0x7733_61E7_F259_F507L, + /* -79 */ 0x5EDB_5C74_82E5_B007L, 0x5500_3A61_EEF0_7249L, + /* -78 */ 0x7692_3391_A39F_1C09L, 0x4A40_48FA_6AAC_8EDBL, + /* -77 */ 0x4A1B_603B_0643_7185L, 0x7E68_2D9C_82AB_D949L, + /* -76 */ 0x5CA2_3849_C7D4_4DE7L, 0x3E02_3903_A356_CF9BL, + /* -75 */ 0x73CA_C65C_39C9_6161L, 0x2D82_C744_8C2C_8382L, + /* -74 */ 0x485E_BBF9_A41D_DCDCL, 0x6C71_BC8A_D79B_D231L, + /* -73 */ 0x5A76_6AF8_0D25_5414L, 0x078E_2BAD_8D82_C6BDL, + /* -72 */ 0x7114_05B6_106E_A919L, 0x0971_B698_F0E3_786DL, + /* -71 */ 0x46AC_8391_CA45_29AFL, 0x55E7_121F_968E_2B44L, + /* -70 */ 0x5857_A476_3CD6_741BL, 0x4B60_D6A7_7C31_B615L, + /* -69 */ 0x6E6D_8D93_CC0C_1122L, 0x3E39_0C51_5B3E_239AL, + /* -68 */ 0x4504_787C_5F87_8AB5L, 0x46E3_A7B2_D906_D640L, + /* -67 */ 0x5645_969B_7769_6D62L, 0x789C_919F_8F48_8BD0L, + /* -66 */ 0x6BD6_FC42_5543_C8BBL, 0x56C3_B607_731A_AEC4L, + /* -65 */ 0x4366_5DA9_754A_5D75L, 0x263A_51C4_A7F0_AD3BL, + /* -64 */ 0x543F_F513_D29C_F4D2L, 0x4FC8_E635_D1EC_D88AL, + /* -63 */ 0x694F_F258_C744_3207L, 0x23BB_1FC3_4668_0EACL, + /* -62 */ 0x41D1_F777_7C8A_9F44L, 0x4654_F3DA_0C01_092CL, + /* -61 */ 0x5246_7555_5BAD_4715L, 0x57EA_30D0_8F01_4B76L, + /* -60 */ 0x66D8_12AA_B298_98DBL, 0x0DE4_BD04_B2C1_9E54L, + /* -59 */ 0x4047_0BAA_AF9F_5F88L, 0x78AE_F622_EFB9_02F5L, + /* -58 */ 0x5058_CE95_5B87_376BL, 0x16DA_B3AB_ABA7_43B2L, + /* -57 */ 0x646F_023A_B269_0545L, 0x7C91_6096_9691_149EL, + /* -56 */ 0x7D8A_C2C9_5F03_4697L, 0x3BB5_B8BC_3C35_59C5L, + /* -55 */ 0x4E76_B9BD_DB62_0C1EL, 0x5551_9375_A5A1_581BL, + /* -54 */ 0x6214_682D_523A_8F26L, 0x2AA5_F853_0F09_AE22L, + /* -53 */ 0x7A99_8238_A6C9_32EFL, 0x754F_7667_D2CC_19ABL, + /* -52 */ 0x4C9F_F163_683D_BFD5L, 0x7951_AA00_E3BF_900BL, + /* -51 */ 0x5FC7_EDBC_424D_2FCBL, 0x37A6_1481_1CAF_740DL, + /* -50 */ 0x77B9_E92B_52E0_7BBEL, 0x258F_99A1_63DB_5111L, + /* -49 */ 0x4AD4_31BB_13CC_4D56L, 0x7779_C004_DE69_12ABL, + /* -48 */ 0x5D89_3E29_D8BF_60ACL, 0x5558_3006_1603_5755L, + /* -47 */ 0x74EB_8DB4_4EEF_38D7L, 0x6AAE_3C07_9B84_2D2AL, + /* -46 */ 0x4913_3890_B155_8386L, 0x72AC_E584_C132_9C3BL, + /* -45 */ 0x5B58_06B4_DDAA_E468L, 0x4F58_1EE5_F17F_4349L, + /* -44 */ 0x722E_0862_1515_9D82L, 0x632E_269F_6DDF_141BL, + /* -43 */ 0x475C_C53D_4D2D_8271L, 0x5DFC_D823_A4AB_6C91L, + /* -42 */ 0x5933_F68C_A078_E30EL, 0x157C_0E2C_8DD6_47B5L, + /* -41 */ 0x6F80_F42F_C897_1BD1L, 0x5ADB_11B7_B14B_D9A3L, + /* -40 */ 0x45B0_989D_DD5E_7163L, 0x08C8_EB12_CECF_6806L, + /* -39 */ 0x571C_BEC5_54B6_0DBBL, 0x6AFB_25D7_8283_4207L, + /* -38 */ 0x6CE3_EE76_A9E3_912AL, 0x65B9_EF4D_6324_1289L, + /* -37 */ 0x440E_750A_2A2E_3ABAL, 0x5F94_3590_5DF6_8B96L, + /* -36 */ 0x5512_124C_B4B9_C969L, 0x3779_42F4_7574_2E7BL, + /* -35 */ 0x6A56_96DF_E1E8_3BC3L, 0x6557_93B1_92D1_3A1AL, + /* -34 */ 0x4276_1E4B_ED31_255AL, 0x2F56_BC4E_FBC2_C450L, + /* -33 */ 0x5313_A5DE_E87D_6EB0L, 0x7B2C_6B62_BAB3_7564L, + /* -32 */ 0x67D8_8F56_A29C_CA5DL, 0x19F7_863B_6960_52BDL, + /* -31 */ 0x40E7_5996_25A1_FE7AL, 0x203A_B3E5_21DC_33B6L, + /* -30 */ 0x5121_2FFB_AF0A_7E18L, 0x6849_60DE_6A53_40A4L, + /* -29 */ 0x6569_7BFA_9ACD_1D9FL, 0x025B_B916_04E8_10CDL, + /* -28 */ 0x7EC3_DAF9_4180_6506L, 0x62F2_A75B_8622_1500L, + /* -27 */ 0x4F3A_68DB_C8F0_3F24L, 0x1DD7_A899_33D5_4D20L, + /* -26 */ 0x6309_0312_BB2C_4EEDL, 0x254D_92BF_80CA_A068L, + /* -25 */ 0x7BCB_43D7_69F7_62A8L, 0x4EA0_F76F_60FD_4882L, + /* -24 */ 0x4D5F_0A66_A23A_9DA9L, 0x3124_9AA5_9C9E_4D51L, + /* -23 */ 0x60B6_CD00_4AC9_4513L, 0x5D6D_C14F_03C5_E0A5L, + /* -22 */ 0x78E4_8040_5D7B_9658L, 0x54C9_31A2_C4B7_58CFL, + /* -21 */ 0x4B8E_D028_3A6D_3DF7L, 0x34FD_BF05_BAF2_9781L, + /* -20 */ 0x5E72_8432_4908_8D75L, 0x223D_2EC7_29AF_3D62L, + /* -19 */ 0x760F_253E_DB4A_B0D2L, 0x4ACC_7A78_F41B_0CBAL, + /* -18 */ 0x49C9_7747_490E_AE83L, 0x4EBF_CC8B_9890_E7F4L, + /* -17 */ 0x5C3B_D519_1B52_5A24L, 0x426F_BFAE_7EB5_21F1L, + /* -16 */ 0x734A_CA5F_6226_F0ADL, 0x530B_AF9A_1E62_6A6DL, + /* -15 */ 0x480E_BE7B_9D58_566CL, 0x43E7_4DC0_52FD_8285L, + /* -14 */ 0x5A12_6E1A_84AE_6C07L, 0x54E1_2130_67BC_E326L, + /* -13 */ 0x7097_09A1_25DA_0709L, 0x4A19_697C_81AC_1BEFL, + /* -12 */ 0x465E_6604_B7A8_4465L, 0x7E4F_E1ED_D10B_9175L, + /* -11 */ 0x57F5_FF85_E592_557FL, 0x3DE3_DA69_454E_75D3L, + /* -10 */ 0x6DF3_7F67_5EF6_EADFL, 0x2D5C_D103_96A2_1347L, + /* -9 */ 0x44B8_2FA0_9B5A_52CBL, 0x4C5A_02A2_3E25_4C0DL, + /* -8 */ 0x55E6_3B88_C230_E77EL, 0x3F70_834A_CDAE_9F10L, + /* -7 */ 0x6B5F_CA6A_F2BD_215EL, 0x0F4C_A41D_811A_46D4L, + /* -6 */ 0x431B_DE82_D7B6_34DAL, 0x698F_E692_70B0_6C44L, + /* -5 */ 0x53E2_D623_8DA3_C211L, 0x43F3_E037_0CDC_8755L, + /* -4 */ 0x68DB_8BAC_710C_B295L, 0x74F0_D844_D013_A92BL, + /* -3 */ 0x4189_374B_C6A7_EF9DL, 0x5916_872B_020C_49BBL, + /* -2 */ 0x51EB_851E_B851_EB85L, 0x0F5C_28F5_C28F_5C29L, + /* -1 */ 0x6666_6666_6666_6666L, 0x3333_3333_3333_3334L, + /* 0 */ 0x4000_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 1 */ 0x5000_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 2 */ 0x6400_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 3 */ 0x7D00_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 4 */ 0x4E20_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 5 */ 0x61A8_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 6 */ 0x7A12_0000_0000_0000L, 0x0000_0000_0000_0001L, + /* 7 */ 0x4C4B_4000_0000_0000L, 0x0000_0000_0000_0001L, + /* 8 */ 0x5F5E_1000_0000_0000L, 0x0000_0000_0000_0001L, + /* 9 */ 0x7735_9400_0000_0000L, 0x0000_0000_0000_0001L, + /* 10 */ 0x4A81_7C80_0000_0000L, 0x0000_0000_0000_0001L, + /* 11 */ 0x5D21_DBA0_0000_0000L, 0x0000_0000_0000_0001L, + /* 12 */ 0x746A_5288_0000_0000L, 0x0000_0000_0000_0001L, + /* 13 */ 0x48C2_7395_0000_0000L, 0x0000_0000_0000_0001L, + /* 14 */ 0x5AF3_107A_4000_0000L, 0x0000_0000_0000_0001L, + /* 15 */ 0x71AF_D498_D000_0000L, 0x0000_0000_0000_0001L, + /* 16 */ 0x470D_E4DF_8200_0000L, 0x0000_0000_0000_0001L, + /* 17 */ 0x58D1_5E17_6280_0000L, 0x0000_0000_0000_0001L, + /* 18 */ 0x6F05_B59D_3B20_0000L, 0x0000_0000_0000_0001L, + /* 19 */ 0x4563_9182_44F4_0000L, 0x0000_0000_0000_0001L, + /* 20 */ 0x56BC_75E2_D631_0000L, 0x0000_0000_0000_0001L, + /* 21 */ 0x6C6B_935B_8BBD_4000L, 0x0000_0000_0000_0001L, + /* 22 */ 0x43C3_3C19_3756_4800L, 0x0000_0000_0000_0001L, + /* 23 */ 0x54B4_0B1F_852B_DA00L, 0x0000_0000_0000_0001L, + /* 24 */ 0x69E1_0DE7_6676_D080L, 0x0000_0000_0000_0001L, + /* 25 */ 0x422C_A8B0_A00A_4250L, 0x0000_0000_0000_0001L, + /* 26 */ 0x52B7_D2DC_C80C_D2E4L, 0x0000_0000_0000_0001L, + /* 27 */ 0x6765_C793_FA10_079DL, 0x0000_0000_0000_0001L, + /* 28 */ 0x409F_9CBC_7C4A_04C2L, 0x1000_0000_0000_0001L, + /* 29 */ 0x50C7_83EB_9B5C_85F2L, 0x5400_0000_0000_0001L, + /* 30 */ 0x64F9_64E6_8233_A76FL, 0x2900_0000_0000_0001L, + /* 31 */ 0x7E37_BE20_22C0_914BL, 0x1340_0000_0000_0001L, + /* 32 */ 0x4EE2_D6D4_15B8_5ACEL, 0x7C08_0000_0000_0001L, + /* 33 */ 0x629B_8C89_1B26_7182L, 0x5B0A_0000_0000_0001L, + /* 34 */ 0x7B42_6FAB_61F0_0DE3L, 0x31CC_8000_0000_0001L, + /* 35 */ 0x4D09_85CB_1D36_08AEL, 0x0F1F_D000_0000_0001L, + /* 36 */ 0x604B_E73D_E483_8AD9L, 0x52E7_C400_0000_0001L, + /* 37 */ 0x785E_E10D_5DA4_6D90L, 0x07A1_B500_0000_0001L, + /* 38 */ 0x4B3B_4CA8_5A86_C47AL, 0x04C5_1120_0000_0001L, + /* 39 */ 0x5E0A_1FD2_7128_7598L, 0x45F6_5568_0000_0001L, + /* 40 */ 0x758C_A7C7_0D72_92FEL, 0x5773_EAC2_0000_0001L, + /* 41 */ 0x4977_E8DC_6867_9BDFL, 0x16A8_72B9_4000_0001L, + /* 42 */ 0x5BD5_E313_8281_82D6L, 0x7C52_8F67_9000_0001L, + /* 43 */ 0x72CB_5BD8_6321_E38CL, 0x5B67_3341_7400_0001L, + /* 44 */ 0x47BF_1967_3DF5_2E37L, 0x7920_8008_E880_0001L, + /* 45 */ 0x59AE_DFC1_0D72_79C5L, 0x7768_A00B_22A0_0001L, + /* 46 */ 0x701A_97B1_50CF_1837L, 0x3542_C80D_EB48_0001L, + /* 47 */ 0x4610_9ECE_D281_6F22L, 0x5149_BD08_B30D_0001L, + /* 48 */ 0x5794_C682_8721_CAEBL, 0x259C_2C4A_DFD0_4001L, + /* 49 */ 0x6D79_F823_28EA_3DA6L, 0x0F03_375D_97C4_5001L, + /* 50 */ 0x446C_3B15_F992_6687L, 0x6962_029A_7EDA_B201L, + /* 51 */ 0x5587_49DB_77F7_0029L, 0x63BA_8341_1E91_5E81L, + /* 52 */ 0x6AE9_1C52_55F4_C034L, 0x1CA9_2411_6635_B621L, + /* 53 */ 0x42D1_B1B3_75B8_F820L, 0x51E9_B68A_DFE1_91D5L, + /* 54 */ 0x5386_1E20_5327_3628L, 0x6664_242D_97D9_F64AL, + /* 55 */ 0x6867_A5A8_67F1_03B2L, 0x7FFD_2D38_FDD0_73DCL, + /* 56 */ 0x4140_C789_40F6_A24FL, 0x6FFE_3C43_9EA2_486AL, + /* 57 */ 0x5190_F96B_9134_4AE3L, 0x6BFD_CB54_864A_DA84L, + /* 58 */ 0x65F5_37C6_7581_5D9CL, 0x66FD_3E29_A7DD_9125L, + /* 59 */ 0x7F72_85B8_12E1_B504L, 0x00BC_8DB4_11D4_F56EL, + /* 60 */ 0x4FA7_9393_0BCD_1122L, 0x4075_D890_8B25_1965L, + /* 61 */ 0x6391_7877_CEC0_556BL, 0x1093_4EB4_ADEE_5FBEL, + /* 62 */ 0x7C75_D695_C270_6AC5L, 0x74B8_2261_D969_F7ADL, + /* 63 */ 0x4DC9_A61D_9986_42BBL, 0x58F3_157D_27E2_3ACCL, + /* 64 */ 0x613C_0FA4_FFE7_D36AL, 0x4F2F_DADC_71DA_C97FL, + /* 65 */ 0x798B_138E_3FE1_C845L, 0x22FB_D193_8E51_7BDFL, + /* 66 */ 0x4BF6_EC38_E7ED_1D2BL, 0x25DD_62FC_38F2_ED6CL, + /* 67 */ 0x5EF4_A747_21E8_6476L, 0x0F54_BBBB_472F_A8C6L, + /* 68 */ 0x76B1_D118_EA62_7D93L, 0x5329_EAAA_18FB_92F8L, + /* 69 */ 0x4A2F_22AF_927D_8E7CL, 0x23FA_32AA_4F9D_3BDBL, + /* 70 */ 0x5CBA_EB5B_771C_F21BL, 0x2CF8_BF54_E384_8AD2L, + /* 71 */ 0x73E9_A632_54E4_2EA2L, 0x1836_EF2A_1C65_AD86L, + /* 72 */ 0x4872_07DF_750E_9D25L, 0x2F22_557A_51BF_8C74L, + /* 73 */ 0x5A8E_89D7_5252_446EL, 0x5AEA_EAD8_E62F_6F91L, + /* 74 */ 0x7132_2C4D_26E6_D58AL, 0x31A5_A58F_1FBB_4B75L, + /* 75 */ 0x46BF_5BB0_3850_4576L, 0x3F07_8779_73D5_0F29L, + /* 76 */ 0x586F_329C_4664_56D4L, 0x0EC9_6957_D0CA_52F3L, + /* 77 */ 0x6E8A_FF43_57FD_6C89L, 0x127B_C3AD_C4FC_E7B0L, + /* 78 */ 0x4516_DF8A_16FE_63D5L, 0x5B8D_5A4C_9B1E_10CEL, + /* 79 */ 0x565C_976C_9CBD_FCCBL, 0x1270_B0DF_C1E5_9502L, + /* 80 */ 0x6BF3_BD47_C3ED_7BFDL, 0x770C_DD17_B25E_FA42L, + /* 81 */ 0x4378_564C_DA74_6D7EL, 0x5A68_0A2E_CF7B_5C69L, + /* 82 */ 0x5456_6BE0_1111_88DEL, 0x3102_0CBA_835A_3384L, + /* 83 */ 0x696C_06D8_1555_EB15L, 0x7D42_8FE9_2430_C065L, + /* 84 */ 0x41E3_8447_0D55_B2EDL, 0x5E49_99F1_B69E_783FL, + /* 85 */ 0x525C_6558_D0AB_1FA9L, 0x15DC_006E_2446_164FL, + /* 86 */ 0x66F3_7EAF_04D5_E793L, 0x3B53_0089_AD57_9BE2L, + /* 87 */ 0x4058_2F2D_6305_B0BCL, 0x1513_E056_0C56_C16EL, + /* 88 */ 0x506E_3AF8_BBC7_1CEBL, 0x1A58_D86B_8F6C_71C9L, + /* 89 */ 0x6489_C9B6_EAB8_E426L, 0x00EF_0E86_7347_8E3BL, + /* 90 */ 0x7DAC_3C24_A567_1D2FL, 0x412A_D228_1019_71C9L, + /* 91 */ 0x4E8B_A596_E760_723DL, 0x58BA_C359_0A0F_E71EL, + /* 92 */ 0x622E_8EFC_A138_8ECDL, 0x0EE9_742F_4C93_E0E6L, + /* 93 */ 0x7ABA_32BB_C986_B280L, 0x32A3_D13B_1FB8_D91FL, + /* 94 */ 0x4CB4_5FB5_5DF4_2F90L, 0x1FA6_62C4_F3D3_87B3L, + /* 95 */ 0x5FE1_77A2_B571_3B74L, 0x278F_FB76_30C8_69A0L, + /* 96 */ 0x77D9_D58B_62CD_8A51L, 0x3173_FA53_BCFA_8408L, + /* 97 */ 0x4AE8_2577_1DC0_7672L, 0x6EE8_7C74_561C_9285L, + /* 98 */ 0x5DA2_2ED4_E530_940FL, 0x4AA2_9B91_6BA3_B726L, + /* 99 */ 0x750A_BA8A_1E7C_B913L, 0x3D4B_4275_C68C_A4F0L, + /* 100 */ 0x4926_B496_530D_F3ACL, 0x164F_0989_9C17_E716L, + /* 101 */ 0x5B70_61BB_E7D1_7097L, 0x1BE2_CBEC_031D_E0DCL, + /* 102 */ 0x724C_7A2A_E1C5_CCBDL, 0x02DB_7EE7_03E5_5912L, + /* 103 */ 0x476F_CC5A_CD1B_9FF6L, 0x11C9_2F50_626F_57ACL, + /* 104 */ 0x594B_BF71_8062_87F3L, 0x563B_7B24_7B0B_2D96L, + /* 105 */ 0x6F9E_AF4D_E07B_29F0L, 0x4BCA_59ED_99CD_F8FCL, + /* 106 */ 0x45C3_2D90_AC4C_FA36L, 0x2F5E_7834_8020_BB9EL, + /* 107 */ 0x5733_F8F4_D760_38C3L, 0x7B36_1641_A028_EA85L, + /* 108 */ 0x6D00_F732_0D38_46F4L, 0x7A03_9BD2_0833_2526L, + /* 109 */ 0x4420_9A7F_4843_2C59L, 0x0C42_4163_451F_F738L, + /* 110 */ 0x5528_C11F_1A53_F76FL, 0x2F52_D1BC_1667_F506L, + /* 111 */ 0x6A72_F166_E0E8_F54BL, 0x1B27_862B_1C01_F247L, + /* 112 */ 0x4287_D6E0_4C91_994FL, 0x00F8_B3DA_F181_376DL, + /* 113 */ 0x5329_CC98_5FB5_FFA2L, 0x6136_E0D1_ADE1_8548L, + /* 114 */ 0x67F4_3FBE_77A3_7F8BL, 0x3984_9906_1959_E699L, + /* 115 */ 0x40F8_A7D7_0AC6_2FB7L, 0x13F2_DFA3_CFD8_3020L, + /* 116 */ 0x5136_D1CC_CD77_BBA4L, 0x78EF_978C_C3CE_3C28L, + /* 117 */ 0x6584_8640_00D5_AA8EL, 0x172B_7D6F_F4C1_CB32L, + /* 118 */ 0x7EE5_A7D0_010B_1531L, 0x5CF6_5CCB_F1F2_3DFEL, + /* 119 */ 0x4F4F_88E2_00A6_ED3FL, 0x0A19_F9FF_7737_66BFL, + /* 120 */ 0x6323_6B1A_80D0_A88EL, 0x6CA0_787F_5505_406FL, + /* 121 */ 0x7BEC_45E1_2104_D2B2L, 0x47C8_969F_2A46_908AL, + /* 122 */ 0x4D73_ABAC_B4A3_03AFL, 0x4CDD_5E23_7A6C_1A57L, + /* 123 */ 0x60D0_9697_E1CB_C49BL, 0x4014_B5AC_5907_20ECL, + /* 124 */ 0x7904_BC3D_DA3E_B5C2L, 0x3019_E317_6F48_E927L, + /* 125 */ 0x4BA2_F5A6_A867_3199L, 0x3E10_2DEE_A58D_91B9L, + /* 126 */ 0x5E8B_B310_5280_FDFFL, 0x6D94_396A_4EF0_F627L, + /* 127 */ 0x762E_9FD4_6721_3D7FL, 0x68F9_47C4_E2AD_33B0L, + /* 128 */ 0x49DD_23E4_C074_C66FL, 0x719B_CCDB_0DAC_404EL, + /* 129 */ 0x5C54_6CDD_F091_F80BL, 0x6E02_C011_D117_5062L, + /* 130 */ 0x7369_8815_6CB6_760EL, 0x6983_7016_455D_247AL, + /* 131 */ 0x4821_F50D_63F2_09C9L, 0x21F2_260D_EB5A_36CCL, + /* 132 */ 0x5A2A_7250_BCEE_8C3BL, 0x4A6E_AF91_6630_C47FL, + /* 133 */ 0x70B5_0EE4_EC2A_2F4AL, 0x3D0A_5B75_BFBC_F59FL, + /* 134 */ 0x4671_294F_139A_5D8EL, 0x4626_7929_97D6_1984L, + /* 135 */ 0x580D_73A2_D880_F4F2L, 0x17B0_1773_FDCB_9FE4L, + /* 136 */ 0x6E10_D08B_8EA1_322EL, 0x5D9C_1D50_FD3E_87DDL, + /* 137 */ 0x44CA_8257_3924_BF5DL, 0x1A81_9252_9E47_14EBL, + /* 138 */ 0x55FD_22ED_076D_EF34L, 0x4121_F6E7_45D8_DA25L, + /* 139 */ 0x6B7C_6BA8_4949_6B01L, 0x516A_74A1_174F_10AEL, + /* 140 */ 0x432D_C349_2DCD_E2E1L, 0x02E2_88E4_AE91_6A6DL, + /* 141 */ 0x53F9_341B_7941_5B99L, 0x239B_2B1D_DA35_C508L, + /* 142 */ 0x68F7_8122_5791_B27FL, 0x4C81_F5E5_50C3_364AL, + /* 143 */ 0x419A_B0B5_76BB_0F8FL, 0x5FD1_39AF_527A_01EFL, + /* 144 */ 0x5201_5CE2_D469_D373L, 0x57C5_881B_2718_826AL, + /* 145 */ 0x6681_B41B_8984_4850L, 0x4DB6_EA21_F0DE_A304L, + /* 146 */ 0x4011_1091_35F2_AD32L, 0x3092_5255_368B_25E3L, + /* 147 */ 0x5015_54B5_836F_587EL, 0x7CB6_E6EA_842D_EF5CL, + /* 148 */ 0x641A_A9E2_E44B_2E9EL, 0x5BE4_A0A5_2539_6B32L, + /* 149 */ 0x7D21_545B_9D5D_FA46L, 0x32DD_C8CE_6E87_C5FFL, + /* 150 */ 0x4E34_D4B9_425A_BC6BL, 0x7FCA_9D81_0514_DBBFL, + /* 151 */ 0x61C2_09E7_92F1_6B86L, 0x7FBD_44E1_465A_12AFL, + /* 152 */ 0x7A32_8C61_77AD_C668L, 0x5FAC_9619_97F0_975BL, + /* 153 */ 0x4C5F_97BC_EACC_9C01L, 0x3BCB_DDCF_FEF6_5E99L, + /* 154 */ 0x5F77_7DAC_257F_C301L, 0x6ABE_D543_FEB3_F63FL, + /* 155 */ 0x7755_5D17_2EDF_B3C2L, 0x256E_8A94_FE60_F3CFL, + /* 156 */ 0x4A95_5A2E_7D4B_D059L, 0x3765_169D_1EFC_9861L, + /* 157 */ 0x5D3A_B0BA_1C9E_C46FL, 0x653E_5C44_66BB_BE7AL, + /* 158 */ 0x7489_5CE8_A3C6_758BL, 0x5E8D_F355_806A_AE18L, + /* 159 */ 0x48D5_DA11_665C_0977L, 0x2B18_B815_7042_ACCFL, + /* 160 */ 0x5B0B_5095_BFF3_0BD5L, 0x15DE_E61A_CC53_5803L, + /* 161 */ 0x71CE_24BB_2FEF_CECAL, 0x3B56_9FA1_7F68_2E03L, + /* 162 */ 0x4720_D6F4_FDF5_E13EL, 0x4516_23C4_EFA1_1CC2L, + /* 163 */ 0x58E9_0CB2_3D73_598EL, 0x165B_ACB6_2B89_63F3L, + /* 164 */ 0x6F23_4FDE_CCD0_2FF1L, 0x5BF2_97E3_B66B_BCEFL, + /* 165 */ 0x4576_11EB_4002_1DF7L, 0x0977_9EEE_5203_5616L, + /* 166 */ 0x56D3_9666_1002_A574L, 0x6BD5_86A9_E684_2B9BL, + /* 167 */ 0x6C88_7BFF_9403_4ED2L, 0x06CA_E854_6025_3682L, + /* 168 */ 0x43D5_4D7F_BC82_1143L, 0x243E_D134_BC17_4211L, + /* 169 */ 0x54CA_A0DF_ABA2_9594L, 0x0D4E_8581_EB1D_1295L, + /* 170 */ 0x69FD_4917_968B_3AF9L, 0x10A2_26E2_65E4_573BL, + /* 171 */ 0x423E_4DAE_BE17_04DBL, 0x5A65_584D_7FAE_B685L, + /* 172 */ 0x52CD_E11A_6D9C_C612L, 0x50FE_AE60_DF9A_6426L, + /* 173 */ 0x6781_5961_0903_F797L, 0x253E_59F9_1780_FD2FL, + /* 174 */ 0x40B0_D7DC_A5A2_7ABEL, 0x4746_F83B_AEB0_9E3EL, + /* 175 */ 0x50DD_0DD3_CF0B_196EL, 0x1918_B64A_9A5C_C5CDL, + /* 176 */ 0x6514_5148_C2CD_DFC9L, 0x5F5E_E3DD_40F3_F740L, + /* 177 */ 0x7E59_659A_F381_57BCL, 0x1736_9CD4_9130_F510L, + /* 178 */ 0x4EF7_DF80_D830_D6D5L, 0x4E82_2204_DABE_992AL, + /* 179 */ 0x62B5_D761_0E3D_0C8BL, 0x0222_AA86_116E_3F75L, + /* 180 */ 0x7B63_4D39_51CC_4FADL, 0x62AB_5527_95C9_CF52L, + /* 181 */ 0x4D1E_1043_D31F_B1CCL, 0x4DAB_1538_BD9E_2193L, + /* 182 */ 0x6065_9454_C7E7_9E3FL, 0x6115_DA86_ED05_A9F8L, + /* 183 */ 0x787E_F969_F9E1_85CFL, 0x595B_5128_A847_1476L, + /* 184 */ 0x4B4F_5BE2_3C2C_F3A1L, 0x67D9_12B9_692C_6CCAL, + /* 185 */ 0x5E23_32DA_CB38_308AL, 0x21CF_5767_C377_87FCL, + /* 186 */ 0x75AB_FF91_7E06_3CACL, 0x6A43_2D41_B455_69FBL, + /* 187 */ 0x498B_7FBA_EEC3_E5ECL, 0x0269_FC49_10B5_623DL, + /* 188 */ 0x5BEE_5FA9_AA74_DF67L, 0x0304_7B5B_54E2_BACCL, + /* 189 */ 0x72E9_F794_1512_1740L, 0x63C5_9A32_2A1B_697FL, + /* 190 */ 0x47D2_3ABC_8D2B_4E88L, 0x3E5B_805F_5A51_21F0L, + /* 191 */ 0x59C6_C96B_B076_222AL, 0x4DF2_6077_30E5_6A6CL, + /* 192 */ 0x7038_7BC6_9C93_AAB5L, 0x216E_F894_FD1E_C506L, + /* 193 */ 0x4623_4D5C_21DC_4AB1L, 0x24E5_5B5D_1E33_3B24L, + /* 194 */ 0x57AC_20B3_2A53_5D5DL, 0x4E1E_B234_65C0_09EDL, + /* 195 */ 0x6D97_28DF_F4E8_34B5L, 0x01A6_5EC1_7F30_0C68L, + /* 196 */ 0x447E_798B_F911_20F1L, 0x1107_FB38_EF7E_07C1L, + /* 197 */ 0x559E_17EE_F755_692DL, 0x3549_FA07_2B5D_89B1L, + /* 198 */ 0x6B05_9DEA_B52A_C378L, 0x629C_7888_F634_EC1EL, + /* 199 */ 0x42E3_82B2_B13A_BA2BL, 0x3DA1_CB55_99E1_1393L, + /* 200 */ 0x539C_635F_5D89_68B6L, 0x2D0A_3E2B_0059_5877L, + /* 201 */ 0x6883_7C37_34EB_C2E3L, 0x784C_CDB5_C06F_AE95L, + /* 202 */ 0x4152_2DA2_8113_59CEL, 0x3B30_0091_9845_CD1DL, + /* 203 */ 0x51A6_B90B_2158_3042L, 0x09FC_00B5_FE57_4065L, + /* 204 */ 0x6610_674D_E9AE_3C52L, 0x4C7B_00E3_7DED_107EL, + /* 205 */ 0x7F94_8121_6419_CB67L, 0x1F99_C11C_5D68_549DL, + /* 206 */ 0x4FBC_D0B4_DE90_1F20L, 0x43C0_18B1_BA61_34E2L, + /* 207 */ 0x63AC_04E2_1634_26E8L, 0x54B0_1EDE_28F9_821BL, + /* 208 */ 0x7C97_061A_9BC1_30A2L, 0x69DC_2695_B337_E2A1L, + /* 209 */ 0x4DDE_63D0_A158_BE65L, 0x6229_981D_9002_EDA5L, + /* 210 */ 0x6155_FCC4_C9AE_EDFFL, 0x1AB3_FE24_F403_A90EL, + /* 211 */ 0x79AB_7BF5_FC1A_A97FL, 0x0160_FDAE_3104_9351L, + /* 212 */ 0x4C0B_2D79_BD90_A9EFL, 0x30DC_9E8C_DEA2_DC13L, + /* 213 */ 0x5F0D_F8D8_2CF4_D46BL, 0x1D13_C630_164B_9318L, + /* 214 */ 0x76D1_770E_3832_0986L, 0x0458_B7BC_1BDE_77DDL, + /* 215 */ 0x4A42_EA68_E31F_45F3L, 0x62B7_72D5_916B_0AEBL, + /* 216 */ 0x5CD3_A503_1BE7_1770L, 0x5B65_4F8A_F5C5_CDA5L, + /* 217 */ 0x7408_8E43_E2E0_DD4CL, 0x723E_A36D_B337_410EL, + /* 218 */ 0x4885_58EA_6DCC_8A50L, 0x0767_2624_9002_88A9L, + /* 219 */ 0x5AA6_AF25_093F_ACE4L, 0x0940_EFAD_B403_2AD3L, + /* 220 */ 0x7150_5AEE_4B8F_981DL, 0x0B91_2B99_2103_F588L, + /* 221 */ 0x46D2_38D4_EF39_BF12L, 0x173A_BB3F_B4A2_7975L, + /* 222 */ 0x5886_C70A_2B08_2ED6L, 0x5D09_6A0F_A1CB_17D2L, + /* 223 */ 0x6EA8_78CC_B5CA_3A8CL, 0x344B_C493_8A3D_DDC7L, + /* 224 */ 0x4529_4B7F_F19E_6497L, 0x60AF_5ADC_3666_AA9CL, + /* 225 */ 0x5673_9E5F_EE05_FDBDL, 0x58DB_3193_4400_5543L, + /* 226 */ 0x6C10_85F7_E987_7D2DL, 0x0F11_FDF8_1500_6A94L, + /* 227 */ 0x438A_53BA_F1F4_AE3CL, 0x196B_3EBB_0D20_429DL, + /* 228 */ 0x546C_E8A9_AE71_D9CBL, 0x1FC6_0E69_D068_5344L, + /* 229 */ 0x6988_22D4_1A0E_503EL, 0x07B7_9204_4482_6815L, + /* 230 */ 0x41F5_15C4_9048_F226L, 0x64D2_BB42_AAD1_810DL, + /* 231 */ 0x5272_5B35_B45B_2EB0L, 0x3E07_6A13_5585_E150L, + /* 232 */ 0x670E_F203_2171_FA5CL, 0x4D89_4498_2AE7_59A4L, + /* 233 */ 0x4069_5741_F4E7_3C79L, 0x7075_CADF_1AD0_9807L, + /* 234 */ 0x5083_AD12_7221_0B98L, 0x2C93_3D96_E184_BE08L, + /* 235 */ 0x64A4_9857_0EA9_4E7EL, 0x37B8_0CFC_99E5_ED8AL, + /* 236 */ 0x7DCD_BE6C_D253_A21EL, 0x05A6_103B_C05F_68EDL, + /* 237 */ 0x4EA0_9704_0374_4552L, 0x6387_CA25_583B_A194L, + /* 238 */ 0x6248_BCC5_0451_56A7L, 0x3C69_BCAE_AE4A_89F9L, + /* 239 */ 0x7ADA_EBF6_4565_AC51L, 0x2B84_2BDA_59DD_2C77L, + /* 240 */ 0x4CC8_D379_EB5F_8BB2L, 0x6B32_9B68_782A_3BCBL, + /* 241 */ 0x5FFB_0858_6637_6E9FL, 0x45FF_4242_9634_CABDL, + /* 242 */ 0x77F9_CA6E_7FC5_4A47L, 0x377F_12D3_3BC1_FD6DL, + /* 243 */ 0x4AFC_1E85_0FDB_4E6CL, 0x52AF_6BC4_0559_3E64L, + /* 244 */ 0x5DBB_2626_53D2_2207L, 0x675B_46B5_06AF_8DFDL, + /* 245 */ 0x7529_EFAF_E8C6_AA89L, 0x6132_1862_485B_717CL, + /* 246 */ 0x493A_35CD_F17C_2A96L, 0x0CBF_4F3D_6D39_26EEL, + /* 247 */ 0x5B88_C341_6DDB_353BL, 0x4FEF_230C_C887_70A9L, + /* 248 */ 0x726A_F411_C952_028AL, 0x43EA_EBCF_FAA9_4CD3L, + /* 249 */ 0x4782_D88B_1DD3_4196L, 0x4A72_D361_FCA9_D004L, + /* 250 */ 0x5963_8EAD_E548_11FCL, 0x1D0F_883A_7BD4_4405L, + /* 251 */ 0x6FBC_7259_5E9A_167BL, 0x2453_6A49_1AC9_5506L, + /* 252 */ 0x45D5_C777_DB20_4E0DL, 0x06B4_226D_B0BD_D524L, + /* 253 */ 0x574B_3955_D1E8_6190L, 0x2861_2B09_1CED_4A6DL, + /* 254 */ 0x6D1E_07AB_4662_79F4L, 0x3279_75CB_6428_9D08L, + /* 255 */ 0x4432_C4CB_0BFD_8C38L, 0x5F8B_E99F_1E99_6225L, + /* 256 */ 0x553F_75FD_CEFC_EF46L, 0x776E_E406_E63F_BAAEL, + /* 257 */ 0x6A8F_537D_42BC_2B18L, 0x554A_9D08_9FCF_A95AL, + /* 258 */ 0x4299_942E_49B5_9AEFL, 0x354E_A225_63E1_C9D8L, + /* 259 */ 0x533F_F939_DC23_01ABL, 0x22A2_4AAE_BCDA_3C4EL, + /* 260 */ 0x680F_F788_532B_C216L, 0x0B4A_DD5A_6C10_CB62L, + /* 261 */ 0x4109_FAB5_33FB_594DL, 0x670E_CA58_838A_7F1DL, + /* 262 */ 0x514C_7962_80FA_2FA1L, 0x20D2_7CEE_A46D_1EE4L, + /* 263 */ 0x659F_97BB_2138_BB89L, 0x4907_1C2A_4D88_669DL, + /* 264 */ 0x7F07_7DA9_E986_EA6BL, 0x7B48_E334_E0EA_8045L, + /* 265 */ 0x4F64_AE8A_31F4_5283L, 0x3D0D_8E01_0C92_902BL, + /* 266 */ 0x633D_DA2C_BE71_6724L, 0x2C50_F181_4FB7_3436L, + /* 267 */ 0x7C0D_50B7_EE0D_C0EDL, 0x3765_2DE1_A3A5_0143L, + /* 268 */ 0x4D88_5272_F4C8_9894L, 0x329F_3CAD_0647_20CAL, + /* 269 */ 0x60EA_670F_B1FA_BEB9L, 0x3F47_0BD8_47D8_E8FDL, + /* 270 */ 0x7925_00D3_9E79_6E67L, 0x6F18_CECE_59CF_233CL, + /* 271 */ 0x4BB7_2084_430B_E500L, 0x756F_8140_F821_7605L, + /* 272 */ 0x5EA4_E8A5_53CE_DE41L, 0x12CB_6191_3629_D387L, + /* 273 */ 0x764E_22CE_A8C2_95D1L, 0x377E_39F5_83B4_4868L, + /* 274 */ 0x49F0_D5C1_2979_9DA2L, 0x72AE_E439_7250_AD41L, + /* 275 */ 0x5C6D_0B31_73D8_050BL, 0x4F5A_9D47_CEE4_D891L, + /* 276 */ 0x7388_4DFD_D0CE_064EL, 0x4331_4499_C29E_0EB6L, + /* 277 */ 0x4835_30BE_A280_C3F1L, 0x09FE_CAE0_19A2_C932L, + /* 278 */ 0x5A42_7CEE_4B20_F4EDL, 0x2C7E_7D98_200B_7B7EL, + /* 279 */ 0x70D3_1C29_DDE9_3228L, 0x579E_1CFE_280E_5A5DL, + /* 280 */ 0x4683_F19A_2AB1_BF59L, 0x36C2_D21E_D908_F87BL, + /* 281 */ 0x5824_EE00_B55E_2F2FL, 0x6473_86A6_8F4B_3699L, + /* 282 */ 0x6E2E_2980_E2B5_BAFBL, 0x5D90_6850_331E_043FL, + /* 283 */ 0x44DC_D9F0_8DB1_94DDL, 0x2A7A_4132_1FF2_C2A8L, + /* 284 */ 0x5614_106C_B11D_FA14L, 0x5518_D17E_A7EF_7352L, + /* 285 */ 0x6B99_1487_DD65_7899L, 0x6A5F_05DE_51EB_5026L, + /* 286 */ 0x433F_ACD4_EA5F_6B60L, 0x127B_63AA_F333_1218L, + /* 287 */ 0x540F_980A_24F7_4638L, 0x171A_3C95_AFFF_D69EL, + /* 288 */ 0x6913_7E0C_AE35_17C6L, 0x1CE0_CBBB_1BFF_CC45L, + /* 289 */ 0x41AC_2EC7_ECE1_2EDBL, 0x720C_7F54_F17F_DFABL, + /* 290 */ 0x5217_3A79_E819_7A92L, 0x6E8F_9F2A_2DDF_D796L, + /* 291 */ 0x669D_0918_621F_D937L, 0x4A33_86F4_B957_CD7BL, + /* 292 */ 0x4022_25AF_3D53_E7C2L, 0x5E60_3458_F3D6_E06DL, + /* 293 */ 0x502A_AF1B_0CA8_E1B3L, 0x35F8_416F_30CC_9888L, + /* 294 */ 0x6435_5AE1_CFD3_1A20L, 0x2376_51CA_FCFF_BEAAL, + /* 295 */ 0x7D42_B19A_43C7_E0A8L, 0x2C53_E63D_BC3F_AE55L, + /* 296 */ 0x4E49_AF00_6A5C_EC69L, 0x1BB4_6FE6_95A7_CCF5L, + /* 297 */ 0x61DC_1AC0_84F4_2783L, 0x42A1_8BE0_3B11_C033L, + /* 298 */ 0x7A53_2170_A631_3164L, 0x3349_EED8_49D6_303FL, + /* 299 */ 0x4C73_F4E6_67DE_BEDEL, 0x600E_3547_2E25_DE28L, + /* 300 */ 0x5F90_F220_01D6_6E96L, 0x3811_C298_F9AF_55B1L, + /* 301 */ 0x7775_2EA8_024C_0A3CL, 0x0616_333F_381B_2B1EL, + /* 302 */ 0x4AA9_3D29_016F_8665L, 0x43CD_E007_8310_FAF3L, + /* 303 */ 0x5D53_8C73_41CB_67FEL, 0x74C1_5809_63D5_39AFL, + /* 304 */ 0x74A8_6F90_123E_41FEL, 0x51F1_AE0B_BCCA_881BL, + /* 305 */ 0x48E9_45BA_0B66_E93FL, 0x1337_0CC7_55FE_9511L, + /* 306 */ 0x5B23_9728_8E40_A38EL, 0x7804_CFF9_2B7E_3A55L, + /* 307 */ 0x71EC_7CF2_B1D0_CC72L, 0x5606_03F7_765D_C8EAL, + /* 308 */ 0x4733_CE17_AF22_7FC7L, 0x55C3_C27A_A9FA_9D93L, + /* 309 */ 0x5900_C19D_9AEB_1FB9L, 0x4B34_B319_5479_44F7L, + /* 310 */ 0x6F40_F205_01A5_E7A7L, 0x7E01_DFDF_A997_9635L, + /* 311 */ 0x4588_9743_2107_B0C8L, 0x7EC1_2BEB_C9FE_BDE1L, + /* 312 */ 0x56EA_BD13_E949_9CFBL, 0x1E71_76E6_BC7E_6D59L, + /* 313 */ 0x6CA5_6C58_E39C_043AL, 0x060D_D4A0_6B9E_08B0L, + /* 314 */ 0x43E7_63B7_8E41_82A4L, 0x23C8_A4E4_4342_C56EL, + /* 315 */ 0x54E1_3CA5_71D1_E34DL, 0x2CBA_CE1D_5413_76C9L, + /* 316 */ 0x6A19_8BCE_CE46_5C20L, 0x57E9_81A4_A918_547BL, + /* 317 */ 0x424F_F761_40EB_F994L, 0x36F1_F106_E9AF_34CDL, + /* 318 */ 0x52E3_F539_9126_F7F9L, 0x44AE_6D48_A41B_0201L, + /* 319 */ 0x679C_F287_F570_B5F7L, 0x75DA_089A_CD21_C281L, + /* 320 */ 0x40C2_1794_F966_71BAL, 0x79A8_4560_C035_1991L, + /* 321 */ 0x50F2_9D7A_37C0_0E29L, 0x5812_56B8_F042_5FF5L, + /* 322 */ 0x652F_44D8_C5B0_11B4L, 0x0E16_EC67_2C52_F7F2L, + /* 323 */ 0x7E7B_160E_F71C_1621L, 0x119C_A780_F767_B5EEL, + /* 324 */ 0x4F0C_EDC9_5A71_8DD4L, 0x5B01_E8B0_9AA0_D1B5L, + }; + +} diff --git a/test/jdk/java/lang/String/concat/ImplicitStringConcatBoundaries.java b/test/jdk/java/lang/String/concat/ImplicitStringConcatBoundaries.java --- a/test/jdk/java/lang/String/concat/ImplicitStringConcatBoundaries.java +++ b/test/jdk/java/lang/String/concat/ImplicitStringConcatBoundaries.java @@ -168,9 +168,9 @@ test("foo2147483647", "foo" + INT_MAX_2); test("foo-2147483648", "foo" + INT_MIN_1); test("foo-2147483648", "foo" + INT_MIN_2); - - test("foo1.17549435E-38", "foo" + FLOAT_MIN_NORM_1); - test("foo1.17549435E-38", "foo" + FLOAT_MIN_NORM_2); + + test("foo1.1754944E-38", "foo" + FLOAT_MIN_NORM_1); + test("foo1.1754944E-38", "foo" + FLOAT_MIN_NORM_2 ); test("foo-126.0", "foo" + FLOAT_MIN_EXP_1); test("foo-126.0", "foo" + FLOAT_MIN_EXP_2); test("foo1.4E-45", "foo" + FLOAT_MIN_1); diff --git a/test/jdk/jdk/internal/math/ToDecimal/DoubleToDecimalTest.java b/test/jdk/jdk/internal/math/ToDecimal/DoubleToDecimalTest.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/DoubleToDecimalTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import jdk.internal.math.DoubleToDecimalChecker; +import jdk.test.lib.RandomFactory; + +/* + * @test + * @bug 8202555 + * @author Raffaello Giulietti + * @key randomness + * + * @modules java.base/jdk.internal.math + * @library /test/lib + * @library java.base + * @build jdk.test.lib.RandomFactory + * @build java.base/jdk.internal.math.* + * @run main DoubleToDecimalTest 1_000_000 + */ +public class DoubleToDecimalTest { + + private static final int RANDOM_COUNT = 100_000; + + public static void main(String[] args) { + int count = RANDOM_COUNT; + if (args.length == 0) { + DoubleToDecimalChecker.test(count, RandomFactory.getRandom()); + return; + } + try { + count = Integer.parseInt(args[0].replace("_", "")); + } catch (NumberFormatException ignored) { + } + DoubleToDecimalChecker.test(count, RandomFactory.getRandom()); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/FloatToDecimalTest.java b/test/jdk/jdk/internal/math/ToDecimal/FloatToDecimalTest.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/FloatToDecimalTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import jdk.internal.math.FloatToDecimalChecker; +import jdk.test.lib.RandomFactory; + +/* + * @test + * @author Raffaello Giulietti + * @key randomness + * + * @modules java.base/jdk.internal.math + * @library /test/lib + * @library java.base + * @build jdk.test.lib.RandomFactory + * @build java.base/jdk.internal.math.* + * @run main FloatToDecimalTest 1_000_000 + */ +public class FloatToDecimalTest { + + private static final int RANDOM_COUNT = 100_000; + + public static void main(String[] args) { + int count = RANDOM_COUNT; + if (args.length == 0) { + FloatToDecimalChecker.test(count, RandomFactory.getRandom()); + return; + } + if (args[0].equals("all")) { + FloatToDecimalChecker.testAll(); + return; + } + if (args[0].equals("positive")) { + FloatToDecimalChecker.testPositive(); + return; + } + try { + count = Integer.parseInt(args[0].replace("_", "")); + } catch (NumberFormatException ignored) { + } + FloatToDecimalChecker.test(count, RandomFactory.getRandom()); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/MathUtilsTest.java b/test/jdk/jdk/internal/math/ToDecimal/MathUtilsTest.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/MathUtilsTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import jdk.internal.math.MathUtilsChecker; + +/* + * @test + * @author Raffaello Giulietti + * + * @modules java.base/jdk.internal.math + * @library java.base + * @build java.base/jdk.internal.math.* + * @run main MathUtilsTest + */ +public class MathUtilsTest { + + public static void main(String[] args) { + MathUtilsChecker.test(); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/BasicChecker.java b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/BasicChecker.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/BasicChecker.java @@ -0,0 +1,18 @@ +package jdk.internal.math; + +class BasicChecker { + + static final boolean FAILURE_THROWS_EXCEPTION = true; + + static void assertTrue(boolean ok, String valueName) { + if (ok) { + return; + } + String msg = valueName + " is not correct"; + if (FAILURE_THROWS_EXCEPTION) { + throw new RuntimeException(msg); + } + System.err.println(msg); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/DoubleToDecimalChecker.java b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/DoubleToDecimalChecker.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/DoubleToDecimalChecker.java @@ -0,0 +1,391 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +import java.math.BigDecimal; +import java.util.Random; + +import static java.lang.Double.*; +import static java.lang.Long.numberOfTrailingZeros; +import static java.lang.Math.scalb; +import static jdk.internal.math.DoubleToDecimal.*; +import static jdk.internal.math.MathUtils.flog10pow2; + +public class DoubleToDecimalChecker extends ToDecimalChecker { + + private double v; + private final long originalBits; + + private DoubleToDecimalChecker(double v, String s) { + super(s); + this.v = v; + originalBits = doubleToRawLongBits(v); + } + + @Override + BigDecimal toBigDecimal() { + return new BigDecimal(v); + } + + @Override + boolean recovers(BigDecimal b) { + return b.doubleValue() == v; + } + + @Override + boolean recovers(String s) { + return parseDouble(s) == v; + } + + @Override + String hexBits() { + return String.format("0x%01X__%03X__%01X_%04X_%04X_%04X", + (int) (originalBits >>> 63) & 0x1, + (int) (originalBits >>> 52) & 0x7FF, + (int) (originalBits >>> 48) & 0xF, + (int) (originalBits >>> 32) & 0xFFFF, + (int) (originalBits >>> 16) & 0xFFFF, + (int) originalBits & 0xFFFF); + } + + @Override + int minExp() { + return MIN_EXP; + } + + @Override + int maxExp() { + return MAX_EXP; + } + + @Override + int maxLen10() { + return H; + } + + @Override + boolean isZero() { + return v == 0; + } + + @Override + boolean isInfinity() { + return v == POSITIVE_INFINITY; + } + + @Override + void negate() { + v = -v; + } + + @Override + boolean isNegative() { + return originalBits < 0; + } + + @Override + boolean isNaN() { + return Double.isNaN(v); + } + + private static void toDec(double v) { +// String s = Double.toString(v); + String s = DoubleToDecimal.toString(v); + new DoubleToDecimalChecker(v, s).assertTrue(); + } + + private static void testExtremeValues() { + toDec(NEGATIVE_INFINITY); + toDec(-MAX_VALUE); + toDec(-MIN_NORMAL); + toDec(-MIN_VALUE); + toDec(-0.0); + toDec(0.0); + toDec(MIN_VALUE); + toDec(MIN_NORMAL); + toDec(MAX_VALUE); + toDec(POSITIVE_INFINITY); + toDec(NaN); + + /* + Quiet NaNs have the most significant bit of the mantissa as 1, + while signaling NaNs have it as 0. + Exercise 4 combinations of quiet/signaling NaNs and + "positive/negative" NaNs + */ + toDec(longBitsToDouble(0x7FF8_0000_0000_0001L)); + toDec(longBitsToDouble(0x7FF0_0000_0000_0001L)); + toDec(longBitsToDouble(0xFFF8_0000_0000_0001L)); + toDec(longBitsToDouble(0xFFF0_0000_0000_0001L)); + + /* + All values treated specially by Schubfach + */ + toDec(4.9E-324); + toDec(9.9E-324); + } + + /* + A few "powers of 10" are incorrectly rendered by the JDK. + The rendering is either too long or it is not the closest decimal. + */ + private static void testPowersOf10() { + for (int e = MIN_EXP; e <= MAX_EXP; ++e) { + toDec(parseDouble("1e" + e)); + } + } + + /* + Many powers of 2 are incorrectly rendered by the JDK. + The rendering is either too long or it is not the closest decimal. + */ + private static void testPowersOf2() { + for (double v = MIN_VALUE; v <= MAX_VALUE; v *= 2) { + toDec(v); + } + } + + /* + There are many doubles that are rendered incorrectly by the JDK. + While the renderings correctly round back to the original value, + they are longer than needed or are not the closest decimal to the double. + Here are just a very few examples. + */ + private static final String[] Anomalies = { + // JDK renders these, and others, with 18 digits! + "2.82879384806159E17", "1.387364135037754E18", + "1.45800632428665E17", + + // JDK renders these longer than needed. + "1.6E-322", "6.3E-322", + "7.3879E20", "2.0E23", "7.0E22", "9.2E22", + "9.5E21", "3.1E22", "5.63E21", "8.41E21", + + // JDK does not render these, and many others, as the closest. + "9.9E-324", "9.9E-323", + "1.9400994884341945E25", "3.6131332396758635E25", + "2.5138990223946153E25", + }; + + private static void testSomeAnomalies() { + for (String dec : Anomalies) { + toDec(parseDouble(dec)); + } + } + + /* + Values are from + Paxson V, "A Program for Testing IEEE Decimal-Binary Conversion" + tables 3 and 4 + */ + private static final double[] PaxsonSignificands = { + 8_511_030_020_275_656L, + 5_201_988_407_066_741L, + 6_406_892_948_269_899L, + 8_431_154_198_732_492L, + 6_475_049_196_144_587L, + 8_274_307_542_972_842L, + 5_381_065_484_265_332L, + 6_761_728_585_499_734L, + 7_976_538_478_610_756L, + 5_982_403_858_958_067L, + 5_536_995_190_630_837L, + 7_225_450_889_282_194L, + 7_225_450_889_282_194L, + 8_703_372_741_147_379L, + 8_944_262_675_275_217L, + 7_459_803_696_087_692L, + 6_080_469_016_670_379L, + 8_385_515_147_034_757L, + 7_514_216_811_389_786L, + 8_397_297_803_260_511L, + 6_733_459_239_310_543L, + 8_091_450_587_292_794L, + + 6_567_258_882_077_402L, + 6_712_731_423_444_934L, + 6_712_731_423_444_934L, + 5_298_405_411_573_037L, + 5_137_311_167_659_507L, + 6_722_280_709_661_868L, + 5_344_436_398_034_927L, + 8_369_123_604_277_281L, + 8_995_822_108_487_663L, + 8_942_832_835_564_782L, + 8_942_832_835_564_782L, + 8_942_832_835_564_782L, + 6_965_949_469_487_146L, + 6_965_949_469_487_146L, + 6_965_949_469_487_146L, + 7_487_252_720_986_826L, + 5_592_117_679_628_511L, + 8_887_055_249_355_788L, + 6_994_187_472_632_449L, + 8_797_576_579_012_143L, + 7_363_326_733_505_337L, + 8_549_497_411_294_502L, + }; + + private static final int[] PaxsonExponents = { + -342, + -824, + 237, + 72, + 99, + 726, + -456, + -57, + 376, + 377, + 93, + 710, + 709, + 117, + -1, + -707, + -381, + 721, + -828, + -345, + 202, + -473, + + 952, + 535, + 534, + -957, + -144, + 363, + -169, + -853, + -780, + -383, + -384, + -385, + -249, + -250, + -251, + 548, + 164, + 665, + 690, + 588, + 272, + -448, + }; + + private static void testPaxson() { + for (int i = 0; i < PaxsonSignificands.length; ++i) { + toDec(scalb(PaxsonSignificands[i], PaxsonExponents[i])); + } + } + + /* + Tests all integers of the form yx_xxx_000_000_000_000_000, y != 0. + These are all exact doubles. + */ + private static void testLongs() { + for (int i = 10_000; i < 100_000; ++i) { + toDec(i * 1e15); + } + } + + /* + Tests all integers up to 1_000_000. + These are all exact doubles and exercise a fast path. + */ + private static void testInts() { + for (int i = 0; i <= 1_000_000; ++i) { + toDec(i); + } + } + + /* + Random doubles over the whole range + */ + private static void testRandom(int randomCount, Random r) { + for (int i = 0; i < randomCount; ++i) { + toDec(longBitsToDouble(r.nextLong())); + } + } + + /* + Random doubles over the integer range [0, 2^52). + These are all exact doubles and exercise the fast path (except 0). + */ + private static void testRandomUnit(int randomCount, Random r) { + for (int i = 0; i < randomCount; ++i) { + toDec(r.nextLong() & (1L << P - 1)); + } + } + + /* + Random doubles over the range [0, 10^15) as "multiples" of 1e-3 + */ + private static void testRandomMilli(int randomCount, Random r) { + for (int i = 0; i < randomCount; ++i) { + toDec(r.nextLong() % 1_000_000_000_000_000_000L / 1e3); + } + } + + /* + Random doubles over the range [0, 10^15) as "multiples" of 1e-6 + */ + private static void testRandomMicro(int randomCount, Random r) { + for (int i = 0; i < randomCount; ++i) { + toDec((r.nextLong() & 0x7FFF_FFFF_FFFF_FFFFL) / 1e6); + } + } + + private static void testConstants() { + assertTrue(precision() == P, "P"); + assertTrue(flog10pow2(P) + 2 == H, "H"); + assertTrue(e(MIN_VALUE) == MIN_EXP, "MIN_EXP"); + assertTrue(e(MAX_VALUE) == MAX_EXP, "MAX_EXP"); + } + + private static int precision() { + /* + Given precision P, the floating point value 3 has the bits + 0e...e10...0 + where there are exactly P - 2 trailing zeroes. + */ + return numberOfTrailingZeros(doubleToRawLongBits(3)) + 2; + } + + public static void test(int randomCount, Random r) { + testConstants(); + testExtremeValues(); + testSomeAnomalies(); + testPowersOf2(); + testPowersOf10(); + testPaxson(); + testInts(); + testLongs(); + testRandom(randomCount, r); + testRandomUnit(randomCount, r); + testRandomMilli(randomCount, r); + testRandomMicro(randomCount, r); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/FloatToDecimalChecker.java b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/FloatToDecimalChecker.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/FloatToDecimalChecker.java @@ -0,0 +1,327 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +import java.math.BigDecimal; +import java.util.Random; + +import static java.lang.Float.*; +import static java.lang.Integer.numberOfTrailingZeros; +import static java.lang.Math.scalb; +import static jdk.internal.math.FloatToDecimal.*; +import static jdk.internal.math.MathUtils.flog10pow2; + +public class FloatToDecimalChecker extends ToDecimalChecker { + + private float v; + private final int originalBits; + + private FloatToDecimalChecker(float v, String s) { + super(s); + this.v = v; + originalBits = floatToRawIntBits(v); + } + + @Override + BigDecimal toBigDecimal() { + return new BigDecimal(v); + } + + @Override + boolean recovers(BigDecimal b) { + return b.floatValue() == v; + } + + @Override + String hexBits() { + return String.format("0x%01X__%02X__%02X_%04X", + (originalBits >>> 31) & 0x1, + (originalBits >>> 23) & 0xFF, + (originalBits >>> 16) & 0x7F, + originalBits & 0xFFFF); + } + + @Override + boolean recovers(String s) { + return parseFloat(s) == v; + } + + @Override + int minExp() { + return MIN_EXP; + } + + @Override + int maxExp() { + return MAX_EXP; + } + + @Override + int maxLen10() { + return H; + } + + @Override + boolean isZero() { + return v == 0; + } + + @Override + boolean isInfinity() { + return v == POSITIVE_INFINITY; + } + + @Override + void negate() { + v = -v; + } + + @Override + boolean isNegative() { + return originalBits < 0; + } + + @Override + boolean isNaN() { + return Float.isNaN(v); + } + + private static void toDec(float v) { +// String s = Float.toString(v); + String s = FloatToDecimal.toString(v); + new FloatToDecimalChecker(v, s).assertTrue(); + } + + /* + MIN_NORMAL is incorrectly rendered by the JDK. + */ + private static void testExtremeValues() { + toDec(NEGATIVE_INFINITY); + toDec(-MAX_VALUE); + toDec(-MIN_NORMAL); + toDec(-MIN_VALUE); + toDec(-0.0f); + toDec(0.0f); + toDec(MIN_VALUE); + toDec(MIN_NORMAL); + toDec(MAX_VALUE); + toDec(POSITIVE_INFINITY); + toDec(NaN); + + /* + Quiet NaNs have the most significant bit of the mantissa as 1, + while signaling NaNs have it as 0. + Exercise 4 combinations of quiet/signaling NaNs and + "positive/negative" NaNs. + */ + toDec(intBitsToFloat(0x7FC0_0001)); + toDec(intBitsToFloat(0x7F80_0001)); + toDec(intBitsToFloat(0xFFC0_0001)); + toDec(intBitsToFloat(0xFF80_0001)); + + /* + All values treated specially by Schubfach + */ + toDec(1.4E-45F); + toDec(2.8E-45F); + toDec(4.2E-45F); + toDec(5.6E-45F); + toDec(7.0E-45F); + toDec(8.4E-45F); + toDec(9.8E-45F); + } + + /* + A few "powers of 10" are incorrectly rendered by the JDK. + The rendering is either too long or it is not the closest decimal. + */ + private static void testPowersOf10() { + for (int e = MIN_EXP; e <= MAX_EXP; ++e) { + toDec(parseFloat("1e" + e)); + } + } + + /* + Many powers of 2 are incorrectly rendered by the JDK. + The rendering is either too long or it is not the closest decimal. + */ + private static void testPowersOf2() { + for (float v = MIN_VALUE; v <= MAX_VALUE; v *= 2) { + toDec(v); + } + } + + /* + There are many floats that are rendered incorrectly by the JDK. + While the renderings correctly round back to the original value, + they are longer than needed or are not the closest decimal to the float. + Here are just a very few examples. + */ + private static final String[] Anomalies = { + // JDK renders these longer than needed. + "1.1754944E-38", "2.2E-44", + "1.0E16", "2.0E16", "3.0E16", "5.0E16", "3.0E17", + "3.2E18", "3.7E18", "3.7E16", "3.72E17", + + // JDK does not render this as the closest. + "9.9E-44", + }; + + private static void testSomeAnomalies() { + for (String dec : Anomalies) { + toDec(parseFloat(dec)); + } + } + + /* + Values are from + Paxson V, "A Program for Testing IEEE Decimal-Binary Conversion" + tables 16 and 17 + */ + private static final float[] PaxsonSignificands = { + 12_676_506, + 15_445_013, + 13_734_123, + 12_428_269, + 12_676_506, + 15_334_037, + 11_518_287, + 12_584_953, + 15_961_084, + 14_915_817, + 10_845_484, + 16_431_059, + + 16_093_626, + 9_983_778, + 12_745_034, + 12_706_553, + 11_005_028, + 15_059_547, + 16_015_691, + 8_667_859, + 14_855_922, + 14_855_922, + 10_144_164, + 13_248_074, + }; + + private static final int[] PaxsonExponents = { + -102, + -103, + 86, + -138, + -130, + -146, + -41, + -145, + -125, + -146, + -102, + -61, + + 69, + 25, + 104, + 72, + 45, + 71, + -99, + 56, + -82, + -83, + -110, + 95, + }; + + private static void testPaxson() { + for (int i = 0; i < PaxsonSignificands.length; ++i) { + toDec(scalb(PaxsonSignificands[i], PaxsonExponents[i])); + } + } + + /* + Tests all positive integers below 2^23. + These are all exact floats and exercise the fast path. + */ + private static void testInts() { + for (int i = 1; i < 1 << P - 1; ++i) { + toDec(i); + } + } + + /* + Random floats over the whole range. + */ + private static void testRandom(int randomCount, Random r) { + for (int i = 0; i < randomCount; ++i) { + toDec(intBitsToFloat(r.nextInt())); + } + } + + private static void testConstants() { + assertTrue(precision() == P, "P"); + assertTrue(flog10pow2(P) + 2 == H, "H"); + assertTrue(e(MIN_VALUE) == MIN_EXP, "MIN_EXP"); + assertTrue(e(MAX_VALUE) == MAX_EXP, "MAX_EXP"); + } + + private static int precision() { + /* + Given precision P, the floating point value 3 has the bits + 0e...e10...0 + where there are exactly P - 2 trailing zeroes. + */ + return numberOfTrailingZeros(floatToRawIntBits(3)) + 2; + } + + /* + All, really all, 2^32 possible floats. Takes between 90 and 120 minutes. + */ + public static void testAll() { + for (long bits = Integer.MIN_VALUE; bits <= Integer.MAX_VALUE; ++bits) { + toDec(intBitsToFloat((int) bits)); + } + } + + /* + All 2^31 positive floats. + */ + public static void testPositive() { + for (long bits = 0; bits <= Integer.MAX_VALUE; ++bits) { + toDec(intBitsToFloat((int) bits)); + } + } + + public static void test(int randomCount, Random r) { + testConstants(); + testExtremeValues(); + testSomeAnomalies(); + testPowersOf2(); + testPowersOf10(); + testPaxson(); + testInts(); + testRandom(randomCount, r); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/MathUtilsChecker.java b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/MathUtilsChecker.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/MathUtilsChecker.java @@ -0,0 +1,448 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +import java.math.BigInteger; + +import static java.math.BigInteger.*; +import static jdk.internal.math.DoubleToDecimal.*; +import static jdk.internal.math.MathUtils.*; + +public class MathUtilsChecker extends BasicChecker { + + private static final BigInteger THREE = BigInteger.valueOf(3); + + /* + Let + 10^e = beta 2^r + for the unique integer r and real beta meeting + 2^125 <= beta < 2^126 + Further, let g = g1 2^63 + g0. + Checks that: + 2^62 <= g1 < 2^63, + 0 <= g0 < 2^63, + g - 1 <= beta < g, (that is, g = floor(beta) + 1) + The last predicate, after multiplying by 2^r, is equivalent to + (g - 1) 2^r <= 10^e < g 2^r + This is the predicate that will be checked in various forms. + */ + private static void testG(int e, long g1, long g0) { + // 2^62 <= g1 < 2^63, 0 <= g0 < 2^63 + assertTrue(g1 << 1 < 0 && g1 >= 0 && g0 >= 0, "g"); + + BigInteger g = valueOf(g1).shiftLeft(63).or(valueOf(g0)); + // double check that 2^125 <= g < 2^126 + assertTrue(g.signum() > 0 && g.bitLength() == 126, "g"); + + // see javadoc of MathUtils.g1(int) + int r = flog2pow10(e) - 125; + + /* + The predicate + (g - 1) 2^r <= 10^e < g 2^r + is equivalent to + g - 1 <= 10^e 2^(-r) < g + When + e >= 0 & r < 0 + all numerical subexpressions are integer-valued. This is the same as + g - 1 = 10^e 2^(-r) + */ + if (e >= 0 && r < 0) { + assertTrue( + g.subtract(ONE).compareTo(TEN.pow(e).shiftLeft(-r)) == 0, + "g"); + return; + } + + /* + The predicate + (g - 1) 2^r <= 10^e < g 2^r + is equivalent to + g 10^(-e) - 10^(-e) <= 2^(-r) < g 10^(-e) + When + e < 0 & r < 0 + all numerical subexpressions are integer-valued. + */ + if (e < 0 && r < 0) { + BigInteger pow5 = TEN.pow(-e); + BigInteger mhs = ONE.shiftLeft(-r); + BigInteger rhs = g.multiply(pow5); + assertTrue(rhs.subtract(pow5).compareTo(mhs) <= 0 && + mhs.compareTo(rhs) < 0, "g"); + return; + } + + /* + Finally, when + e >= 0 & r >= 0 + the predicate + (g - 1) 2^r <= 10^e < g 2^r + can be used straightforwardly as all numerical subexpressions are + already integer-valued. + */ + if (e >= 0) { + BigInteger mhs = TEN.pow(e); + assertTrue(g.subtract(ONE).shiftLeft(r).compareTo(mhs) <= 0 && + mhs.compareTo(g.shiftLeft(r)) < 0, "g"); + return; + } + + /* + For combinatorial reasons, the only remaining case is + e < 0 & r >= 0 + which, however, cannot arise. Indeed, the predicate + (g - 1) 2^r <= 10^e < g 2^r + implies + (g - 1) 10 <= (g - 1) 2^r 10^(-e) <= 1 + which cannot hold. + */ + assertTrue(false, "g"); + } + + /* + Verifies the soundness of the values returned by g1() and g0(). + */ + private static void testG() { + for (int e = -MAX_K; e <= -MIN_K; ++e) { + testG(e, g1(e), g0(e)); + } + } + + /* + Let + k = floor(log10(3/4 2^e)) + The method verifies that + k = flog10threeQuartersPow2(e), |e| <= 2_000 + This range amply covers all binary exponents of doubles and floats. + + The first equation above is equivalent to + 10^k <= 3 2^(e-2) < 10^(k+1) + Equality never holds. Henceforth, the predicate to check is + 10^k < 3 2^(e-2) < 10^(k+1) + This will be transformed in various ways for checking purposes. + + For integer n > 0, let further + b = len2(n) + denote its length in bits. This means exactly the same as + 2^(b-1) <= n < 2^b + */ + private static void testFlog10threeQuartersPow2() { + /* + First check the case e = 1 + */ + assertTrue(flog10threeQuartersPow2(1) == 0, + "flog10threeQuartersPow2"); + + /* + Now check the range -2_000 <= e <= 0. + By rewriting, the predicate to check is equivalent to + 3 10^(-k-1) < 2^(2-e) < 3 10^(-k) + As e <= 0, it follows that 2^(2-e) >= 4 and the right inequality + implies k < 0, so the powers of 10 are integers. + + The left inequality is equivalent to + len2(3 10^(-k-1)) <= 2 - e + and the right inequality to + 2 - e < len2(3 10^(-k)) + The original predicate is therefore equivalent to + len2(3 10^(-k-1)) <= 2 - e < len2(3 10^(-k)) + + Starting with e = 0 and decrementing until the lower bound, the code + keeps track of the two powers of 10 to avoid recomputing them. + This is easy because at each iteration k changes at most by 1. A simple + multiplication by 10 computes the next power of 10 when needed. + */ + int e = 0; + int k0 = flog10threeQuartersPow2(e); + assertTrue(k0 < 0, "flog10threeQuartersPow2"); + BigInteger l = THREE.multiply(TEN.pow(-k0 - 1)); + BigInteger u = l.multiply(TEN); + for (;;) { + assertTrue(l.bitLength() <= 2 - e && 2 - e < u.bitLength(), + "flog10threeQuartersPow2"); + if (e == -2_000) { + break; + } + --e; + int kp = flog10threeQuartersPow2(e); + assertTrue(kp <= k0, "flog10threeQuartersPow2"); + if (kp < k0) { + // k changes at most by 1 at each iteration, hence: + assertTrue(k0 - kp == 1, "flog10threeQuartersPow2"); + k0 = kp; + l = u; + u = u.multiply(TEN); + } + } + + /* + Finally, check the range 2 <= e <= 2_000. + In predicate + 10^k < 3 2^(e-2) < 10^(k+1) + the right inequality shows that k >= 0 as soon as e >= 2. + It is equivalent to + 10^k / 3 < 2^(e-2) < 10^(k+1) / 3 + Both the powers of 10 and the powers of 2 are integer-valued. + The left inequality is therefore equivalent to + floor(10^k / 3) < 2^(e-2) + and thus to + len2(floor(10^k / 3)) <= e - 2 + while the right inequality is equivalent to + 2^(e-2) <= floor(10^(k+1) / 3) + and hence to + e - 2 < len2(floor(10^(k+1) / 3)) + These are summarized as + len2(floor(10^k / 3)) <= e - 2 < len2(floor(10^(k+1) / 3)) + */ + e = 2; + k0 = flog10threeQuartersPow2(e); + assertTrue(k0 >= 0, "flog10threeQuartersPow2"); + BigInteger l10 = TEN.pow(k0); + BigInteger u10 = l10.multiply(TEN); + l = l10.divide(THREE); + u = u10.divide(THREE); + for (;;) { + assertTrue(l.bitLength() <= e - 2 && e - 2 < u.bitLength(), + "flog10threeQuartersPow2"); + if (e == 2_000) { + break; + } + ++e; + int kp = flog10threeQuartersPow2(e); + assertTrue(kp >= k0, "flog10threeQuartersPow2"); + if (kp > k0) { + // k changes at most by 1 at each iteration, hence: + assertTrue(kp - k0 == 1, "flog10threeQuartersPow2"); + k0 = kp; + u10 = u10.multiply(TEN); + l = u; + u = u10.divide(THREE); + } + } + } + + /* + Let + k = floor(log10(2^e)) + The method verifies that + k = flog10pow2(e), |e| <= 2_000 + This range amply covers all binary exponents of doubles and floats. + + The first equation above is equivalent to + 10^k <= 2^e < 10^(k+1) + Equality holds iff e = 0, implying k = 0. + Henceforth, the predicates to check are equivalent to + k = 0, if e = 0 + 10^k < 2^e < 10^(k+1), otherwise + The latter will be transformed in various ways for checking purposes. + + For integer n > 0, let further + b = len2(n) + denote its length in bits. This means exactly the same as + 2^(b-1) <= n < 2^b + */ + private static void testFlog10pow2() { + /* + First check the case e = 0 + */ + assertTrue(flog10pow2(0) == 0, "flog10pow2"); + + /* + Now check the range -2_000 <= e < 0. + By inverting all quantities, the predicate to check is equivalent to + 10^(-k-1) < 2^(-e) < 10^(-k) + As e < 0, it follows that 2^(-e) >= 2 and the right inequality + implies k < 0. + The left inequality means exactly the same as + len2(10^(-k-1)) <= -e + Similarly, the right inequality is equivalent to + -e < len2(10^(-k)) + The original predicate is therefore equivalent to + len2(10^(-k-1)) <= -e < len2(10^(-k)) + The powers of 10 are integer-valued because k < 0. + + Starting with e = -1 and decrementing towards the lower bound, the code + keeps track of the two powers of 10 so as to avoid recomputing them. + This is easy because at each iteration k changes at most by 1. A simple + multiplication by 10 computes the next power of 10 when needed. + */ + int e = -1; + int k = flog10pow2(e); + assertTrue(k < 0, "flog10pow2"); + BigInteger l = TEN.pow(-k - 1); + BigInteger u = l.multiply(TEN); + for (;;) { + assertTrue(l.bitLength() <= -e && -e < u.bitLength(), + "flog10pow2"); + if (e == -2_000) { + break; + } + --e; + int kp = flog10pow2(e); + assertTrue(kp <= k, "flog10pow2"); + if (kp < k) { + // k changes at most by 1 at each iteration, hence: + assertTrue(k - kp == 1, "flog10pow2"); + k = kp; + l = u; + u = u.multiply(TEN); + } + } + + /* + Finally, in a similar vein, check the range 0 <= e <= 2_000. + In predicate + 10^k < 2^e < 10^(k+1) + the right inequality shows that k >= 0. + The left inequality means the same as + len2(10^k) <= e + and the right inequality holds iff + e < len2(10^(k+1)) + The original predicate is thus equivalent to + len2(10^k) <= e < len2(10^(k+1)) + As k >= 0, the powers of 10 are integer-valued. + */ + e = 1; + k = flog10pow2(e); + assertTrue(k >= 0, "flog10pow2"); + l = TEN.pow(k); + u = l.multiply(TEN); + for (;;) { + assertTrue(l.bitLength() <= e && e < u.bitLength(), + "flog10pow2"); + if (e == 2_000) { + break; + } + ++e; + int kp = flog10pow2(e); + assertTrue(kp >= k, "flog10pow2"); + if (kp > k) { + // k changes at most by 1 at each iteration, hence: + assertTrue(kp - k == 1, "flog10pow2"); + k = kp; + l = u; + u = u.multiply(TEN); + } + } + } + + /* + Let + k = floor(log2(10^e)) + The method verifies that + k = flog2pow10(e), |e| <= 500 + This range amply covers all decimal exponents of doubles and floats. + + The first equation above is equivalent to + 2^k <= 10^e < 2^(k+1) + Equality holds iff e = 0, implying k = 0. + Henceforth, the equivalent predicates to check are + k = 0, if e = 0 + 2^k < 10^e < 2^(k+1), otherwise + The latter will be transformed in various ways for checking purposes. + + For integer n > 0, let further + b = len2(n) + denote its length in bits. This means exactly the same as + 2^(b-1) <= n < 2^b + */ + private static void testFlog2pow10() { + /* + First check the case e = 0 + */ + assertTrue(flog2pow10(0) == 0, "flog2pow10"); + + /* + Now check the range -500 <= e < 0. + By inverting all quantities, the predicate to check is equivalent to + 2^(-k-1) < 10^(-e) < 2^(-k) + As e < 0, this leads to 10^(-e) >= 10 and the right inequality implies + k <= -4. + The above means the same as + len2(10^(-e)) = -k + The powers of 10 are integer values since e < 0. + */ + int e = -1; + int k0 = flog2pow10(e); + assertTrue(k0 <= -4, "flog2pow10"); + BigInteger l = TEN; + for (;;) { + assertTrue(l.bitLength() == -k0, "flog2pow10"); + if (e == -500) { + break; + } + --e; + k0 = flog2pow10(e); + l = l.multiply(TEN); + } + + /* + Finally check the range 0 < e <= 500. + From the predicate + 2^k < 10^e < 2^(k+1) + as e > 0, it follows that 10^e >= 10 and the right inequality implies + k >= 3. + The above means the same as + len2(10^e) = k + 1 + The powers of 10 are all integer valued, as e > 0. + */ + e = 1; + k0 = flog2pow10(e); + assertTrue(k0 >= 3, "flog2pow10"); + l = TEN; + for (;;) { + assertTrue(l.bitLength() == k0 + 1, "flog2pow10"); + if (e == 500) { + break; + } + ++e; + k0 = flog2pow10(e); + l = l.multiply(TEN); + } + } + + private static void testConstants() { + int qMin = (-1 << Double.SIZE - P - 1) - P + 3; + assertTrue(flog10pow2(qMin) == MIN_K, "MIN_K"); + int qMax = (1 << Double.SIZE - P - 1) - P; + assertTrue(flog10pow2(qMax) == MAX_K, "MAX_K"); + } + + private static void testPow10() { + int e = 0; + long pow = 1; + for (; e <= H; e += 1, pow *= 10) { + assertTrue(pow == pow10(e), "pow10"); + } + } + + public static void test() { + testFlog10pow2(); + testFlog10threeQuartersPow2(); + testFlog2pow10(); + testPow10(); + testConstants(); + testG(); + } + +} diff --git a/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/ToDecimalChecker.java b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/ToDecimalChecker.java new file mode 100644 --- /dev/null +++ b/test/jdk/jdk/internal/math/ToDecimal/java.base/jdk/internal/math/ToDecimalChecker.java @@ -0,0 +1,399 @@ +/* + * Copyright 2018-2019 Raffaello Giulietti + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jdk.internal.math; + +import java.io.IOException; +import java.io.StringReader; +import java.math.BigDecimal; +import java.math.BigInteger; + +/* +A checker for the Javadoc specification. +It just relies on straightforward use of (expensive) BigDecimal arithmetic, +not optimized at all. + */ +abstract class ToDecimalChecker extends BasicChecker { + + // The string to check + private final String s; + + // The decimal parsed from s is c 10^q + private long c; + private int q; + + // The number of digits parsed from s: 10^(len10-1) <= c < 10^len10 + private int len10; + + ToDecimalChecker(String s) { + this.s = s; + } + + /* + Returns e be such that 10^(e-1) <= c 2^q < 10^e. + */ + static int e(double v) { + // log10(v) + 1 is a first good approximation of e + int e = (int) Math.floor(Math.log10(v)) + 1; + + // Full precision search for e such that 10^(e-1) <= c 2^q < 10^e. + BigDecimal bv = new BigDecimal(v); + BigDecimal low = new BigDecimal(BigInteger.ONE, -(e - 1)); + while (low.compareTo(bv) > 0) { + e -= 1; + low = new BigDecimal(BigInteger.ONE, -(e - 1)); + } + BigDecimal high = new BigDecimal(BigInteger.ONE, -e); + while (bv.compareTo(high) >= 0) { + e += 1; + high = new BigDecimal(BigInteger.ONE, -e); + } + return e; + } + + void assertTrue() { + if (isOK()) { + return; + } + String msg = "toString applied to the bits " + + hexBits() + + " returns " + + "\"" + s + "\"" + + ", which is not correct according to the specification."; + if (FAILURE_THROWS_EXCEPTION) { + throw new RuntimeException(msg); + } + System.err.println(msg); + } + + /* + Returns whether s syntactically meets the expected output of + toString. It is restricted to finite positive outputs. + It is an unusually long method but rather straightforward, too. + Many conditionals could be merged, but KISS here. + */ + private boolean parse(String t) { + try { + // first determine interesting boundaries in the string + StringReader r = new StringReader(t); + int ch = r.read(); + + int i = 0; + while (ch == '0') { + ++i; + ch = r.read(); + } + // i is just after zeroes starting the integer + + int p = i; + while ('0' <= ch && ch <= '9') { + c = 10 * c + (ch - '0'); + if (c < 0) { + return false; + } + ++len10; + ++p; + ch = r.read(); + } + // p is just after digits ending the integer + + int fz = p; + if (ch == '.') { + ++fz; + ch = r.read(); + } + // fz is just after a decimal '.' + + int f = fz; + while (ch == '0') { + c = 10 * c + (ch - '0'); + if (c < 0) { + return false; + } + ++len10; + ++f; + ch = r.read(); + } + // f is just after zeroes starting the fraction + + if (c == 0) { + len10 = 0; + } + int x = f; + while ('0' <= ch && ch <= '9') { + c = 10 * c + (ch - '0'); + if (c < 0) { + return false; + } + ++len10; + ++x; + ch = r.read(); + } + // x is just after digits ending the fraction + + int g = x; + if (ch == 'E') { + ++g; + ch = r.read(); + } + // g is just after an exponent indicator 'E' + + int ez = g; + if (ch == '-') { + ++ez; + ch = r.read(); + } + // ez is just after a '-' sign in the exponent + + int e = ez; + while (ch == '0') { + ++e; + ch = r.read(); + } + // e is just after zeroes starting the exponent + + int z = e; + while ('0' <= ch && ch <= '9') { + q = 10 * q + (ch - '0'); + if (q < 0) { + return false; + } + ++z; + ch = r.read(); + } + // z is just after digits ending the exponent + + // No other char after the number + if (z != t.length()) { + return false; + } + + // The integer must be present + if (p == 0) { + return false; + } + + // The decimal '.' must be present + if (fz == p) { + return false; + } + + // The fraction must be present + if (x == fz) { + return false; + } + + // The fraction is not 0 or it consists of exactly one 0 + if (f == x && f - fz > 1) { + return false; + } + + // Plain notation, no exponent + if (x == z) { + // At most one 0 starting the integer + if (i > 1) { + return false; + } + + // If the integer is 0, at most 2 zeroes start the fraction + if (i == 1 && f - fz > 2) { + return false; + } + + // The integer cannot have more than 7 digits + if (p > 7) { + return false; + } + + q = fz - x; + + // OK for plain notation + return true; + } + + // Computerized scientific notation + + // The integer has exactly one nonzero digit + if (i != 0 || p != 1) { + return false; + } + + // + // There must be an exponent indicator + if (x == g) { + return false; + } + + // There must be an exponent + if (ez == z) { + return false; + } + + // The exponent must not start with zeroes + if (ez != e) { + return false; + } + + if (g != ez) { + q = -q; + } + + // The exponent must not lie in [-3, 7) + if (-3 <= q && q < 7) { + return false; + } + + q += fz - x; + + // OK for computerized scientific notation + return true; + } catch (IOException ex) { + // An IOException on a StringReader??? Please... + return false; + } + } + + private boolean isOK() { + if (isNaN()) { + return s.equals("NaN"); + } + String t = s; + if (isNegative()) { + if (s.isEmpty() || s.charAt(0) != '-') { + return false; + } + negate(); + t = s.substring(1); + } + if (isInfinity()) { + return t.equals("Infinity"); + } + if (isZero()) { + return t.equals("0.0"); + } + if (!parse(t)) { + return false; + } + if (len10 < 2) { + c *= 10; + q -= 1; + len10 += 1; + } + if (2 > len10 || len10 > maxLen10()) { + return false; + } + + // The exponent is bounded + if (minExp() > q + len10 || q + len10 > maxExp()) { + return false; + } + + // s must recover v + try { + if (!recovers(t)) { + return false; + } + } catch (NumberFormatException e) { + return false; + } + + // Get rid of trailing zeroes, still ensuring at least 2 digits + while (len10 > 2 && c % 10 == 0) { + c /= 10; + q += 1; + len10 -= 1; + } + + if (len10 > 2) { + // Try with a shorter number less than v... + if (recovers(BigDecimal.valueOf(c / 10, -q - 1))) { + return false; + } + + // ... and with a shorter number greater than v + if (recovers(BigDecimal.valueOf(c / 10 + 1, -q - 1))) { + return false; + } + } + + // Try with the decimal predecessor... + BigDecimal dp = c == 10 ? + BigDecimal.valueOf(99, -q + 1) : + BigDecimal.valueOf(c - 1, -q); + if (recovers(dp)) { + BigDecimal bv = toBigDecimal(); + BigDecimal deltav = bv.subtract(BigDecimal.valueOf(c, -q)); + if (deltav.signum() >= 0) { + return true; + } + BigDecimal delta = dp.subtract(bv); + if (delta.signum() >= 0) { + return false; + } + int cmp = deltav.compareTo(delta); + return cmp > 0 || cmp == 0 && (c & 0x1) == 0; + } + + // ... and with the decimal successor + BigDecimal ds = BigDecimal.valueOf(c + 1, -q); + if (recovers(ds)) { + BigDecimal bv = toBigDecimal(); + BigDecimal deltav = bv.subtract(BigDecimal.valueOf(c, -q)); + if (deltav.signum() <= 0) { + return true; + } + BigDecimal delta = ds.subtract(bv); + if (delta.signum() <= 0) { + return false; + } + int cmp = deltav.compareTo(delta); + return cmp < 0 || cmp == 0 && (c & 0x1) == 0; + } + + return true; + } + + abstract BigDecimal toBigDecimal(); + + abstract boolean recovers(BigDecimal b); + + abstract boolean recovers(String s); + + abstract String hexBits(); + + abstract int minExp(); + + abstract int maxExp(); + + abstract int maxLen10(); + + abstract boolean isZero(); + + abstract boolean isInfinity(); + + abstract void negate(); + + abstract boolean isNegative(); + + abstract boolean isNaN(); + +} -------------- next part -------------- A non-text attachment was scrubbed... Name: JDK-4511638.patch Type: text/x-patch Size: 171897 bytes Desc: not available URL: From brian.burkhalter at oracle.com Thu Apr 18 19:29:46 2019 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Thu, 18 Apr 2019 12:29:46 -0700 Subject: [PATCH] 4511638: Double.toString(double) sometimes produces incorrect results In-Reply-To: References: <4F722010-2DC8-40FB-97BA-5A69500810A7@oracle.com> Message-ID: <5E36735D-1B21-4CBB-B5BC-F2D5E09E6D7D@oracle.com> > On Apr 18, 2019, at 11:44 AM, Raffaello Giulietti wrote: > > here's another revision of the patch. Its purpose is to overcome the test failure observed in [1]. To this end, the patch adds > > FloatToDecimal.appendTo(float, Appendable) and > DoubleToDecimal.appendTo(double, Appendable) > > static methods to help AbstractStringBuilder in using the corrected algorithm implemented in > > FloatToDecimal.toString(float) and > DoubleToDecimal.toString(double), respectively. > > The implementation has been jmh tested to make sure there are no performance regressions. Thanks, Raffaello. > As there are now only less than two months left before Rampdown 1 for OpenJDK 13, I beg anybody interested in reviewing this patch to contact me for any question or clarification. Also, you might want to take a look at the CSR [2]. +1 on both counts. > As usual, Brian will make the patch available as webrev in the coming hours. Please see http://cr.openjdk.java.net/~bpb/4511638/webrev.03/ I wonder whether in the new AbstractStringBuilder.append() changes the constructs: 880 try { 881 FloatToDecimal.appendTo(f, this); 882 } catch (IOException ignored) { 883 assert false; 884 } might be better as: 880 try { 881 FloatToDecimal.appendTo(f, this); 882 } catch (IOException cause) { 883 throw new RuntimeException(cause); 884 } Comments appreciated. Brian From andy.herrick at oracle.com Thu Apr 18 19:49:12 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Thu, 18 Apr 2019 15:49:12 -0400 Subject: RFR: JDK-8222733: Modify jpackage option --add-launcher syntax Message-ID: Please review the jpackage fix for bugs [1] and [2] at [3]. This is a fix for the JDK-8200758-branch branch of the open sandbox repository (jpackage). [1] https://bugs.openjdk.java.net/browse/JDK-8222733 [2] https://bugs.openjdk.java.net/browse/JDK-8222731 [3] http://cr.openjdk.java.net/~herrick/8222733/ /Andy From raffaello.giulietti at gmail.com Thu Apr 18 20:37:10 2019 From: raffaello.giulietti at gmail.com (Raffaello Giulietti) Date: Thu, 18 Apr 2019 22:37:10 +0200 Subject: [PATCH] 4511638: Double.toString(double) sometimes produces incorrect results In-Reply-To: <5E36735D-1B21-4CBB-B5BC-F2D5E09E6D7D@oracle.com> References: <4F722010-2DC8-40FB-97BA-5A69500810A7@oracle.com> <5E36735D-1B21-4CBB-B5BC-F2D5E09E6D7D@oracle.com> Message-ID: Hi, On 18.04.19 21:29, Brian Burkhalter wrote: > >> On Apr 18, 2019, at 11:44 AM, Raffaello Giulietti >> > > wrote: >> >> here's another revision of the patch. Its purpose is to overcome the >> test failure observed in [1]. To this end, the patch adds >> >> FloatToDecimal.appendTo(float, Appendable) and >> DoubleToDecimal.appendTo(double, Appendable) >> >> static methods to help AbstractStringBuilder in using the corrected >> algorithm implemented in >> >> FloatToDecimal.toString(float) and >> DoubleToDecimal.toString(double), respectively. >> >> The implementation has been jmh tested to make sure there are no >> performance regressions. > > Thanks,?Raffaello. > >> As there are now only less than two months left before Rampdown 1 for >> OpenJDK 13, I beg anybody interested in reviewing this patch to >> contact me for any question or clarification. Also, you might want to >> take a look at the CSR [2]. > > +1 on both counts. > >> As usual, Brian will make the patch available as webrev in the coming >> hours. > > Please see > > http://cr.openjdk.java.net/~bpb/4511638/webrev.03/ > > I wonder whether in the new AbstractStringBuilder.append() changes the > constructs: > 880 try { > 881 FloatToDecimal.appendTo(f, this); > 882 } catch (IOException ignored) { > 883 assert false; > 884 } > might be better as: > 880 try { > 881 FloatToDecimal.appendTo(f, this); > 882 } catch (IOException cause) { > 883 throw new RuntimeException(cause); > 884 } > Comments appreciated. > > Brian The reason is that FloatToDecimal.appendTo() takes an Appendable as parameter. Appendable's append() methods throw a checked IOException. This cannot happen with AbstractStringBuilder (the this passed as argument), so the code catches the IOException just to please the compiler. The assert is there just in case, but control shall never pass there. Whatever conventions are in place to emphasize that control flow cannot reach some point, I'll adopt them. Let me know. The same holds for DoubleToDecimal.appendTo(). From alexander.matveev at oracle.com Thu Apr 18 21:17:06 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Thu, 18 Apr 2019 14:17:06 -0700 Subject: RFR: JDK-8222733: Modify jpackage option --add-launcher syntax In-Reply-To: References: Message-ID: <1d2f6be3-6093-d639-c021-97d1bbb1d55c@oracle.com> Hi Andy, Looks good. Thanks, Alexander On 4/18/2019 12:49 PM, Andy Herrick wrote: > Please review the jpackage fix for bugs [1] and [2] at [3]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > [1] https://bugs.openjdk.java.net/browse/JDK-8222733 > > [2] https://bugs.openjdk.java.net/browse/JDK-8222731 > > [3] http://cr.openjdk.java.net/~herrick/8222733/ > > /Andy > From philip.race at oracle.com Thu Apr 18 21:21:12 2019 From: philip.race at oracle.com (Phil Race) Date: Thu, 18 Apr 2019 14:21:12 -0700 Subject: RFR: JDK-8222733: Modify jpackage option --add-launcher syntax In-Reply-To: <1d2f6be3-6093-d639-c021-97d1bbb1d55c@oracle.com> References: <1d2f6be3-6093-d639-c021-97d1bbb1d55c@oracle.com> Message-ID: <5c74c670-562a-8e7d-fe23-257be72e037f@oracle.com> 173 \ This Option can be used Multiple times.\n\ Why the capitalisation ? -phil. On 4/18/19 2:17 PM, Alexander Matveev wrote: > Hi Andy, > > Looks good. > > Thanks, > Alexander > > On 4/18/2019 12:49 PM, Andy Herrick wrote: >> Please review the jpackage fix for bugs [1] and [2] at [3]. >> >> This is a fix for the JDK-8200758-branch branch of the open sandbox >> repository (jpackage). >> >> [1] https://bugs.openjdk.java.net/browse/JDK-8222733 >> >> [2] https://bugs.openjdk.java.net/browse/JDK-8222731 >> >> [3] http://cr.openjdk.java.net/~herrick/8222733/ >> >> /Andy >> > From andy.herrick at oracle.com Thu Apr 18 21:23:44 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Thu, 18 Apr 2019 17:23:44 -0400 Subject: RFR: JDK-8222733: Modify jpackage option --add-launcher syntax In-Reply-To: <5c74c670-562a-8e7d-fe23-257be72e037f@oracle.com> References: <1d2f6be3-6093-d639-c021-97d1bbb1d55c@oracle.com> <5c74c670-562a-8e7d-fe23-257be72e037f@oracle.com> Message-ID: On 4/18/2019 5:21 PM, Phil Race wrote: > ?173 \????????? This Option can be used Multiple times.\n\ > > Why the capitalisation ? no reason - will revise /Andy > > -phil. > > On 4/18/19 2:17 PM, Alexander Matveev wrote: >> Hi Andy, >> >> Looks good. >> >> Thanks, >> Alexander >> >> On 4/18/2019 12:49 PM, Andy Herrick wrote: >>> Please review the jpackage fix for bugs [1] and [2] at [3]. >>> >>> This is a fix for the JDK-8200758-branch branch of the open sandbox >>> repository (jpackage). >>> >>> [1] https://bugs.openjdk.java.net/browse/JDK-8222733 >>> >>> [2] https://bugs.openjdk.java.net/browse/JDK-8222731 >>> >>> [3] http://cr.openjdk.java.net/~herrick/8222733/ >>> >>> /Andy >>> >> > From kevin.rushforth at oracle.com Thu Apr 18 21:33:06 2019 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Thu, 18 Apr 2019 14:33:06 -0700 Subject: RFR: JDK-8222733: Modify jpackage option --add-launcher syntax In-Reply-To: References: <1d2f6be3-6093-d639-c021-97d1bbb1d55c@oracle.com> <5c74c670-562a-8e7d-fe23-257be72e037f@oracle.com> Message-ID: <817470fe-af9e-8c19-984b-e89a30dfdd44@oracle.com> On 4/18/2019 2:23 PM, Andy Herrick wrote: > > On 4/18/2019 5:21 PM, Phil Race wrote: >> ?173 \????????? This Option can be used Multiple times.\n\ >> >> Why the capitalisation ? > no reason - will revise One other issue with the help message: +ERR_NoAddLauncherName=Error: --add-launcher option require a name and a file path (--add-launcher =). +ERR_NoUniqueName=Error: --add-launcher = require a unique name. That should be "requires". The code changes look good. I tested it, and see no issues. -- Kevin From Sergey.Bylokhov at oracle.com Thu Apr 18 22:41:15 2019 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Thu, 18 Apr 2019 15:41:15 -0700 Subject: [13] Review Request: 8220134 Cleanup the code in java.base which take care about multiple AppContext Message-ID: <0abe3d3c-637b-d332-4df0-765237e120f6@oracle.com> Hello. Please review the fix for JDK 13. Bug: https://bugs.openjdk.java.net/browse/JDK-8220134 Fix: http://cr.openjdk.java.net/~serb/8220134/webrev.00 The AppContext class was used as a kind of "sandbox" in case of applets/webstart. Both applets and webstart were removed from the jdk11, since then we always use only one "MainAppcontext", which means that AppContext itself became useless. Supporting AppContext overly complicates the code, and provides no benefits. It would be great if we can remove this code. In this change I have removed: - The "jdk.internal.access.JavaAWTAccess" class which implemented a bridge between java.desktop and java.base - The code which setup JavaAWTAccess in sun.awt.AppContext class - The mapping between LoggerContext and AppContext in the java.util.logging.LogManager class Some tests were updated/removed as well. ..... mach5 tier1 and client-tests are green. -- Best regards, Sergey. From Sergey.Bylokhov at oracle.com Thu Apr 18 23:08:09 2019 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Thu, 18 Apr 2019 16:08:09 -0700 Subject: [13] Review Request: 8220134 Cleanup the code in java.base which take care about multiple AppContext In-Reply-To: <0abe3d3c-637b-d332-4df0-765237e120f6@oracle.com> References: <0abe3d3c-637b-d332-4df0-765237e120f6@oracle.com> Message-ID: I have found one of the removed test in the ProblemList, webrev is updated in place. On 18/04/2019 15:41, Sergey Bylokhov wrote: > Hello. > Please review the fix for JDK 13. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8220134 > Fix: http://cr.openjdk.java.net/~serb/8220134/webrev.00 > > The AppContext class was used as a kind of "sandbox" in case of applets/webstart. Both applets and webstart were removed from the jdk11, since then we always use only one "MainAppcontext", which means that AppContext itself became useless. > > Supporting AppContext overly complicates the code, and provides no benefits. It would be great if we can remove this code. > > In this change I have removed: > ?- The "jdk.internal.access.JavaAWTAccess" class which implemented a bridge between java.desktop and java.base > ?- The code which setup JavaAWTAccess in sun.awt.AppContext class > ?- The mapping between LoggerContext and AppContext in the java.util.logging.LogManager class > > Some tests were updated/removed as well. > > ..... > mach5 tier1 and client-tests are green. > -- Best regards, Sergey. From alexander.matveev at oracle.com Fri Apr 19 00:05:01 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Thu, 18 Apr 2019 17:05:01 -0700 Subject: RFR: JDK-8222676: create-installer with --app-image fails on mac Message-ID: <8cacb057-6326-ce30-17f9-c1aeef0d5881@oracle.com> Please review the jpackage fix for bug [1] at [2]. This is a fix for the JDK-8200758-branch branch of the open sandbox repository (jpackage). - Fixed issue when app image is located at root of working folder, since fix for JDK-8219144 assumed app image located under some folder other then working directory. - Another issue found while working on this bug: pkgbuild will package any components in root folder or any sub-folder, so app image should be only one component in root folder without any sub-folder. This issue is fixed by making copy of app image if it is located in folder with other files. [1] https://bugs.openjdk.java.net/browse/JDK-8222676 [2] http://cr.openjdk.java.net/~almatvee/8222676/webrev.00/ Thanks, Alexander From andy.herrick at oracle.com Fri Apr 19 00:26:02 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Thu, 18 Apr 2019 20:26:02 -0400 Subject: RFR: JDK-8222676: create-installer with --app-image fails on mac In-Reply-To: <8cacb057-6326-ce30-17f9-c1aeef0d5881@oracle.com> References: <8cacb057-6326-ce30-17f9-c1aeef0d5881@oracle.com> Message-ID: <2c79fd71-3e27-ce49-a791-749b303b15a7@oracle.com> looks good to me - will test it tomorrow with my test cases. /Andy On 4/18/2019 8:05 PM, Alexander Matveev wrote: > Please review the jpackage fix for bug [1] at [2]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > - Fixed issue when app image is located at root of working folder, > since fix for JDK-8219144 assumed app image located under some folder > other then working directory. > - Another issue found while working on this bug: pkgbuild will package > any components in root folder or any sub-folder, so app image should > be only one component in root folder without any sub-folder. This > issue is fixed by making copy of app image if it is located in folder > with other files. > > [1] https://bugs.openjdk.java.net/browse/JDK-8222676 > > [2] http://cr.openjdk.java.net/~almatvee/8222676/webrev.00/ > > Thanks, > Alexander From Alan.Bateman at oracle.com Fri Apr 19 15:46:42 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 19 Apr 2019 16:46:42 +0100 Subject: [13] Review Request: 8220134 Cleanup the code in java.base which take care about multiple AppContext In-Reply-To: <0abe3d3c-637b-d332-4df0-765237e120f6@oracle.com> References: <0abe3d3c-637b-d332-4df0-765237e120f6@oracle.com> Message-ID: <6eba7bc4-5cf1-4a8c-ebc8-a74db359fc33@oracle.com> On 18/04/2019 23:41, Sergey Bylokhov wrote: > Hello. > Please review the fix for JDK 13. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8220134 > Fix: http://cr.openjdk.java.net/~serb/8220134/webrev.00 > > The AppContext class was used as a kind of "sandbox" in case of > applets/webstart. Both applets and webstart were removed from the > jdk11, since then we always use only one "MainAppcontext", which means > that AppContext itself became useless. Good riddance :-)?? The changes look fine. -Alan From daniel.fuchs at oracle.com Fri Apr 19 16:07:00 2019 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 19 Apr 2019 17:07:00 +0100 Subject: [13] Review Request: 8220134 Cleanup the code in java.base which take care about multiple AppContext In-Reply-To: <6eba7bc4-5cf1-4a8c-ebc8-a74db359fc33@oracle.com> References: <0abe3d3c-637b-d332-4df0-765237e120f6@oracle.com> <6eba7bc4-5cf1-4a8c-ebc8-a74db359fc33@oracle.com> Message-ID: On 19/04/2019 16:46, Alan Bateman wrote: > On 18/04/2019 23:41, Sergey Bylokhov wrote: >> Hello. >> Please review the fix for JDK 13. >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8220134 >> Fix: http://cr.openjdk.java.net/~serb/8220134/webrev.00 >> >> The AppContext class was used as a kind of "sandbox" in case of >> applets/webstart. Both applets and webstart were removed from the >> jdk11, since then we always use only one "MainAppcontext", which means >> that AppContext itself became useless. > Good riddance :-)?? The changes look fine. Seconded :-) I have double checked that the removed tests do not make sense any longer with this "feature" gone. Reviewed. best regards, -- daniel From andy.herrick at oracle.com Fri Apr 19 16:32:57 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Fri, 19 Apr 2019 12:32:57 -0400 Subject: RFR: JDK-8219683,,Modify App Image layout on Mac Message-ID: <73421755-89e3-2a1a-16c2-7a7e271653e3@oracle.com> Please review the jpackage fix for bug [1] at [2]. This is a fix for the JDK-8200758-branch branch of the open sandbox repository (jpackage). [1] https://bugs.openjdk.java.net/browse/JDK-8219683 [2] http://cr.openjdk.java.net/~herrick/8219683/ /Andy From jason_mehrens at hotmail.com Fri Apr 19 17:21:24 2019 From: jason_mehrens at hotmail.com (Jason Mehrens) Date: Fri, 19 Apr 2019 17:21:24 +0000 Subject: [PATCH] 4511638: Double.toString(double) sometimes produces incorrect results In-Reply-To: References: <4F722010-2DC8-40FB-97BA-5A69500810A7@oracle.com> <5E36735D-1B21-4CBB-B5BC-F2D5E09E6D7D@oracle.com>, Message-ID: Maybe rename the catch variable from 'cause' or 'ignored' to 'unreachable' and then wrap java.io.IOException in java.io.IOError? ________________________________________ From: core-libs-dev on behalf of Raffaello Giulietti Sent: Thursday, April 18, 2019 3:37 PM To: Brian Burkhalter; core-libs-dev Subject: Re: [PATCH] 4511638: Double.toString(double) sometimes produces incorrect results Hi, On 18.04.19 21:29, Brian Burkhalter wrote: > >> On Apr 18, 2019, at 11:44 AM, Raffaello Giulietti >> > > wrote: >> >> here's another revision of the patch. Its purpose is to overcome the >> test failure observed in [1]. To this end, the patch adds >> >> FloatToDecimal.appendTo(float, Appendable) and >> DoubleToDecimal.appendTo(double, Appendable) >> >> static methods to help AbstractStringBuilder in using the corrected >> algorithm implemented in >> >> FloatToDecimal.toString(float) and >> DoubleToDecimal.toString(double), respectively. >> >> The implementation has been jmh tested to make sure there are no >> performance regressions. > > Thanks, Raffaello. > >> As there are now only less than two months left before Rampdown 1 for >> OpenJDK 13, I beg anybody interested in reviewing this patch to >> contact me for any question or clarification. Also, you might want to >> take a look at the CSR [2]. > > +1 on both counts. > >> As usual, Brian will make the patch available as webrev in the coming >> hours. > > Please see > > http://cr.openjdk.java.net/~bpb/4511638/webrev.03/ > > I wonder whether in the new AbstractStringBuilder.append() changes the > constructs: > 880 try { > 881 FloatToDecimal.appendTo(f, this); > 882 } catch (IOException ignored) { > 883 assert false; > 884 } > might be better as: > 880 try { > 881 FloatToDecimal.appendTo(f, this); > 882 } catch (IOException cause) { > 883 throw new RuntimeException(cause); > 884 } > Comments appreciated. > > Brian The reason is that FloatToDecimal.appendTo() takes an Appendable as parameter. Appendable's append() methods throw a checked IOException. This cannot happen with AbstractStringBuilder (the this passed as argument), so the code catches the IOException just to please the compiler. The assert is there just in case, but control shall never pass there. Whatever conventions are in place to emphasize that control flow cannot reach some point, I'll adopt them. Let me know. The same holds for DoubleToDecimal.appendTo(). From kevin.rushforth at oracle.com Fri Apr 19 17:46:54 2019 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Fri, 19 Apr 2019 10:46:54 -0700 Subject: RFR: JDK-8219683,,Modify App Image layout on Mac In-Reply-To: <73421755-89e3-2a1a-16c2-7a7e271653e3@oracle.com> References: <73421755-89e3-2a1a-16c2-7a7e271653e3@oracle.com> Message-ID: <1feb5783-4f63-9fd3-0ad0-2b1d37ea8ea0@oracle.com> Looks good. -- Kevin On 4/19/2019 9:32 AM, Andy Herrick wrote: > Please review the jpackage fix for bug [1] at [2]. > > This is a fix for the JDK-8200758-branch branch of the open sandbox > repository (jpackage). > > [1] https://bugs.openjdk.java.net/browse/JDK-8219683 > > [2] http://cr.openjdk.java.net/~herrick/8219683/ > > /Andy > From philip.race at oracle.com Fri Apr 19 18:20:32 2019 From: philip.race at oracle.com (Phil Race) Date: Fri, 19 Apr 2019 11:20:32 -0700 Subject: RFR: JDK-8219683,,Modify App Image layout on Mac In-Reply-To: <1feb5783-4f63-9fd3-0ad0-2b1d37ea8ea0@oracle.com> References: <73421755-89e3-2a1a-16c2-7a7e271653e3@oracle.com> <1feb5783-4f63-9fd3-0ad0-2b1d37ea8ea0@oracle.com> Message-ID: <3ddc3eb5-4889-6f20-0ed1-2910980d138b@oracle.com> +1 Only thing I have to say is that in the test JPackagePath I liked the esier to read formatting you didhere at lines 184-185 and you could have done something similar at lines 159-161 + + File.separator + "Contents" + + File.separator + "runtime" + + File.separator + "Contents" + + File.separator + "Home" + File.separator + "bin"; -phil. On 4/19/19 10:46 AM, Kevin Rushforth wrote: > Looks good. > > -- Kevin > > > On 4/19/2019 9:32 AM, Andy Herrick wrote: >> Please review the jpackage fix for bug [1] at [2]. >> >> This is a fix for the JDK-8200758-branch branch of the open sandbox >> repository (jpackage). >> >> [1] https://bugs.openjdk.java.net/browse/JDK-8219683 >> >> [2] http://cr.openjdk.java.net/~herrick/8219683/ >> >> /Andy >> > From raffaello.giulietti at gmail.com Fri Apr 19 18:29:12 2019 From: raffaello.giulietti at gmail.com (Raffaello Giulietti) Date: Fri, 19 Apr 2019 20:29:12 +0200 Subject: [PATCH] 4511638: Double.toString(double) sometimes produces incorrect results In-Reply-To: References: <4F722010-2DC8-40FB-97BA-5A69500810A7@oracle.com> <5E36735D-1B21-4CBB-B5BC-F2D5E09E6D7D@oracle.com> Message-ID: Hi, the semantics of java.io.IOError is: "Thrown when a serious I/O error has occurred" which I guess is not appropriate here. I think the best compromise is 880 try { 881 FloatToDecimal.appendTo(f, this); 882 } catch (IOException cause) { 883 throw new AssertionError("Code shall be unreachable", cause); 884 } which is more explicit and doesn't rely on assertions being enabled. Greetings Raffaello On 2019-04-19 19:21, Jason Mehrens wrote: > Maybe rename the catch variable from 'cause' or 'ignored' to 'unreachable' and then wrap java.io.IOException in java.io.IOError? > > ________________________________________ > From: core-libs-dev on behalf of Raffaello Giulietti > Sent: Thursday, April 18, 2019 3:37 PM > To: Brian Burkhalter; core-libs-dev > Subject: Re: [PATCH] 4511638: Double.toString(double) sometimes produces incorrect results > > Hi, > > On 18.04.19 21:29, Brian Burkhalter wrote: >> >>> On Apr 18, 2019, at 11:44 AM, Raffaello Giulietti >>> >> > wrote: >>> >>> here's another revision of the patch. Its purpose is to overcome the >>> test failure observed in [1]. To this end, the patch adds >>> >>> FloatToDecimal.appendTo(float, Appendable) and >>> DoubleToDecimal.appendTo(double, Appendable) >>> >>> static methods to help AbstractStringBuilder in using the corrected >>> algorithm implemented in >>> >>> FloatToDecimal.toString(float) and >>> DoubleToDecimal.toString(double), respectively. >>> >>> The implementation has been jmh tested to make sure there are no >>> performance regressions. >> >> Thanks, Raffaello. >> >>> As there are now only less than two months left before Rampdown 1 for >>> OpenJDK 13, I beg anybody interested in reviewing this patch to >>> contact me for any question or clarification. Also, you might want to >>> take a look at the CSR [2]. >> >> +1 on both counts. >> >>> As usual, Brian will make the patch available as webrev in the coming >>> hours. >> >> Please see >> >> http://cr.openjdk.java.net/~bpb/4511638/webrev.03/ >> >> I wonder whether in the new AbstractStringBuilder.append() changes the >> constructs: >> 880 try { >> 881 FloatToDecimal.appendTo(f, this); >> 882 } catch (IOException ignored) { >> 883 assert false; >> 884 } >> might be better as: >> 880 try { >> 881 FloatToDecimal.appendTo(f, this); >> 882 } catch (IOException cause) { >> 883 throw new RuntimeException(cause); >> 884 } >> Comments appreciated. >> >> Brian > > > The reason is that FloatToDecimal.appendTo() takes an Appendable as > parameter. Appendable's append() methods throw a checked IOException. > This cannot happen with AbstractStringBuilder (the this passed as > argument), so the code catches the IOException just to please the > compiler. The assert is there just in case, but control shall never pass > there. Whatever conventions are in place to emphasize that control flow > cannot reach some point, I'll adopt them. Let me know. > > The same holds for DoubleToDecimal.appendTo(). > > From huizhe.wang at oracle.com Fri Apr 19 20:19:51 2019 From: huizhe.wang at oracle.com (Joe Wang) Date: Fri, 19 Apr 2019 13:19:51 -0700 Subject: RFR(JDK 13/java.xml) 8222743: Xerces 2.12.0: DOM Implementation Message-ID: <5CBA2D67.9000805@oracle.com> Please review an update to xerces/dom. Details are as described in the JBS. XML related tests and JCK passed. JBS: https://bugs.openjdk.java.net/browse/JDK-8222743 webrev: http://cr.openjdk.java.net/~joehw/jdk13/8222743/webrev/ Thanks, Joe From martinrb at google.com Sun Apr 21 23:38:03 2019 From: martinrb at google.com (Martin Buchholz) Date: Sun, 21 Apr 2019 16:38:03 -0700 Subject: RFR: 8215017: Improve String::equals warmup characteristics In-Reply-To: <68B48A75-AAAD-4022-9724-555B3464A27B@oracle.com> References: <68B48A75-AAAD-4022-9724-555B3464A27B@oracle.com> Message-ID: Array copy and array compare seem like very similar optimization problems and could even share some infrastructure. On Thu, Apr 11, 2019 at 9:23 AM John Rose wrote: > On Dec 7, 2018, at 4:11 PM, Claes Redestad > wrote: > > > > - Jim's proposal to use Arrays.equals is _interesting_: it improves > > peak performance on some inputs but regress it on others. I'll defer > > that to a future RFE as it needs a more thorough examination. > > > > - what we can do is simplify to only use StringLatin1.equals. If I'm not > > completely mistaken these are all semantically neutral (and > > StringUTF16.equals effectively redundant). If I'm completely wrong here > > I'll welcome the learning opportunity. :-) > > If they are semantically neutral then they belong in > the same place as the neutral intrinsics, which is > jdk.internal.util.ArraysSupport. This in turn calls > the question of how the operation differs from > the existing mismatch intrinsic. > > I'll go out on a limb here and say that the standard > ArraysSupport.mismatch intrinsic can probably be > tuned to cover string compares without hurting its > other customers. Often such intrinsics are only > engineered for throughput on long inputs. > Later on we may find they can be additionally > tuned for other workloads, by adjusting the setup > logic, or (alternatively) they can be factored into > multiple entry points for specific use cases, with > complete sharing of assembly-level code except > for differing setup logic for the different use cases. > This sort of thing is the case with our arraycopy > intrinsics (used by the JIT) and may well also be > the case for array matching intrinsics. > > I agree the above questions can be answered in > a separate investigation. > > ? John From ivan.gerasimov at oracle.com Mon Apr 22 02:50:19 2019 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Sun, 21 Apr 2019 19:50:19 -0700 Subject: RFR 8214245 : Case insensitive matching doesn't work correctly for some character classes Message-ID: <59ccaf4d-02e5-ed11-3800-f75412d16342@oracle.com> Hello! It turns out, that the case-insensitive j.u.regex.Pattern still pays attention to the characters case when certain char classes are used. For example \p{IsLowerCase}, \p{IsUpperCase} and \p{IsTitleCase} continue to recognize only lower, upper and title case characters, even in case-insensitive context. For example, for POSIX char classes this behavior contradicts this paragraph: """ 9.2 Regular Expression General Requirements ... When a standard utility or function that uses regular expressions specifies that pattern matching shall be performed without regard to the case (uppercase or lowercase) of either data or patterns, then when each character in the string is matched against the pattern, not only the character, but also its case counterpart (if any), shall be matched. This definition of case-insensitive processing is intended to allow matching of multi-character collating elements as well as characters, as each character in the string is matched using both its cases. ... """ I also checked how Perl is dealing with in such situation, and yes, it ignores the case with various \p{} classes when they are used in case-insensitive context, so all these tests run fine: 'A' =~ /\p{Lower}/i or die; 'a' =~ /\p{Upper}/i or die; 'A' =~ /\p{gc=Lt}/i or die; # title case 'a' =~ /\p{IsTitlecase}/i or die; '?' =~ /\p{Lower}/i or die; # title-cased digraph '?' =~ /\p{Upper}/i or die; '?' =~ /\p{Lt}/i or die; For reference, here's a lengthy document, describing precise rules used by Perl to deal with \p{} char classes: https://perldoc.perl.org/perluniprops.html#Properties-accessible-through-%5cp%7b%7d-and-%5cP%7b%7d So, for any Lower, Upper or Title case chars in case-insensitive context Perl uses set of "Cased Letters", with is just a combination of these three categories (aka "LC" general category). Would you please help review the patch? BUGURL: https://bugs.openjdk.java.net/browse/JDK-8214245 WEBREV: http://cr.openjdk.java.net/~igerasim/8214245/00/webrev/ -- With kind regards, Ivan Gerasimov From andy.herrick at oracle.com Mon Apr 22 14:38:05 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Mon, 22 Apr 2019 10:38:05 -0400 Subject: jpackage EA 6 Build 49 (2019/4/19) Message-ID: <00b9a8bd-8b4e-0024-786d-7393b1cac472@oracle.com> A sixth EA build (Build 49) of jpackage tool is available at https://jdk.java.net/jpackage/ This release contains fixes to the following issues: JDK-8221777:? CLI changes from jpackage EA5 feedback JDK-8221779:? Help text changes from JDK-8221777 and other jpackage EA5 feedback JDK-8222733:? Modify jpackage option --add-launcher syntax JDK-8219683:? Modify App Image layout on Mac JDK-8222676:? create-installer with --app-image fails on mac JDK-8222406:? Multiple arguments for the same option - aggragation broken. JDK-8222486:? Reorder sample usage in jpackage help output JDK-8222439:? New jpackage test fails on mac, linux JDK-8217895:? jpackage --identifer purpose JDK-8221749:? Error messages JDK-8221641:? Follow up code clean up for JDK-8221582 JDK-8221876:? [macOS] JPackage install takes long time JDK-8208652:? JPackageCreateInstallerFileAssociationsTest.java fails on Mac. please send feedback to core-libs-dev at openjdk.java.net /Andy Herrick From Alan.Bateman at oracle.com Mon Apr 22 15:52:14 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 22 Apr 2019 16:52:14 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <9218d37f-9820-9216-b125-8f3bc2d19e3d@redhat.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> <9218d37f-9820-9216-b125-8f3bc2d19e3d@redhat.com> Message-ID: <453045f6-0259-e098-8211-0187428adb9f@oracle.com> On 18/04/2019 10:17, Andrew Dinn wrote: > Hi Alan, > > The CSR for this issue has been finalized and is awaiting approval. > Would it now be possible to proceed with reviews of the implementation? > > JIRA: https://bugs.openjdk.java.net/browse/JDK-8221696 > webrev: http://cr.openjdk.java.net/~adinn/8221696/webrev.01 > The calculation to compute the page aligned address and then the distance from there to the end of the region is tricky to get right. I think you have it right, I'm just wondering if we could leverage the existing mappingOffset/mappingAddress methods so that we have only one place to audit. For example, suppose mappingOffset is changed to take an index. I think this would reduce the new force method down to: long offset = mappingOffset(index); force0(fd, mappingAddress(offset), offset + length); We'd need to add an overload so that the existing usages of mappingOffset would continue to work, or we change then to use mappingOffset(0).? Just something to think about because this code is tricky. I don't expect any issues on Windows but I will test it to make sure. -Alan From james.laskey at oracle.com Mon Apr 22 17:45:53 2019 From: james.laskey at oracle.com (Jim Laskey) Date: Mon, 22 Apr 2019 14:45:53 -0300 Subject: RFR: 8215017: Improve String::equals warmup characteristics In-Reply-To: References: Message-ID: <2BC8E39D-68EA-4550-9218-6F2C6BC87DD8@oracle.com> +1 > On Dec 7, 2018, at 8:11 PM, Claes Redestad wrote: > > Hi, > > following up from discussions during review of JDK-8214971[1], I > examined the startup and peak performance of a few different variant of > writing String::equals. > > Webrev: http://cr.openjdk.java.net/~redestad/8215017/jdk.00/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8215017 > > - folding coder() == aString.coder() into sameCoder(aString) helps > interpreter without adversely affecting higher optimization levels > > - Jim's proposal to use Arrays.equals is _interesting_: it improves > peak performance on some inputs but regress it on others. I'll defer > that to a future RFE as it needs a more thorough examination. > > - what we can do is simplify to only use StringLatin1.equals. If I'm not > completely mistaken these are all semantically neutral (and > StringUTF16.equals effectively redundant). If I'm completely wrong here > I'll welcome the learning opportunity. :-) > > This removes a branch and two method calls, and for UTF16 Strings we'll > use a simpler algorithm early, which turns out to be beneficial during > interpreter and C1 level. > > I added a simple microbenchmark to explore this, results show 1.2-2.5x > improvements in interpreter performance, while remaining perfectly > neutral results for optimized code on this simple micro[2]. > > This could be extended to clean up and move StringLatin1.equals back > into String and remove StringUTF16, but we'd also need to rearrange the > intrinsics on the VM side. Let me know what you think. > > Thanks! > > /Claes > > [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-December/057162.html > > [2] > ========== Baseline ================= > > -Xint > Benchmark Mode Cnt Score Error Units > StringEquals.equalsAlmostEqual avgt 4 968.640 ? 1.337 ns/op > StringEquals.equalsAlmostEqualUTF16 avgt 4 2082.007 ? 5.303 ns/op > StringEquals.equalsDifferent avgt 4 583.166 ? 29.461 ns/op > StringEquals.equalsDifferentCoders avgt 4 422.993 ? 1.291 ns/op > StringEquals.equalsEqual avgt 4 988.671 ? 1.492 ns/op > StringEquals.equalsEqualsUTF16 avgt 4 2103.060 ? 5.705 ns/op > > -XX:+CompactStrings > Benchmark Mode Cnt Score Error Units > StringEquals.equalsAlmostEqual avgt 4 23.896 ? 0.089 ns/op > StringEquals.equalsAlmostEqualUTF16 avgt 4 23.935 ? 0.562 ns/op > StringEquals.equalsDifferent avgt 4 15.086 ? 0.044 ns/op > StringEquals.equalsDifferentCoders avgt 4 12.572 ? 0.008 ns/op > StringEquals.equalsEqual avgt 4 25.143 ? 0.025 ns/op > StringEquals.equalsEqualsUTF16 avgt 4 25.148 ? 0.021 ns/op > > -XX:-CompactStrings > Benchmark Mode Cnt Score Error Units > StringEquals.equalsAlmostEqual avgt 4 24.539 ? 0.127 ns/op > StringEquals.equalsAlmostEqualUTF16 avgt 4 22.638 ? 0.047 ns/op > StringEquals.equalsDifferent avgt 4 13.930 ? 0.835 ns/op > StringEquals.equalsDifferentCoders avgt 4 13.836 ? 0.025 ns/op > StringEquals.equalsEqual avgt 4 26.420 ? 0.020 ns/op > StringEquals.equalsEqualsUTF16 avgt 4 23.889 ? 0.037 ns/op > > ========== Fix ====================== > > -Xint > Benchmark Mode Cnt Score Error Units > StringEquals.equalsAlmostEqual avgt 4 811.859 ? 8.663 ns/op > StringEquals.equalsAlmostEqualUTF16 avgt 4 802.784 ? 352.884 ns/op > StringEquals.equalsDifferent avgt 4 431.837 ? 1.884 ns/op > StringEquals.equalsDifferentCoders avgt 4 358.244 ? 1.208 ns/op > StringEquals.equalsEqual avgt 4 832.056 ? 3.541 ns/op > StringEquals.equalsEqualsUTF16 avgt 4 832.434 ? 3.516 ns/op > > -XX:+CompactStrings > Benchmark Mode Cnt Score Error Units > StringEquals.equalsAlmostEqual avgt 4 23.906 ? 0.151 ns/op > StringEquals.equalsAlmostEqualUTF16 avgt 4 23.905 ? 0.123 ns/op > StringEquals.equalsDifferent avgt 4 15.088 ? 0.023 ns/op > StringEquals.equalsDifferentCoders avgt 4 12.575 ? 0.030 ns/op > StringEquals.equalsEqual avgt 4 25.149 ? 0.059 ns/op > StringEquals.equalsEqualsUTF16 avgt 4 25.149 ? 0.033 ns/op > > -XX:-CompactStrings > Benchmark Mode Cnt Score Error Units > StringEquals.equalsAlmostEqual avgt 4 24.521 ? 0.050 ns/op > StringEquals.equalsAlmostEqualUTF16 avgt 4 22.639 ? 0.035 ns/op > StringEquals.equalsDifferent avgt 4 13.831 ? 0.020 ns/op > StringEquals.equalsDifferentCoders avgt 4 13.884 ? 0.345 ns/op > StringEquals.equalsEqual avgt 4 26.395 ? 0.066 ns/op > StringEquals.equalsEqualsUTF16 avgt 4 23.904 ? 0.112 ns/op From james.laskey at oracle.com Mon Apr 22 18:34:02 2019 From: james.laskey at oracle.com (Jim Laskey) Date: Mon, 22 Apr 2019 15:34:02 -0300 Subject: RFR - JDK-8212975 ClassDesc should have a full name method Message-ID: <1A1BEBF9-5180-4EAA-9B25-22917F3080FD@oracle.com> ClassDesc.displayName(boolean detail) allows the user the option to fetch the fully qualified class name. webrev: http://cr.openjdk.java.net/~jlaskey/8212975/webrev-02 JBS: https://bugs.openjdk.java.net/browse/JDK-8212975 Thank you. Cheers, - Jim From some-java-user-99206970363698485155 at vodafonemail.de Mon Apr 22 19:54:32 2019 From: some-java-user-99206970363698485155 at vodafonemail.de (some-java-user-99206970363698485155 at vodafonemail.de) Date: Mon, 22 Apr 2019 21:54:32 +0200 (CEST) Subject: Feature suggestion: Allow generic wildcard in class literal expression In-Reply-To: <926413616.355273.1546642874476@mail.vodafone.de> References: <926413616.355273.1546642874476@mail.vodafone.de> Message-ID: <795533387.132210.1555962872435@mail.vodafone.de> What do you think about this idea? I hope the fact that I did not get any responses yet does not mean that you are not interested or that I annoyed you. > JDK-6184881 describes that Object.getClass() should ideally not return classes of raw types anymore but instead use wildcards. The problem is that, as noted in the comments, this breaks compability with previously written code and therefore this change is not very likely (at the moment?). > > However, the report does not cover the class literal expression (https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.8.2). > > It would be good to allow the usage of the wildcard (`?`) for this expression: > List.class => Class> > > Since it is currently not allowed to provide type parameters in the class literal expression there should not be any compatibility issues. > Additionally if at some point JDK-6184881 is fixed for class literals as well, then the expression List.class could just be a verbose variant of List.class without causing any problems either. > > > This would make writing methods or constructors which determine a generic type based on a given class easier for generic classes, e.g.: > > public class MyContainer { > private final Class valueClass; > > public MyContainer(Class valueClass) { > this.valueClass = valueClass; > } > > public static void main(String[] args) { > MyContainer stringContainer = new MyContainer<>(String.class); > // Have to use raw type (or verbose casting of class) > MyContainer listContainer = new MyContainer<>(List.class); > > // With suggested change: > MyContainer> listContainer = new MyContainer<>(List.class); > } > } > From philip.race at oracle.com Mon Apr 22 20:57:24 2019 From: philip.race at oracle.com (Phil Race) Date: Mon, 22 Apr 2019 13:57:24 -0700 Subject: RFR: 8212701: remove sun.desktop property from launcher code Message-ID: <4653924b-6fe6-67d6-4e90-af1200e5496b@oracle.com> Bug: https://bugs.openjdk.java.net/browse/JDK-8212701 CSR: https://bugs.openjdk.java.net/browse/JDK-8222814 Webrev: http://cr.openjdk.java.net/~prr/8212701/index.html Please review the above CSR and webrev which eliminates the sun.desktop system property which was set in launcher code to the value 1) "windows" on Windows for no apparent reason 2) "gnome" if running in a Gnome desktop session 3) left unset in all other cases/platforms/desktops, so it being null seems unlikely to be a problem. The Swing code in the desktop module that consumed the value has been updated to get it in a different way internal to the desktop module. -phil. From sci at amazon.com Mon Apr 22 21:04:42 2019 From: sci at amazon.com (Sciampacone, Ryan) Date: Mon, 22 Apr 2019 21:04:42 +0000 Subject: [8u-dev] RFR (S): JDK-8194653: Deadlock involving FileSystems.getDefault and System.loadLibrary call Message-ID: Bug: https://bugs.openjdk.java.net/browse/JDK-8194653 Webrev: http://cr.openjdk.java.net/~phh/8194653/webrev.00/ Eliminates a race condition on call to java.nio.file.FileSystems::getDefault() where two threads (one inside a loadLibrary() call) could cause a deadlock if they both referenced this code path. Priming the code path during startup eliminates the deadlock ( and loadLibrary0 are single threaded). Note the JVM is at the end of initialization and the getDefault() call is safe to make. This does result in a few extra classes being loaded before the user class is touched, but this path was almost inevitably being called once the user class is invoked. The general problem of multithreaded class initialization and JNI library loading remains ? this patch addresses a defect that is seen out in the field (the defect contains at least 2 public cases, anecdotally I have seen others). This is JDK8 only ? as discussed in the defect JDK9 and beyond address this problem with a different startup sequence. Note that Oracle appears to have picked up this fix (or a version of it) for their 8u repo. Paul Hohensee (phh) has agreed to sponsor the fix. From david.holmes at oracle.com Mon Apr 22 22:11:18 2019 From: david.holmes at oracle.com (David Holmes) Date: Tue, 23 Apr 2019 08:11:18 +1000 Subject: [8u-dev] RFR (S): JDK-8194653: Deadlock involving FileSystems.getDefault and System.loadLibrary call In-Reply-To: References: Message-ID: Hi Ryan, On 23/04/2019 7:04 am, Sciampacone, Ryan wrote: > > Bug: https://bugs.openjdk.java.net/browse/JDK-8194653 > Webrev: http://cr.openjdk.java.net/~phh/8194653/webrev.00/ Why does this need to be pushed to the VM? Why not do the pre-loading/initializing at the Java level? Cheers, David ----- > Eliminates a race condition on call to java.nio.file.FileSystems::getDefault() where two threads (one inside a loadLibrary() call) could cause a deadlock if they both referenced this code path. Priming the code path during startup eliminates the deadlock ( and loadLibrary0 are single threaded). Note the JVM is at the end of initialization and the getDefault() call is safe to make. This does result in a few extra classes being loaded before the user class is touched, but this path was almost inevitably being called once the user class is invoked. > > The general problem of multithreaded class initialization and JNI library loading remains ? this patch addresses a defect that is seen out in the field (the defect contains at least 2 public cases, anecdotally I have seen others). > > This is JDK8 only ? as discussed in the defect JDK9 and beyond address this problem with a different startup sequence. > > Note that Oracle appears to have picked up this fix (or a version of it) for their 8u repo. > > Paul Hohensee (phh) has agreed to sponsor the fix. > > > From david.holmes at oracle.com Mon Apr 22 22:12:20 2019 From: david.holmes at oracle.com (David Holmes) Date: Tue, 23 Apr 2019 08:12:20 +1000 Subject: [8u-dev] RFR (S): JDK-8194653: Deadlock involving FileSystems.getDefault and System.loadLibrary call In-Reply-To: References: Message-ID: PS. Given you have implemented this in the VM you're asking for a review on the wrong mailing list. David On 23/04/2019 7:04 am, Sciampacone, Ryan wrote: > > Bug: https://bugs.openjdk.java.net/browse/JDK-8194653 > Webrev: http://cr.openjdk.java.net/~phh/8194653/webrev.00/ > > Eliminates a race condition on call to java.nio.file.FileSystems::getDefault() where two threads (one inside a loadLibrary() call) could cause a deadlock if they both referenced this code path. Priming the code path during startup eliminates the deadlock ( and loadLibrary0 are single threaded). Note the JVM is at the end of initialization and the getDefault() call is safe to make. This does result in a few extra classes being loaded before the user class is touched, but this path was almost inevitably being called once the user class is invoked. > > The general problem of multithreaded class initialization and JNI library loading remains ? this patch addresses a defect that is seen out in the field (the defect contains at least 2 public cases, anecdotally I have seen others). > > This is JDK8 only ? as discussed in the defect JDK9 and beyond address this problem with a different startup sequence. > > Note that Oracle appears to have picked up this fix (or a version of it) for their 8u repo. > > Paul Hohensee (phh) has agreed to sponsor the fix. > > > From Sergey.Bylokhov at oracle.com Tue Apr 23 03:02:53 2019 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Mon, 22 Apr 2019 20:02:53 -0700 Subject: RFR: 8212701: remove sun.desktop property from launcher code In-Reply-To: <4653924b-6fe6-67d6-4e90-af1200e5496b@oracle.com> References: <4653924b-6fe6-67d6-4e90-af1200e5496b@oracle.com> Message-ID: <1c5688a1-6ece-be01-1476-56438a35d8eb@oracle.com> Looks fine. On 22/04/2019 13:57, Phil Race wrote: > Bug: https://bugs.openjdk.java.net/browse/JDK-8212701 > CSR: https://bugs.openjdk.java.net/browse/JDK-8222814 > Webrev: http://cr.openjdk.java.net/~prr/8212701/index.html > > Please review the above CSR and webrev which eliminates the sun.desktop system property > which was set in launcher code to the value > 1) "windows" on Windows for no apparent reason > 2) "gnome" if running in a Gnome desktop session > 3) left unset in all other cases/platforms/desktops, so it being null seems unlikely to be a problem. > > The Swing code in the desktop module that consumed the value > has been updated to get it in a different way internal to the desktop module. > > -phil. > -- Best regards, Sergey. From Alan.Bateman at oracle.com Tue Apr 23 06:41:40 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 23 Apr 2019 07:41:40 +0100 Subject: [8u-dev] RFR (S): JDK-8194653: Deadlock involving FileSystems.getDefault and System.loadLibrary call In-Reply-To: References: Message-ID: On 22/04/2019 23:11, David Holmes wrote: > Hi Ryan, > > On 23/04/2019 7:04 am, Sciampacone, Ryan wrote: >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8194653 >> Webrev: http://cr.openjdk.java.net/~phh/8194653/webrev.00/ > > Why does this need to be pushed to the VM? Why not do the > pre-loading/initializing at the Java level? Ryan - do you have a test case that demonstrates the issue with the main line (jdk/jdk)? I think we need that in order to study this issue a bit more closely and see what options are available. I see Paul has pasted in a stack trace from January and I think it would be interesting to see what command line options were used. I don't have a good sense yet how this might be fixed but it may need work in FilePermission and/or initializing the default file system provider at a different time during the startup. -Alan From Alan.Bateman at oracle.com Tue Apr 23 06:52:16 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 23 Apr 2019 07:52:16 +0100 Subject: RFR: 8212701: remove sun.desktop property from launcher code In-Reply-To: <4653924b-6fe6-67d6-4e90-af1200e5496b@oracle.com> References: <4653924b-6fe6-67d6-4e90-af1200e5496b@oracle.com> Message-ID: <1b5de082-b46a-b4e9-12ca-eedaa46d82c2@oracle.com> On 22/04/2019 21:57, Phil Race wrote: > Bug: https://bugs.openjdk.java.net/browse/JDK-8212701 > CSR: https://bugs.openjdk.java.net/browse/JDK-8222814 > Webrev: http://cr.openjdk.java.net/~prr/8212701/index.html The launcher changes look fine. -Alan From lenborje at gmail.com Tue Apr 23 07:19:52 2019 From: lenborje at gmail.com (=?utf-8?Q?Lennart_B=C3=B6rjeson?=) Date: Tue, 23 Apr 2019 09:19:52 +0200 Subject: ZipFileSystem performance regression In-Reply-To: References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> <680D03D1-9631-45DA-A89A-6EEDBC63EACE@gmail.com> Message-ID: <1C3C1378-AF9A-4283-B0DE-9E99D605936A@gmail.com> Any chance we might get this repaired in time for the Java 13 ramp down? Best regards, /Lennart B?rjeson > 16 apr. 2019 kl. 23:02 skrev Langer, Christoph : > > Hi, > > I also think the regression should be repaired and maybe we can have an option like "lazy compress" to avoid compression on write but defer it to zipfs closing time. > > It should also be possible to parallelize deflation during close, shouldn't it? > > Best regards > Christoph > >> -----Original Message----- >> From: core-libs-dev On Behalf >> Of Xueming Shen >> Sent: Dienstag, 16. April 2019 22:50 >> To: Lennart B?rjeson >> Cc: core-libs-dev at openjdk.java.net >> Subject: Re: ZipFileSystem performance regression >> >> Well, have to admitted I didn't expect your use scenario when made the >> change. Thought as a >> >> filesystem runtime access performance has more weight compared to >> shutdown performance... >> >> basically you are no using zipfs as a filesystem, but another jar tool >> that happens to have >> >> better in/out concurrent performance. Yes, back then I was working on >> using zipfs as a memory >> >> filesystem. One possible usage is that javac to use it as its filesystem >> (temp?) to write out compiled >> >> class files ... so I thought I can have better performance if I can keep >> those classes uncompressed >> >> until the zip/jarfs is closed and written to a "jar" file. >> >> That said, regression is a regression, we probably want to get the >> performance back for your >> >> use scenario. Just wanted to give you guys some background what happened >> back then. >> >> >> -Sherman >> >> >> On 4/16/19 12:54 PM, Lennart B?rjeson wrote: >>> I?m using the tool I wrote to compress directories with thousands of log >> files. The standard zip utility (as well as my utility when run with JDK 12) takes >> up to an hour of user time to create the archive, on our server class 40+ core >> servers this is reduced to 1?2 minutes. >>> >>> So while I understand the motivation for the change, I don?t get why you >> would want to use ZipFs for what in essence is a RAM disk, *unless* you >> want it compressed in memory? >>> >>> Oh well. Do we need a new option for this? >>> >>> /Lennart B?rjeson >>> >>> Electrogramma ab iPhono meo missum est >>> >>>> 16 apr. 2019 kl. 21:44 skrev Xueming Shen : >>>> >>>> One of the motivations back then is to speed up the performance of >> accessing >>>> >>>> those entries, means you don't have to deflate/inflate those >> new/updated entries >>>> >>>> during the lifetime of that zipfilesystem. Those updated entries only get >> compressed >>>> >>>> when go to storage. So the regression is more like a trade off of >> performance of >>>> >>>> different usages. (it also simplifies the logic on handing different types of >> entries ...) >>>> >>>> >>>> One idea I experimented long time ago for jartool is to concurrently write >> out >>>> >>>> entries when need compression ... it does gain some performance >> improvement >>>> >>>> on multi-cores, but not lots, as it ends up coming back to the main thread >> to >>>> >>>> write out to the underlying filesystem. >>>> >>>> >>>> -Sherman >>>> >>>>> On 4/16/19 5:21 AM, Claes Redestad wrote: >>>>> Both before and after this regression, it seems the default behavior is >>>>> not to use a temporary file (until ZFS.sync(), which writes to a temp >>>>> file and then moves it in place, but that's different from what happens >>>>> with the useTempFile option enabled). Instead entries (and the backing >>>>> zip file system) are kept in-memory. >>>>> >>>>> The cause of the issue here is instead that no deflation happens until >>>>> sync(), even when writing to entries in-memory. Previously, the >>>>> deflation happened eagerly, then the result of that was copied into >>>>> the zip file during sync(). >>>>> >>>>> I've written a proof-of-concept patch that restores the behavior of >>>>> eagerly compressing entries when the method is METHOD_DEFLATED >> and the >>>>> target is to store byte[]s in-memory (the default scenario): >>>>> >>>>> http://cr.openjdk.java.net/~redestad/scratch/zfs.eager_deflation.00/ >>>>> >>>>> This restores performance of parallel zip to that of 11.0.2 for the >>>>> default case. It still has a similar regression for the case where >>>>> useTempFile is enabled, but that should be easily addressed if this >>>>> looks like a way forward? >>>>> >>>>> (I've not yet created a bug as I got too caught up in trying to figure >>>>> out what was going on here...) >>>>> >>>>> Thanks! >>>>> >>>>> /Claes >>>>> >>>>>> On 2019-04-16 09:29, Alan Bateman wrote: >>>>>>> On 15/04/2019 14:32, Lennart B?rjeson wrote: >>>>>>> : >>>>>>> >>>>>>> Previously, the deflation was done when in the call to Files.copy, thus >> executed in parallel, and the final ZipFileSystem.close() didn't do anything >> much. >>>>>>> >>>>>> Can you submit a bug? When creating/updating a zip file with zipfs then >> the closing the file system creates the zip file. Someone needs to check but it >> may have been that the temporary files (on the file system hosting the zip >> file) were deflated when writing (which is surprising but may have been the >> case). >>>>>> >>>>>> -Alan From Alan.Bateman at oracle.com Tue Apr 23 07:29:22 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 23 Apr 2019 08:29:22 +0100 Subject: ZipFileSystem performance regression In-Reply-To: <1C3C1378-AF9A-4283-B0DE-9E99D605936A@gmail.com> References: <82233063-7CD4-4C8B-9BB9-49E1696795D6@gmail.com> <3063F2F5-CD96-4D46-A992-0576782BF3CB@gmail.com> <9b179056-aa0c-e900-eced-de84833be5e7@oracle.com> <87b1d281-a8e0-95a7-c87c-643a1a81606d@oracle.com> <680D03D1-9631-45DA-A89A-6EEDBC63EACE@gmail.com> <1C3C1378-AF9A-4283-B0DE-9E99D605936A@gmail.com> Message-ID: <31bddc3b-f1f1-ebc8-0307-73dd5f5ed73e@oracle.com> On 23/04/2019 08:19, Lennart B?rjeson wrote: > Any chance we might get this repaired in time for the Java 13 ramp down? > > Under discussion/review here: https://mail.openjdk.java.net/pipermail/nio-dev/2019-April/006043.html From kustaa.nyholm at sparetimelabs.com Tue Apr 23 08:04:47 2019 From: kustaa.nyholm at sparetimelabs.com (Kustaa Nyholm) Date: Tue, 23 Apr 2019 11:04:47 +0300 Subject: jpackage EA 6 Build 49 (2019/4/19) In-Reply-To: <00b9a8bd-8b4e-0024-786d-7393b1cac472@oracle.com> References: <00b9a8bd-8b4e-0024-786d-7393b1cac472@oracle.com> Message-ID: Hi, thanks for those fixes. What about the compatibility with older macOS version, I think you said you'd file a bug report but I never got the number of that. wbr Kusti > On 22 Apr 2019, at 17.38, Andy Herrick wrote: > > A sixth EA build (Build 49) of jpackage tool is available at https://jdk.java.net/jpackage/ > > This release contains fixes to the following issues: > > JDK-8221777: CLI changes from jpackage EA5 feedback > JDK-8221779: Help text changes from JDK-8221777 and other jpackage EA5 feedback > JDK-8222733: Modify jpackage option --add-launcher syntax > JDK-8219683: Modify App Image layout on Mac > JDK-8222676: create-installer with --app-image fails on mac > JDK-8222406: Multiple arguments for the same option - aggragation broken. > JDK-8222486: Reorder sample usage in jpackage help output > JDK-8222439: New jpackage test fails on mac, linux > JDK-8217895: jpackage --identifer purpose > JDK-8221749: Error messages > JDK-8221641: Follow up code clean up for JDK-8221582 > JDK-8221876: [macOS] JPackage install takes long time > JDK-8208652: JPackageCreateInstallerFileAssociationsTest.java fails on Mac. > > please send feedback to core-libs-dev at openjdk.java.net > > /Andy Herrick > From christoph.langer at sap.com Tue Apr 23 09:37:25 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Tue, 23 Apr 2019 09:37:25 +0000 Subject: RFR: 8222440: (zipfs) JarFileSystem does not correctly handle versioned entries if no root entry is present In-Reply-To: <7C9075D6-69B2-4A8E-A748-CA61537B4710@oracle.com> References: <7C9075D6-69B2-4A8E-A748-CA61537B4710@oracle.com> Message-ID: Hi Lance, > Overall, I think the changes look good. Thanks for looking at this. > Was there a reason that you did not leave the multi-release 9 test as is when > you added the 10 test? Well, since I wanted to use this test as blueprint to provoke the jarfs issue, I had a closer look to it. I thought it's nicer if the structure of the jar file to test could be defined in the code rather than by directory trees checked into mercurial. But if you think, it's not a good idea to refacture this, I can also leave it untouched. I could alternatively add my test as a net new testcase. I also thought already, that I'd hereby remove a test path for the jar tool to create multi release jars... wanted to check if that's tested somewhere else still. So what do you (or others) say which way I should go? > As far as removing the jar file, I would think that would still want to be > done. ?I understand why you did this, not sure what the standard is here as > most tests try to do clean up Hm, I thought, the jar file is so small that it wouldn't be ok to leave it in scratch and have jtreg do the cleanup. I'll check if I can come up with something that would take the retain policy of jtreg into account... Best regards Christoph From lance.andersen at oracle.com Tue Apr 23 10:49:00 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Tue, 23 Apr 2019 06:49:00 -0400 Subject: RFR: 8222440: (zipfs) JarFileSystem does not correctly handle versioned entries if no root entry is present In-Reply-To: References: <7C9075D6-69B2-4A8E-A748-CA61537B4710@oracle.com> Message-ID: Hi Christoph > On Apr 23, 2019, at 5:37 AM, Langer, Christoph wrote: > > Hi Lance, > >> Overall, I think the changes look good. > > Thanks for looking at this. > > >> Was there a reason that you did not leave the multi-release 9 test as is when >> you added the 10 test? > > Well, since I wanted to use this test as blueprint to provoke the jarfs issue, I had a closer look to it. I thought it's nicer if the structure of the jar file to test could be defined in the code rather than by directory trees checked into mercurial. But if you think, it's not a good idea to refacture this, I can also leave it untouched. I could alternatively add my test as a net new testcase. > Thank you for the follow up. No the restructure of the test and getting rid of the directory tree and just building the jar within the test is good > I also thought already, that I'd hereby remove a test path for the jar tool to create multi release jars... wanted to check if that's tested somewhere else still. > > So what do you (or others) say which way I should go? > >> As far as removing the jar file, I would think that would still want to be >> done. I understand why you did this, not sure what the standard is here as >> most tests try to do clean up > > Hm, I thought, the jar file is so small that it wouldn't be ok to leave it in scratch and have jtreg do the cleanup. I'll check if I can come up with something that would take the retain policy of jtreg into account? I do not have a strong preference either way. In the past, I have been suggested to clean up anything created. I agree it can be handy if it these types of things remain after a failure I think you are good to go. Best Lance > > Best regards > Christoph > 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 claes.redestad at oracle.com Tue Apr 23 11:05:30 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 23 Apr 2019 13:05:30 +0200 Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers Message-ID: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> Hi, by folding a constant prepend followed by an argument prepend into a single prepender with the constant bound in, we significantly reduce the amount of possible MH shapes that the String concat bootstrap method can generate by sharing the stem of the combinator tree between similar concatenations like '"foo" + obj + obj' and 'obj + "foo" + obj'. See bug for details and the outline of a proof that this turns an exponential growth factor into a constant one. Bug: https://bugs.openjdk.java.net/browse/JDK-8222852 Webrev: http://cr.openjdk.java.net/~redestad/8222852/open.00/ Testing: tier1-3, verified retained throughput performance in microbenchmarks, verified significant startup and footprint improvements for both realistic and synthetically complex combinations of argument shapes. Thanks! /Claes From shade at redhat.com Tue Apr 23 11:27:00 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Tue, 23 Apr 2019 13:27:00 +0200 Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> Message-ID: <05526f62-727a-6b53-b15f-a8df3a1cb688@redhat.com> On 4/23/19 1:05 PM, Claes Redestad wrote: > Bug:??? https://bugs.openjdk.java.net/browse/JDK-8222852 > Webrev: http://cr.openjdk.java.net/~redestad/8222852/open.00/ Cool. Do we see the real-world examples where this helps? E.g. larger applications that have lots of concats? Asking because most apps do not have lots of concat shapes to begin with. I'd keep the switch in the second loop, like this: for (RecipeElement el : recipe.getElements()) { switch (el.getTag()) { case TAG_ARG: ... break; case TAG_CONST: // Constants are already handled in the code above. break; default: throw new StringConcatException("Unhandled tag: " + el.getTag()); } } -Aleksey From claes.redestad at oracle.com Tue Apr 23 12:07:11 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 23 Apr 2019 14:07:11 +0200 Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: <05526f62-727a-6b53-b15f-a8df3a1cb688@redhat.com> References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> <05526f62-727a-6b53-b15f-a8df3a1cb688@redhat.com> Message-ID: On 2019-04-23 13:27, Aleksey Shipilev wrote: > On 4/23/19 1:05 PM, Claes Redestad wrote: >> Bug:??? https://bugs.openjdk.java.net/browse/JDK-8222852 >> Webrev: http://cr.openjdk.java.net/~redestad/8222852/open.00/ > > Cool. Do we see the real-world examples where this helps? E.g. larger applications that have lots of > concats? Asking because most apps do not have lots of concat shapes to begin with. I can see some real but modest gains at use sites in the JDK code, e.g., java.util.logging bootstraps a few variants, and you get small improvements already on bootstrapping obj + "foo" + obj at one site and "foo" + obj + obj at another (-8 classes). Most "real-world" benchmarks we run have not been built with a release target of 9 or above, and even if they had most libraries they use are likely to stay 8 compatible for some time. So it's anyone's guess what gains we'd be able to expect on modern real-world applications. > > I'd keep the switch in the second loop, like this: > > for (RecipeElement el : recipe.getElements()) { > switch (el.getTag()) { > case TAG_ARG: > ... > break; > case TAG_CONST: > // Constants are already handled in the code above. > break; > default: > throw new StringConcatException("Unhandled tag: " + el.getTag()); > } > } I figured that since the first switch would already check for unhandled tags then a single test for TAG_ARG would suffice in the second, but I have no strong opinion. Just thought it simplified the code flow a bit. Thanks! /Claes From kevin.rushforth at oracle.com Tue Apr 23 12:08:59 2019 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Tue, 23 Apr 2019 05:08:59 -0700 Subject: jpackage EA 6 Build 49 (2019/4/19) In-Reply-To: References: <00b9a8bd-8b4e-0024-786d-7393b1cac472@oracle.com> Message-ID: <73ae56bf-b5b8-41cb-c60e-f90e64136ecb@oracle.com> I didn't try your exact scenario yet (building the installer on 10.14 and running it on an earlier version, right?), but I have successfully run jpackage on macOS 10.12. Now that we have the new EA out, it would be worth trying it again. I note that by the time JDK 13 comes out, macOS 10.13 will be the oldest version of macOS that Apple will support. Having said that, I don't know of any reason why it should work as far back as 10.11 -- it just won't be supported. -- Kevin On 4/23/2019 1:04 AM, Kustaa Nyholm wrote: > Hi, > > thanks for those fixes. > > What about the compatibility with older macOS version, I think you said you'd file > a bug report but I never got the number of that. > > wbr Kusti > > >> On 22 Apr 2019, at 17.38, Andy Herrick wrote: >> >> A sixth EA build (Build 49) of jpackage tool is available at https://jdk.java.net/jpackage/ >> >> This release contains fixes to the following issues: >> >> JDK-8221777: CLI changes from jpackage EA5 feedback >> JDK-8221779: Help text changes from JDK-8221777 and other jpackage EA5 feedback >> JDK-8222733: Modify jpackage option --add-launcher syntax >> JDK-8219683: Modify App Image layout on Mac >> JDK-8222676: create-installer with --app-image fails on mac >> JDK-8222406: Multiple arguments for the same option - aggragation broken. >> JDK-8222486: Reorder sample usage in jpackage help output >> JDK-8222439: New jpackage test fails on mac, linux >> JDK-8217895: jpackage --identifer purpose >> JDK-8221749: Error messages >> JDK-8221641: Follow up code clean up for JDK-8221582 >> JDK-8221876: [macOS] JPackage install takes long time >> JDK-8208652: JPackageCreateInstallerFileAssociationsTest.java fails on Mac. >> >> please send feedback to core-libs-dev at openjdk.java.net >> >> /Andy Herrick >> From kevin.rushforth at oracle.com Tue Apr 23 12:17:49 2019 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Tue, 23 Apr 2019 05:17:49 -0700 Subject: jpackage EA 6 Build 49 (2019/4/19) In-Reply-To: <73ae56bf-b5b8-41cb-c60e-f90e64136ecb@oracle.com> References: <00b9a8bd-8b4e-0024-786d-7393b1cac472@oracle.com> <73ae56bf-b5b8-41cb-c60e-f90e64136ecb@oracle.com> Message-ID: > I don't know of any reason why it should work as far back as 10.11 I meant I don't know of any reason why it should NOT work as far back as 10.11... -- Kevin On 4/23/2019 5:08 AM, Kevin Rushforth wrote: > I didn't try your exact scenario yet (building the installer on 10.14 > and running it on an earlier version, right?), but I have successfully > run jpackage on macOS 10.12. Now that we have the new EA out, it would > be worth trying it again. > > I note that by the time JDK 13 comes out, macOS 10.13 will be the > oldest version of macOS that Apple will support. Having said that, I > don't know of any reason why it should work as far back as 10.11 -- it > just won't be supported. > > -- Kevin > > > On 4/23/2019 1:04 AM, Kustaa Nyholm wrote: >> Hi, >> >> thanks for those fixes. >> >> What about the compatibility with older macOS version, I think you >> said you'd file >> a bug report but I never got the number of that. >> >> wbr Kusti >> >> >>> On 22 Apr 2019, at 17.38, Andy Herrick wrote: >>> >>> A sixth EA build (Build 49) of jpackage tool is available at >>> https://jdk.java.net/jpackage/ >>> >>> This release contains fixes to the following issues: >>> >>> JDK-8221777:? CLI changes from jpackage EA5 feedback >>> JDK-8221779:? Help text changes from JDK-8221777 and other jpackage >>> EA5 feedback >>> JDK-8222733:? Modify jpackage option --add-launcher syntax >>> JDK-8219683:? Modify App Image layout on Mac >>> JDK-8222676:? create-installer with --app-image fails on mac >>> JDK-8222406:? Multiple arguments for the same option - aggragation >>> broken. >>> JDK-8222486:? Reorder sample usage in jpackage help output >>> JDK-8222439:? New jpackage test fails on mac, linux >>> JDK-8217895:? jpackage --identifer purpose >>> JDK-8221749:? Error messages >>> JDK-8221641:? Follow up code clean up for JDK-8221582 >>> JDK-8221876:? [macOS] JPackage install takes long time >>> JDK-8208652:? JPackageCreateInstallerFileAssociationsTest.java fails >>> on Mac. >>> >>> please send feedback to core-libs-dev at openjdk.java.net >>> >>> /Andy Herrick >>> > From kustaa.nyholm at sparetimelabs.com Tue Apr 23 12:20:32 2019 From: kustaa.nyholm at sparetimelabs.com (Kustaa Nyholm) Date: Tue, 23 Apr 2019 15:20:32 +0300 Subject: jpackage EA 6 Build 49 (2019/4/19) In-Reply-To: <73ae56bf-b5b8-41cb-c60e-f90e64136ecb@oracle.com> References: <00b9a8bd-8b4e-0024-786d-7393b1cac472@oracle.com> <73ae56bf-b5b8-41cb-c60e-f90e64136ecb@oracle.com> Message-ID: <943B5699-8F40-4F5C-88BF-88A07B2AB068@sparetimelabs.com> Thanks Kevin > On 23 Apr 2019, at 15.08, Kevin Rushforth wrote: > > I didn't try your exact scenario yet (building the installer on 10.14 and running it on an earlier version, right?), but I have successfully run jpackage on macOS 10.12. Now that we have the new EA out, it would be worth trying it again. I will try again. But that is not the actual scenario which was that the resulting .app file did not run on older macOS versions: On 4/3/19, 11:25 PM, Kustaa Nyholm wrote: > "You can't use this version of the application with this version of OS X. > You have OS X 10.11.6. The application requires 10.13 or later." I suspect this is just a matter of compiler settings for the C-stub code that starts the JVM in which case it should be trivial to support almost any macOS version as I expect that the code should not have many OS version dependent stuff in it. > > I note that by the time JDK 13 comes out, macOS 10.13 will be the oldest version of macOS that Apple will support. Having said that, I don't know of any reason why it should work as far back as 10.11 -- it just won't be supported. As long as it works ;) You'd be surprised how many people (are forced to) hang to older macOS versions because they have expensive software that would require re-paying to get a version that runs on modern macOS versions. I sometimes think that people (at Apple and Linux community) do not realise that if the OS is free (as in beer) upgrading it often has a high price tag in terms of work and sometimes cold cash. So it really would be great if Java and by extension my software did not have to join the ranks of applications that force people to upgrade for no reason and no benefit. wbr Kusti From Roger.Riggs at oracle.com Tue Apr 23 14:33:04 2019 From: Roger.Riggs at oracle.com (Roger Riggs) Date: Tue, 23 Apr 2019 10:33:04 -0400 Subject: RFR: 8212701: remove sun.desktop property from launcher code In-Reply-To: <1b5de082-b46a-b4e9-12ca-eedaa46d82c2@oracle.com> References: <4653924b-6fe6-67d6-4e90-af1200e5496b@oracle.com> <1b5de082-b46a-b4e9-12ca-eedaa46d82c2@oracle.com> Message-ID: +1, Looks good, thanks for the native cleanup. Roger On 04/23/2019 02:52 AM, Alan Bateman wrote: > On 22/04/2019 21:57, Phil Race wrote: >> Bug: https://bugs.openjdk.java.net/browse/JDK-8212701 >> CSR: https://bugs.openjdk.java.net/browse/JDK-8222814 >> Webrev: http://cr.openjdk.java.net/~prr/8212701/index.html > The launcher changes look fine. > > -Alan > From sci at amazon.com Tue Apr 23 14:44:52 2019 From: sci at amazon.com (Sciampacone, Ryan) Date: Tue, 23 Apr 2019 14:44:52 +0000 Subject: [8u-dev] RFR (S): JDK-8194653: Deadlock involving FileSystems.getDefault and System.loadLibrary call In-Reply-To: References: Message-ID: <527BD0BA-634A-4C93-A792-CA6107D2BD81@amazon.com> Hey David, the bug was marked as core-libs and so this is why I posted to core-libs-dev. I'm happy to move the conversation elsewhere. Should I move this to hotspot-runtime-dev or do you have another suggestion? ?On 4/22/19, 3:13 PM, "David Holmes" wrote: PS. Given you have implemented this in the VM you're asking for a review on the wrong mailing list. David On 23/04/2019 7:04 am, Sciampacone, Ryan wrote: > > Bug: https://bugs.openjdk.java.net/browse/JDK-8194653 > Webrev: http://cr.openjdk.java.net/~phh/8194653/webrev.00/ > > Eliminates a race condition on call to java.nio.file.FileSystems::getDefault() where two threads (one inside a loadLibrary() call) could cause a deadlock if they both referenced this code path. Priming the code path during startup eliminates the deadlock ( and loadLibrary0 are single threaded). Note the JVM is at the end of initialization and the getDefault() call is safe to make. This does result in a few extra classes being loaded before the user class is touched, but this path was almost inevitably being called once the user class is invoked. > > The general problem of multithreaded class initialization and JNI library loading remains ? this patch addresses a defect that is seen out in the field (the defect contains at least 2 public cases, anecdotally I have seen others). > > This is JDK8 only ? as discussed in the defect JDK9 and beyond address this problem with a different startup sequence. > > Note that Oracle appears to have picked up this fix (or a version of it) for their 8u repo. > > Paul Hohensee (phh) has agreed to sponsor the fix. > > > From sci at amazon.com Tue Apr 23 14:47:07 2019 From: sci at amazon.com (Sciampacone, Ryan) Date: Tue, 23 Apr 2019 14:47:07 +0000 Subject: [8u-dev] RFR (S): JDK-8194653: Deadlock involving FileSystems.getDefault and System.loadLibrary call In-Reply-To: References: Message-ID: <70B49CDC-E5AD-4639-BCDA-169CF2131673@amazon.com> Alan / David, I agree this could have also been a class library only solution. Looking at the problem I saw a few things: - Just above the patched code in create_vm() there is similar code for a JSR 292 deadlock problem where classes are pre-loaded as a solution. I felt this matched the type of fix I was making here. - There is plenty of other class pre loading / initialization done in create_vm() - If there was a need to put an early switch on the pre-load of this class, I felt this be more natural to wrap that here - The problem doesn't exist at jdk9+ because the classes causing this problem get loaded and initialized as part of the initialization sequence "naturally" (ie: I see no indication that they are loaded to solve this specific problem). I agree that jdk8 is unlikely to have dramatic changes in initialization moving forward, but putting it as part of (to me) the more streamlined create_vm() function made sense from a "safety" perspective as it felt more controlled and unlikely to be perturbed by any other change in the initialization code flow (class library or vm). To follow on this last couple of points, as noted in the defect (and Brian Burkhalter also observes through running the reproducer test), this doesn't happen at jdk9+ because initialization has changed and the class got loaded "for free". The reproducer test certainly applies to 13 (it's a valid check) but you can also eyeball the classes loaded and see the effect. ?On 4/22/19, 11:42 PM, "Alan Bateman" wrote: On 22/04/2019 23:11, David Holmes wrote: > Hi Ryan, > > On 23/04/2019 7:04 am, Sciampacone, Ryan wrote: >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8194653 >> Webrev: http://cr.openjdk.java.net/~phh/8194653/webrev.00/ > > Why does this need to be pushed to the VM? Why not do the > pre-loading/initializing at the Java level? Ryan - do you have a test case that demonstrates the issue with the main line (jdk/jdk)? I think we need that in order to study this issue a bit more closely and see what options are available. I see Paul has pasted in a stack trace from January and I think it would be interesting to see what command line options were used. I don't have a good sense yet how this might be fixed but it may need work in FilePermission and/or initializing the default file system provider at a different time during the startup. -Alan From james.laskey at oracle.com Tue Apr 23 14:58:53 2019 From: james.laskey at oracle.com (Jim Laskey) Date: Tue, 23 Apr 2019 11:58:53 -0300 Subject: RFR - JDK-8212975 ClassDesc should have a full name method In-Reply-To: <1A1BEBF9-5180-4EAA-9B25-22917F3080FD@oracle.com> References: <1A1BEBF9-5180-4EAA-9B25-22917F3080FD@oracle.com> Message-ID: <1F6B40AB-D620-4DB6-93B8-474F47872CF8@oracle.com> Revision based on Joe review webrev: http://cr.openjdk.java.net/~jlaskey/8212975/webrev-03 > On Apr 22, 2019, at 3:34 PM, Jim Laskey wrote: > > ClassDesc.displayName(boolean detail) allows the user the option to fetch the fully qualified class name. > > webrev: http://cr.openjdk.java.net/~jlaskey/8212975/webrev-02 > JBS: https://bugs.openjdk.java.net/browse/JDK-8212975 > > Thank you. > > Cheers, > > - Jim > From Alan.Bateman at oracle.com Tue Apr 23 15:30:49 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 23 Apr 2019 16:30:49 +0100 Subject: [8u-dev] RFR (S): JDK-8194653: Deadlock involving FileSystems.getDefault and System.loadLibrary call In-Reply-To: <70B49CDC-E5AD-4639-BCDA-169CF2131673@amazon.com> References: <70B49CDC-E5AD-4639-BCDA-169CF2131673@amazon.com> Message-ID: On 23/04/2019 15:47, Sciampacone, Ryan wrote: > > - The problem doesn't exist at jdk9+ because the classes causing this problem get loaded and initialized as part of the initialization sequence "naturally" (ie: I see no indication that they are loaded to solve this specific problem). I agree that jdk8 is unlikely to have dramatic changes in initialization moving forward, but putting it as part of (to me) the more streamlined create_vm() function made sense from a "safety" perspective as it felt more controlled and unlikely to be perturbed by any other change in the initialization code flow (class library or vm). > True for JDK 9 but there has been significant changes since than and the file system is not eagerly loaded since JDK 10 or 11. So I think it needs further investigation to see if we have a potential issue in the main line or not. -Alan From adinn at redhat.com Tue Apr 23 16:15:01 2019 From: adinn at redhat.com (Andrew Dinn) Date: Tue, 23 Apr 2019 17:15:01 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <453045f6-0259-e098-8211-0187428adb9f@oracle.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> <9218d37f-9820-9216-b125-8f3bc2d19e3d@redhat.com> <453045f6-0259-e098-8211-0187428adb9f@oracle.com> Message-ID: Hi Alan, Thanks for looking at this. On 22/04/2019 16:52, Alan Bateman wrote: > The calculation to compute the page aligned address and then the > distance from there to the end of the region is tricky to get right. I > think you have it right, I'm just wondering if we could leverage the > existing mappingOffset/mappingAddress methods so that we have only one > place to audit. For example, suppose mappingOffset is changed to take an > index. I think this would reduce the new force method down to: > > long offset = mappingOffset(index); > force0(fd, mappingAddress(offset), offset + length); I like this idea but I'd like to make sure I am clear about exactly how it ought to work. If you will indulge me I will work through this by describing first the status quo (as I perceive it) and then what my change attempts before trying to reconcile the two. Currently: There are 4 key locations of interest in the mapped byte range [... map_base ... address ... address+limit ... address+capacity ...] | | +----- page size -----+ where: - addresses to the left are numerically (i.e. as longs) lower than those to the right - map_base is aligned to page size -- it is obtained by rounding down address to a page boundary - consequently (address - map_base) is less than page size n.b. the mmapped region may or may not commence at map_base but it will always include map_base. Also, it will include bytes at all subsequent addresses up to (address + capacity). Whether it includes or extends beyond (address + capacity) is not really important. mappingOffset() computes (address - map_base): int ps = Bits.pageSize(); long offset = address % ps; return (offset >= 0) ? offset : (ps + offset); The jiggery-pokery with ? : works round the rather unhelpful behaviour of mod wrt negative longs. I think it could, equivalently, compute it directly as: int ps = Bits.pageSize(); long map_base = (address & ~(ps - 1)); return address - map_base; mappingAddress(mappingOffset) converts a previously retrieved mappingOffset back to the map base: return (address - mappingOffset) == (address - (address - map_base)) == map_base mappingLength(mappingOffset) computes ((address + capacity) - map_base) i.e. the byte count from start of page map_base to the last (potentially) /writeable/ buffer byte. return capacity() + mappingOffset == capacity + (address - map_base) == (address + capacity) - map_base arguably this method could just compute ((address + length) - map_base) i.e. the byte count from map_base to the last /written/ byte -- but that makes no real difference when performing a file-based flush. The call to force0 is made as force0(fd, mappingAddress(offset), mappingLength(offset)) which is equivalent to force0(fd, map_base, capacity + (address - map_base)) My updated code: When looking at an indexed location there are now 7 key locations of interest in the mapped byte range [... m_base ... a ... i_base ... a+i ... a+i+ln ... a+lim, a+cap ...] | | | | +- page size -+ +- page size -+ where: - for brevity, map_base is abbreviated to m_base, address to a, index_base to i_base, index to i, length to ln, limit to lim and capacity to cap - index is identifies the start of the region to be flushed - length is the length of the region to be flushed - (address + index) is the address of the byte at offset index - index_base is the largest page aligned address below (address + idx) i.e. it is obtained by rounding down the first byte of the flush region to a page boundary index_base is computed as follows int ps = Bits.pageSize(); long index_base = ((address + index) & ~(ps - 1)); My code is calling force0(fd, index_base, length + ((address + index) - i_base)) i.e. it the flushed range starts at the nearest page boundary below or equal to (address + index) and includes the original length bytes plus the intervening bytes between that page boundary and address. When this is considered by analogy with the previous call then three things stand out: 1) in place of map_base for the first argument we have index_base 2) in place of the extra included intervening bytes between map_base and address we have the extra included intervening bytes between index_base and address + index 3) in place of capacity (default) demarcated bytes to be flushed we have length user demarcated bytes to be flushed So, to retain those parallels detailed in 1, 2 and 3 we need mappingOffset and mappingAddress to be overloaded and the originals rerouted as follows mappingOffset(index) { int ps = Bits.pageSize(); long index_address = address + index; long index_base = (index_address & ~(ps - 1)); return index_address - index_base; } mappingOffset() => mappingOffset(0) mappingAddress(mappingOffset, index) { long index_address = address + index; return index_address - mappingOffset == (index_address - (index_address - index_base)) == index_base } mappingAddress(mappingOffset) => mappingAddress(mappingOffset, 0) mappingLength(mappingOffset, length) { return length + mappingOffset } mappingLength(mappingOffset) => mappingLength(mappingOffset, (long)capacity()) Does that look correct? If so I will prepare a new webrev accordingly. > I don't expect any issues on Windows but I will test it to make sure. Thank you. That would be very helpful. regards, Andrew Dinn ----------- Senior Principal Software Engineer Red Hat UK Ltd Registered in England and Wales under Company Registration No. 03798903 Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander From jlaskey at me.com Mon Apr 22 17:41:12 2019 From: jlaskey at me.com (James Laskey) Date: Mon, 22 Apr 2019 14:41:12 -0300 Subject: RFR: 8215017: Improve String::equals warmup characteristics In-Reply-To: References: Message-ID: <94EBA909-E89B-4072-914E-4373971FD2C2@me.com> +1 > On Dec 7, 2018, at 8:11 PM, Claes Redestad wrote: > > Hi, > > following up from discussions during review of JDK-8214971[1], I > examined the startup and peak performance of a few different variant of > writing String::equals. > > Webrev: http://cr.openjdk.java.net/~redestad/8215017/jdk.00/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8215017 > > - folding coder() == aString.coder() into sameCoder(aString) helps > interpreter without adversely affecting higher optimization levels > > - Jim's proposal to use Arrays.equals is _interesting_: it improves > peak performance on some inputs but regress it on others. I'll defer > that to a future RFE as it needs a more thorough examination. > > - what we can do is simplify to only use StringLatin1.equals. If I'm not > completely mistaken these are all semantically neutral (and > StringUTF16.equals effectively redundant). If I'm completely wrong here > I'll welcome the learning opportunity. :-) > > This removes a branch and two method calls, and for UTF16 Strings we'll > use a simpler algorithm early, which turns out to be beneficial during > interpreter and C1 level. > > I added a simple microbenchmark to explore this, results show 1.2-2.5x > improvements in interpreter performance, while remaining perfectly > neutral results for optimized code on this simple micro[2]. > > This could be extended to clean up and move StringLatin1.equals back > into String and remove StringUTF16, but we'd also need to rearrange the > intrinsics on the VM side. Let me know what you think. > > Thanks! > > /Claes > > [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-December/057162.html > > [2] > ========== Baseline ================= > > -Xint > Benchmark Mode Cnt Score Error Units > StringEquals.equalsAlmostEqual avgt 4 968.640 ? 1.337 ns/op > StringEquals.equalsAlmostEqualUTF16 avgt 4 2082.007 ? 5.303 ns/op > StringEquals.equalsDifferent avgt 4 583.166 ? 29.461 ns/op > StringEquals.equalsDifferentCoders avgt 4 422.993 ? 1.291 ns/op > StringEquals.equalsEqual avgt 4 988.671 ? 1.492 ns/op > StringEquals.equalsEqualsUTF16 avgt 4 2103.060 ? 5.705 ns/op > > -XX:+CompactStrings > Benchmark Mode Cnt Score Error Units > StringEquals.equalsAlmostEqual avgt 4 23.896 ? 0.089 ns/op > StringEquals.equalsAlmostEqualUTF16 avgt 4 23.935 ? 0.562 ns/op > StringEquals.equalsDifferent avgt 4 15.086 ? 0.044 ns/op > StringEquals.equalsDifferentCoders avgt 4 12.572 ? 0.008 ns/op > StringEquals.equalsEqual avgt 4 25.143 ? 0.025 ns/op > StringEquals.equalsEqualsUTF16 avgt 4 25.148 ? 0.021 ns/op > > -XX:-CompactStrings > Benchmark Mode Cnt Score Error Units > StringEquals.equalsAlmostEqual avgt 4 24.539 ? 0.127 ns/op > StringEquals.equalsAlmostEqualUTF16 avgt 4 22.638 ? 0.047 ns/op > StringEquals.equalsDifferent avgt 4 13.930 ? 0.835 ns/op > StringEquals.equalsDifferentCoders avgt 4 13.836 ? 0.025 ns/op > StringEquals.equalsEqual avgt 4 26.420 ? 0.020 ns/op > StringEquals.equalsEqualsUTF16 avgt 4 23.889 ? 0.037 ns/op > > ========== Fix ====================== > > -Xint > Benchmark Mode Cnt Score Error Units > StringEquals.equalsAlmostEqual avgt 4 811.859 ? 8.663 ns/op > StringEquals.equalsAlmostEqualUTF16 avgt 4 802.784 ? 352.884 ns/op > StringEquals.equalsDifferent avgt 4 431.837 ? 1.884 ns/op > StringEquals.equalsDifferentCoders avgt 4 358.244 ? 1.208 ns/op > StringEquals.equalsEqual avgt 4 832.056 ? 3.541 ns/op > StringEquals.equalsEqualsUTF16 avgt 4 832.434 ? 3.516 ns/op > > -XX:+CompactStrings > Benchmark Mode Cnt Score Error Units > StringEquals.equalsAlmostEqual avgt 4 23.906 ? 0.151 ns/op > StringEquals.equalsAlmostEqualUTF16 avgt 4 23.905 ? 0.123 ns/op > StringEquals.equalsDifferent avgt 4 15.088 ? 0.023 ns/op > StringEquals.equalsDifferentCoders avgt 4 12.575 ? 0.030 ns/op > StringEquals.equalsEqual avgt 4 25.149 ? 0.059 ns/op > StringEquals.equalsEqualsUTF16 avgt 4 25.149 ? 0.033 ns/op > > -XX:-CompactStrings > Benchmark Mode Cnt Score Error Units > StringEquals.equalsAlmostEqual avgt 4 24.521 ? 0.050 ns/op > StringEquals.equalsAlmostEqualUTF16 avgt 4 22.639 ? 0.035 ns/op > StringEquals.equalsDifferent avgt 4 13.831 ? 0.020 ns/op > StringEquals.equalsDifferentCoders avgt 4 13.884 ? 0.345 ns/op > StringEquals.equalsEqual avgt 4 26.395 ? 0.066 ns/op > StringEquals.equalsEqualsUTF16 avgt 4 23.904 ? 0.112 ns/op From sci at amazon.com Tue Apr 23 21:53:07 2019 From: sci at amazon.com (Sciampacone, Ryan) Date: Tue, 23 Apr 2019 21:53:07 +0000 Subject: [8u-dev] RFR (S): JDK-8194653: Deadlock involving FileSystems.getDefault and System.loadLibrary call In-Reply-To: References: <70B49CDC-E5AD-4639-BCDA-169CF2131673@amazon.com> Message-ID: <5E71817A-F432-4DFA-BB6C-1989082FDF40@amazon.com> Agreed on the changes since JDK9. This specific problem doesn't exist in jdk/jdk because even in a (for my example, linux) product image, although FileSystems isn't touched, sun.nio.fs.UnixNativeDispatcher gets initialized as part of startup - this clears up the native library load (nio) collision that could occur through that class. This is the case we see customers experiencing. Preloading FileSystems.getDefault() in jdk8 is a mostly inert and friendly (not reaching into the bowels, letting the platform pick the right class) way of getting that problem out of the way. You can see the corresponding stack traces here that highlight the issue: http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-January/050819.html If the mainline initialization sequence is changed, could this potentially become an issue? Yes, that's possible - imo given the dependencies it is unlikely. Would this patch fix this specific issue? Yes, assuming FileSystem.getDefault() still found its way to the NativeDispatcher which loads "nio". Would adding this test case detect the issue? Yes, again assuming the above. I admit this goes after a fairly specific set of circumstances - but they are the ones that we end up seeing in jdk8. Fixing the general multi-threaded clinit / loadLibrary paths in the library is likely not worth it given what I believe would be involved. The jtreg test case in the patch works on jdk/jdk, and also fails in jdk8 until the patch is applied. All versions after 8 also pass. Does it make sense to open a JBS against the test and have it applied / backported? ?On 4/23/19, 8:31 AM, "Alan Bateman" wrote: On 23/04/2019 15:47, Sciampacone, Ryan wrote: > > - The problem doesn't exist at jdk9+ because the classes causing this problem get loaded and initialized as part of the initialization sequence "naturally" (ie: I see no indication that they are loaded to solve this specific problem). I agree that jdk8 is unlikely to have dramatic changes in initialization moving forward, but putting it as part of (to me) the more streamlined create_vm() function made sense from a "safety" perspective as it felt more controlled and unlikely to be perturbed by any other change in the initialization code flow (class library or vm). > True for JDK 9 but there has been significant changes since than and the file system is not eagerly loaded since JDK 10 or 11. So I think it needs further investigation to see if we have a potential issue in the main line or not. -Alan From david.holmes at oracle.com Tue Apr 23 22:03:39 2019 From: david.holmes at oracle.com (David Holmes) Date: Wed, 24 Apr 2019 08:03:39 +1000 Subject: [8u-dev] RFR (S): JDK-8194653: Deadlock involving FileSystems.getDefault and System.loadLibrary call In-Reply-To: <70B49CDC-E5AD-4639-BCDA-169CF2131673@amazon.com> References: <70B49CDC-E5AD-4639-BCDA-169CF2131673@amazon.com> Message-ID: Hi Ryan, First with regard to the mailing list for the RFR it is not the bug filing category that determines this (though there is usually a correlation) but the location of the files where you actually made changes. In this case, in the current form, as hotspot changes, it should have been reviewed on hotspot-runtime-dev. But I don't want this to be hotspot changes. :) On 24/04/2019 12:47 am, Sciampacone, Ryan wrote: > > Alan / David, > > I agree this could have also been a class library only solution. Looking at the problem I saw a few things: > > - Just above the patched code in create_vm() there is similar code for a JSR 292 deadlock problem where classes are pre-loaded as a solution. I felt this matched the type of fix I was making here. > - There is plenty of other class pre loading / initialization done in create_vm() The VM controls the basic bootstrapping initialization process** to get the core of the core libraries initialized in the right order so that the VM can execute the initialization code in a sane fashion. JSR-292 code is tightly connected to the VM, so are String, Class, and a bunch of others like exceptions. The FileSystem code is not part of this core and the VM doesn't need to know about it. This is a library problem that can and should be fixed in the library code. ** With the introduction of the module system a lot of this was pushed back into the Java library code itself. > - If there was a need to put an early switch on the pre-load of this class, I felt this be more natural to wrap that here Not sure what you mean by "early switch", if you mean a flag to control whether or not to do the eager-initialization then a Java property could be used for that. Though I'd argue against making this optional unless there is a significant penalty for always doing the early init - is there? Thanks, David > - The problem doesn't exist at jdk9+ because the classes causing this problem get loaded and initialized as part of the initialization sequence "naturally" (ie: I see no indication that they are loaded to solve this specific problem). I agree that jdk8 is unlikely to have dramatic changes in initialization moving forward, but putting it as part of (to me) the more streamlined create_vm() function made sense from a "safety" perspective as it felt more controlled and unlikely to be perturbed by any other change in the initialization code flow (class library or vm). > > To follow on this last couple of points, as noted in the defect (and Brian Burkhalter also observes through running the reproducer test), this doesn't happen at jdk9+ because initialization has changed and the class got loaded "for free". The reproducer test certainly applies to 13 (it's a valid check) but you can also eyeball the classes loaded and see the effect. > > ?On 4/22/19, 11:42 PM, "Alan Bateman" wrote: > > On 22/04/2019 23:11, David Holmes wrote: > > Hi Ryan, > > > > On 23/04/2019 7:04 am, Sciampacone, Ryan wrote: > >> > >> Bug: https://bugs.openjdk.java.net/browse/JDK-8194653 > >> Webrev: http://cr.openjdk.java.net/~phh/8194653/webrev.00/ > > > > Why does this need to be pushed to the VM? Why not do the > > pre-loading/initializing at the Java level? > Ryan - do you have a test case that demonstrates the issue with the main > line (jdk/jdk)? I think we need that in order to study this issue a bit > more closely and see what options are available. I see Paul has pasted > in a stack trace from January and I think it would be interesting to see > what command line options were used. I don't have a good sense yet how > this might be fixed but it may need work in FilePermission and/or > initializing the default file system provider at a different time during > the startup. > > -Alan > > From david.holmes at oracle.com Wed Apr 24 07:12:47 2019 From: david.holmes at oracle.com (David Holmes) Date: Wed, 24 Apr 2019 17:12:47 +1000 Subject: RFR(S): 8222518: Remove unnecessary caching of Parker object in java.lang.Thread Message-ID: <4d1ad4b6-95e9-e7c9-2064-4e9ff67edae8@oracle.com> Bug: https://bugs.openjdk.java.net/browse/JDK-8222518 webrev: http://cr.openjdk.java.net/~dholmes/8222518/webrev/ The original implementation of Unsafe.unpark simply extracted the JavaThread reference from the java.lang.Thread oop and if non-null extracted the Parker instance from it and invoked unpark. This was racy however as the native JavaThread could terminate at any time and deallocate the Parker. That logic was fixed by JDK-6271298 which used of combination of type-stable-memory "event" objects for the Parker, along with use of the Threads_lock to obtain the initial reference to the Parker (from a JavaThread guaranteed to be alive), together with caching the native Parker pointer in a field of java.lang.Thread. Even though the native thread may have terminated the Parker was still valid (even if associated with a different thread) and the unpark at worst was a spurious wakeup for that other thread. When JDK-8167108 introduced Thread Safe-Memory-Reclaimation (SMR) the logic was updated to always use the safe mechanism - we grab a ThreadsListHandle then check the cached field, else lookup the native thread to see if it is alive and locate the Parker instance that way. With SMR the caching of the Parker pointer no longer serves any purpose - we no longer have a lock-free use-the-cache path versus a lock-using populate-the-cache path. With SMR we've already"paid" for the ability to ensure the native thread can't terminate regardless of whether we lookup the field from the java.lang.Thread or the JavaThread. So we can simplify the code and save a little footprint by removing the cache from java.lang.Thread: /* * JVM-private state that persists after native thread termination. */ private long nativeParkEventPointer; and the supporting code from unsafe.cpp and javaClass.*pp in the JVM. I considered restoring the fast-path use of the cache without recourse to Thread-SMR but performance measurements failed to show any benefit in doing. See bug report for details. Thanks, David From xueming.shen at gmail.com Wed Apr 24 07:28:18 2019 From: xueming.shen at gmail.com (Xueming Shen) Date: Wed, 24 Apr 2019 00:28:18 -0700 Subject: RFR: 8222532: (zipfs) Performance regression when writing ZipFileSystem entries in parallel In-Reply-To: <1f20a70c-3d35-5005-12d4-d5a6853e4549@oracle.com> References: <74d67729-fbea-2b5a-a840-d7abc2067682@oracle.com> <72cb59c0-e977-d297-589f-80f7d1a417e4@oracle.com> <1f20a70c-3d35-5005-12d4-d5a6853e4549@oracle.com> Message-ID: <0420114e-f0f3-c5be-292a-ae3fcd90f0a8@gmail.com> Alan, Claes, If my memory was correct, ExChannelClose was not being used even in previous implementation. Actually it should never have been used in any of the released JDK. I might have been missing some discussions ... so I might be wrong here. But the original reason of having a exchannelcloser was that I was implementing the sync() the way that it would be invoked during its lifetime. Means you can actually fresh the in-memory entries back to underlying zipfile to reduce memory pressure ... because the fs is not really being closed in this situation, we can't just close those streams. Have to keep them alive till they get closed by the caller. But then the plan was changed and the sync() is being invoked only in its close(). In this situation, we should simply close those pending streams. The filesystem is getting closed, any inputstream open on its entry should be closed as well. No need for this closer any more in current sync() use scenario. -Sherman ExistingChannelCloser On 4/23/19 4:42 AM, Claes Redestad wrote: > Hi Alan, Christoph, > > thanks for reviewing this! > > On 2019-04-23 12:42, Alan Bateman wrote: >> On 18/04/2019 14:10, Claes Redestad wrote: >>> Webrev: http://cr.openjdk.java.net/~redestad/8222532/open.00/ >> I think the approach looks good. >> >> One thing that I think could be improved is ExChannelCloser. I think >> it needs a better name. Also I think it should encapsulate its fields >> a lot better so that sync doesn't need to access its interanls -- >> e.g. maybe it can define a closeAndDelete method that closes the >> channel and deletes the path. >> > > Based on what it does, ExChannelCloser (which I restored from its pre- > existing state) should probably be named ExistingChannelCloser. > > I've collected the feedback from you, Christoph and Lance into this > new webrev: http://cr.openjdk.java.net/~redestad/8222532/open.01/ > > Incremental: http://cr.openjdk.java.net/~redestad/8222532/open.00_01/ > > Thanks! > > /Claes From claes.redestad at oracle.com Wed Apr 24 08:19:43 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Wed, 24 Apr 2019 10:19:43 +0200 Subject: RFR: 8222532: (zipfs) Performance regression when writing ZipFileSystem entries in parallel In-Reply-To: <0420114e-f0f3-c5be-292a-ae3fcd90f0a8@gmail.com> References: <74d67729-fbea-2b5a-a840-d7abc2067682@oracle.com> <72cb59c0-e977-d297-589f-80f7d1a417e4@oracle.com> <1f20a70c-3d35-5005-12d4-d5a6853e4549@oracle.com> <0420114e-f0f3-c5be-292a-ae3fcd90f0a8@gmail.com> Message-ID: Sherman, I actually left the ExChannelCloser out as I was stepping back the changes one by one, thinking it had nothing to do with the behavior we're trying to restore here, but then I ran into some obscure test failures (IIRC some zip files not being generated as expected) - when I restored the ExChannelCloser code those tests passed. Thus I'd like to leave it as-is for this patch to keep tests happy, but I admit I don't fully understand what was going on in those tests. OK to leave it for an RFE to re-examine and remove the Ex(isting)ChannelCloser? /Claes On 2019-04-24 09:28, Xueming Shen wrote: > Alan, Claes, > > If my memory was correct, ExChannelClose was not being used even in > previous implementation. > > Actually it should never have been used in any of the released JDK. I > might have been missing some discussions ... so I might be wrong here. > But the original reason of having a exchannelcloser was > > that I was implementing the sync() the way that it would be invoked > during its lifetime. Means you > > can actually fresh the in-memory entries back to underlying zipfile to > reduce memory pressure ... > > because the fs is not really being closed in this situation, we can't > just close those streams. Have to > > keep them alive till they get closed by the caller. But then the plan > was changed and the sync() is > > being invoked only in its close(). In this situation, we should simply > close those pending streams. > > The filesystem is getting closed, any inputstream open on its entry > should be closed as well. No > > need for this closer any more in current sync() use scenario. > > -Sherman > > > > ExistingChannelCloser > > On 4/23/19 4:42 AM, Claes Redestad wrote: >> Hi Alan, Christoph, >> >> thanks for reviewing this! >> >> On 2019-04-23 12:42, Alan Bateman wrote: >>> On 18/04/2019 14:10, Claes Redestad wrote: >>>> Webrev: http://cr.openjdk.java.net/~redestad/8222532/open.00/ >>> I think the approach looks good. >>> >>> One thing that I think could be improved is ExChannelCloser. I think >>> it needs a better name. Also I think it should encapsulate its fields >>> a lot better so that sync doesn't need to access its interanls -- >>> e.g. maybe it can define a closeAndDelete method that closes the >>> channel and deletes the path. >>> >> >> Based on what it does, ExChannelCloser (which I restored from its pre- >> existing state) should probably be named ExistingChannelCloser. >> >> I've collected the feedback from you, Christoph and Lance into this >> new webrev: http://cr.openjdk.java.net/~redestad/8222532/open.01/ >> >> Incremental: http://cr.openjdk.java.net/~redestad/8222532/open.00_01/ >> >> Thanks! >> >> /Claes From frank.yuan at oracle.com Wed Apr 24 09:51:40 2019 From: frank.yuan at oracle.com (Frank Yuan) Date: Wed, 24 Apr 2019 17:51:40 +0800 Subject: VarHandle instance methods performance Message-ID: <044601d4fa83$525d4110$f717c330$@oracle.com> Hi Aleksey I happened to see the performance to access a field by VarHandle API is much worse than the native access. I tested the following situations: 1. reading a volatile field directly 2. calling getVolatile against this volatile field 3. calling getVolatile against another non-volatile field As my expectation, Situation 2 has similar performance with situation 3, but both of them have 100 times of situation 1 execution time in my test. I think it should be due to some overhead, and it doesn't violate the JEP 193 performance requirement. But I still can't figure out why it's so slow after runtime compiling? Hope you can give me some point. Thanks! My test code is as below: import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; public class Test5 { static final int iter_num = 100000000; private volatile int vf = 1; private int f = 1; final VarHandle vhf; final VarHandle vhvf; final ThreadMXBean threadMXBean; public Test5 () throws Exception { vhf = MethodHandles.lookup().findVarHandle( Test5.class, "f", int.class); vhvf = MethodHandles.lookup().findVarHandle( Test5.class, "vf", int.class); threadMXBean = ManagementFactory.getThreadMXBean(); //System.out.println(threadMXBean.isCurrentThreadCpuTimeSupported()); //System.out.println(threadMXBean.isThreadCpuTimeEnabled()); } public void measGetVolatileField() { int tmpProgress = 0; long startCpu = threadMXBean.getCurrentThreadCpuTime(); long startUser = threadMXBean.getCurrentThreadUserTime(); for (int i = 0; i < iter_num; ++i) { tmpProgress += vf; } long endCpu = threadMXBean.getCurrentThreadCpuTime(); long endUser = threadMXBean.getCurrentThreadUserTime(); long durCpu = endCpu -startCpu; long durUser = endUser - startUser; System.out.println("measGetVolatileField"); System.out.println("cpu time: " + durCpu); System.out.println("user time: " + durUser); System.out.println(tmpProgress); } public void measGetVolatileFieldByVHWithVolatile() { int tmpProgress = 0; long startCpu = threadMXBean.getCurrentThreadCpuTime(); long startUser = threadMXBean.getCurrentThreadUserTime(); for (int i = 0; i < iter_num; ++i) { tmpProgress += (int) vhvf.getVolatile(this); } long endCpu = threadMXBean.getCurrentThreadCpuTime(); long endUser = threadMXBean.getCurrentThreadUserTime(); long durCpu = endCpu -startCpu; long durUser = endUser - startUser; System.out.println("measGetVolatileFieldByVHWithVolatile"); System.out.println("cpu time: " + durCpu); System.out.println("user time: " + durUser); System.out.println(tmpProgress); } public void measGetFieldByVHWithVolatile() { int tmpProgress = 0; long startCpu = threadMXBean.getCurrentThreadCpuTime(); long startUser = threadMXBean.getCurrentThreadUserTime(); for (int i = 0; i < iter_num; ++i) { tmpProgress += (int) vhf.getVolatile(this); } long endCpu = threadMXBean.getCurrentThreadCpuTime(); long endUser = threadMXBean.getCurrentThreadUserTime(); long durCpu = endCpu -startCpu; long durUser = endUser - startUser; System.out.println("measGetFieldByVHWithVolatile"); System.out.println("cpu time: " + durCpu); System.out.println("user time: " + durUser); System.out.println(tmpProgress); } public static void main(String[] args) throws Exception { for (int i = 0; i < 5; i++) { Test5 test = new Test5 (); Thread threadA = new Thread(() -> test.measGetVolatileField()); Thread threadB = new Thread(() -> test.measGetVolatileFieldByVHWithVolatile()); Thread threadC = new Thread(() -> test.measGetFieldByVHWithVolatile()); threadA.start(); threadA.join(); threadB.start(); threadB.join(); threadC.start(); threadC.join(); } } } From shade at redhat.com Wed Apr 24 10:03:34 2019 From: shade at redhat.com (Aleksey Shipilev) Date: Wed, 24 Apr 2019 12:03:34 +0200 Subject: VarHandle instance methods performance In-Reply-To: <044601d4fa83$525d4110$f717c330$@oracle.com> References: <044601d4fa83$525d4110$f717c330$@oracle.com> Message-ID: On 4/24/19 11:51 AM, Frank Yuan wrote: > My test code is as below: > ... > final VarHandle vhf; > final VarHandle vhvf; > ... Make these two "static final", initialize them in class initializer, then try again. VarHandle (like Atomic*FieldUpdaters, MethodHandle, etc), have internal checks that can only be folded away when the VH/MH/A*FU instance is constant. -Aleksey From frank.yuan at oracle.com Wed Apr 24 10:11:11 2019 From: frank.yuan at oracle.com (Frank Yuan) Date: Wed, 24 Apr 2019 18:11:11 +0800 Subject: VarHandle instance methods performance In-Reply-To: References: <044601d4fa83$525d4110$f717c330$@oracle.com> Message-ID: <045101d4fa86$0c56be00$25043a00$@oracle.com> > On 4/24/19 11:51 AM, Frank Yuan wrote: > > My test code is as below: > > ... > > final VarHandle vhf; > > final VarHandle vhvf; > > ... > > Make these two "static final", initialize them in class initializer, then try again. > > VarHandle (like Atomic*FieldUpdaters, MethodHandle, etc), have internal checks that can only be > folded away when the VH/MH/A*FU instance is constant. > Thank you, it works! YC > -Aleksey From forax at univ-mlv.fr Wed Apr 24 10:26:24 2019 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 24 Apr 2019 12:26:24 +0200 (CEST) Subject: VarHandle instance methods performance In-Reply-To: <045101d4fa86$0c56be00$25043a00$@oracle.com> References: <044601d4fa83$525d4110$f717c330$@oracle.com> <045101d4fa86$0c56be00$25043a00$@oracle.com> Message-ID: <457020178.522781.1556101584784.JavaMail.zimbra@u-pem.fr> Hi Frank, a VarHandle is a glorified integer value that correspond to the number of bytes from a pointer to a field address, so you give it a reference and you have access to the field at the address: reference + shift, given that the shift value is the same for all the instances of the same class, it should be declared static (and final so it's a constant for the VM). R?mi ----- Mail original ----- > De: "Frank Yuan" > ?: "Aleksey Shipilev" > Cc: "core-libs-dev" > Envoy?: Mercredi 24 Avril 2019 12:11:11 > Objet: RE: VarHandle instance methods performance >> On 4/24/19 11:51 AM, Frank Yuan wrote: >> > My test code is as below: >> > ... >> > final VarHandle vhf; >> > final VarHandle vhvf; >> > ... >> >> Make these two "static final", initialize them in class initializer, then try >> again. >> >> VarHandle (like Atomic*FieldUpdaters, MethodHandle, etc), have internal checks >> that can only be >> folded away when the VH/MH/A*FU instance is constant. >> > > Thank you, it works! > > YC > > > -Aleksey From Alan.Bateman at oracle.com Wed Apr 24 11:26:54 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 24 Apr 2019 12:26:54 +0100 Subject: [8u-dev] RFR (S): JDK-8194653: Deadlock involving FileSystems.getDefault and System.loadLibrary call In-Reply-To: <5E71817A-F432-4DFA-BB6C-1989082FDF40@amazon.com> References: <70B49CDC-E5AD-4639-BCDA-169CF2131673@amazon.com> <5E71817A-F432-4DFA-BB6C-1989082FDF40@amazon.com> Message-ID: On 23/04/2019 22:53, Sciampacone, Ryan wrote: > Agreed on the changes since JDK9. > > This specific problem doesn't exist in jdk/jdk because even in a (for my example, linux) product image, although FileSystems isn't touched, sun.nio.fs.UnixNativeDispatcher gets initialized as part of startup - this clears up the native library load (nio) collision that could occur through that class. This is the case we see customers experiencing. Preloading FileSystems.getDefault() in jdk8 is a mostly inert and friendly (not reaching into the bowels, letting the platform pick the right class) way of getting that problem out of the way. > > You can see the corresponding stack traces here that highlight the issue: http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-January/050819.html > I realize you are running the issue with JDK 8 but I think we do need to investigate the main line a bit more too. You are correct that the file system is initialized early in JDK 9 but this isn't the case for JDK 10 and newer due to further work to reduce startup time. The stack traces in the bug report look like they may have been taken with an exploded build or with --patch-module, just two of several cases where it might be initialized early. I think it will be harder to demonstrate an issue with JDK 10, esp. if there are JAR files on the class path as any access to JAR files will trigger the file system to be initialized. -Alan From claes.redestad at oracle.com Wed Apr 24 12:49:13 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Wed, 24 Apr 2019 14:49:13 +0200 Subject: RFR: 8222895: StackOverflowError in custom security manager that relies on ClassSpecializer Message-ID: Hi, recent changes to the String concatenation bootstrap sequence[1] accidentally uncovered an issue introduced earlier by changing the ClassSpecializer to use Lookup.defineClass[2]. The issue with this is the introduction of a call to SM.checkPermission deep inside the ClassSpecializer code used when bootstrapping certain String concatenation expressions. When triggered, this causes a recursive bootstrap cycle and a crash with a StackOverflowError. This is related to earlier bootstrapping issues in the area[3], and would have been caught by the regression test added then if not for the fact that we've been rather successful in avoiding the use of ClassSpecializer during bootstrap of commonly used concatenation shapes. Providing a more contorted concatenation shape in the test ensures we drop into the ClassSpecializer code path where the recursive checkPermission call happens. The updated test passes before JDK-8181443, fails since, and passes with the changes proposed in this patch. Webrev: http://cr.openjdk.java.net/~redestad/8222895/open.00/ Bug: https://bugs.openjdk.java.net/browse/JDK-8222895 Testing: tier1-3 (still in-flight), local verification Thanks! /Claes [1] https://bugs.openjdk.java.net/browse/JDK-8222484 [2] https://bugs.openjdk.java.net/browse/JDK-8181443 [3] https://bugs.openjdk.java.net/browse/JDK-8155090 From vicente.romero at oracle.com Wed Apr 24 15:06:48 2019 From: vicente.romero at oracle.com (Vicente Romero) Date: Wed, 24 Apr 2019 11:06:48 -0400 Subject: RFR - JDK-8212975 ClassDesc should have a full name method In-Reply-To: <1F6B40AB-D620-4DB6-93B8-474F47872CF8@oracle.com> References: <1A1BEBF9-5180-4EAA-9B25-22917F3080FD@oracle.com> <1F6B40AB-D620-4DB6-93B8-474F47872CF8@oracle.com> Message-ID: <82cec2da-44af-3759-c905-378f35208bb5@oracle.com> looks good to me, Vicente On 4/23/19 10:58 AM, Jim Laskey wrote: > Revision based on Joe review > > webrev: http://cr.openjdk.java.net/~jlaskey/8212975/webrev-03 > >> On Apr 22, 2019, at 3:34 PM, Jim Laskey wrote: >> >> ClassDesc.displayName(boolean detail) allows the user the option to fetch the fully qualified class name. >> >> webrev: http://cr.openjdk.java.net/~jlaskey/8212975/webrev-02 >> JBS: https://bugs.openjdk.java.net/browse/JDK-8212975 >> >> Thank you. >> >> Cheers, >> >> - Jim >> From daniel.daugherty at oracle.com Wed Apr 24 15:16:17 2019 From: daniel.daugherty at oracle.com (Daniel D. Daugherty) Date: Wed, 24 Apr 2019 11:16:17 -0400 Subject: RFR(S): 8222518: Remove unnecessary caching of Parker object in java.lang.Thread In-Reply-To: <4d1ad4b6-95e9-e7c9-2064-4e9ff67edae8@oracle.com> References: <4d1ad4b6-95e9-e7c9-2064-4e9ff67edae8@oracle.com> Message-ID: <0db0ea2a-6192-0587-3cd2-41f0d718c449@oracle.com> On 4/24/19 3:12 AM, David Holmes wrote: > Bug: https://bugs.openjdk.java.net/browse/JDK-8222518 > webrev: http://cr.openjdk.java.net/~dholmes/8222518/webrev/ src/hotspot/share/classfile/javaClasses.cpp ??? L1629: ? macro(_park_blocker_offset,? k, "parkBlocker", object_signature, false); ??????? Line ends with a ';' and the previous last line did not. When the ? ? ? ? THREAD_FIELDS_DO macro is called, it is already followed by a ';': ??????? L1635: ? THREAD_FIELDS_DO(FIELD_COMPUTE_OFFSET); ??????? L1640: ? THREAD_FIELDS_DO(FIELD_SERIALIZE_OFFSET); src/hotspot/share/classfile/javaClasses.hpp ??? No comments. src/hotspot/share/prims/unsafe.cpp ??? No comments. src/java.base/share/classes/java/lang/Thread.java ??? No comments. Thumbs up.? I don't need to see another webrev if you choose to remove the ';' on L1629. Dan > > The original implementation of Unsafe.unpark simply extracted the > JavaThread reference from the java.lang.Thread oop and if non-null > extracted the Parker instance from it and invoked unpark. This was > racy however as the native JavaThread could terminate at any time and > deallocate the Parker. > > That logic was fixed by JDK-6271298 which used of combination of > type-stable-memory "event" objects for the Parker, along with use of > the Threads_lock to obtain the initial reference to the Parker (from a > JavaThread guaranteed to be alive), together with caching the native > Parker pointer in a field of java.lang.Thread. Even though the native > thread may have terminated the Parker was still valid (even if > associated with a different thread) and the unpark at worst was a > spurious wakeup for that other thread. > > When JDK-8167108 introduced Thread Safe-Memory-Reclaimation (SMR) the > logic was updated to always use the safe mechanism - we grab a > ThreadsListHandle then check the cached field, else lookup the native > thread to see if it is alive and locate the Parker instance that way. > With SMR the caching of the Parker pointer no longer serves any > purpose - we no longer have a lock-free use-the-cache path versus a > lock-using populate-the-cache path. With SMR we've already"paid" for > the ability to ensure the native thread can't terminate regardless of > whether we lookup the field from the java.lang.Thread or the > JavaThread. So we can simplify the code and save a little footprint by > removing the cache from java.lang.Thread: > > ??? /* > ???? * JVM-private state that persists after native thread termination. > ???? */ > ??? private long nativeParkEventPointer; > > and the supporting code from unsafe.cpp and javaClass.*pp in the JVM. > > I considered restoring the fast-path use of the cache without recourse > to Thread-SMR but performance measurements failed to show any benefit > in doing. See bug report for details. > > Thanks, > David From adam.farley at uk.ibm.com Wed Apr 24 16:20:43 2019 From: adam.farley at uk.ibm.com (Adam Farley8) Date: Wed, 24 Apr 2019 17:20:43 +0100 Subject: RFR: JDK-8222930: ConcurrentSkipListMapTest.clone() broken since jdk10 Message-ID: Hi All, ConcurrentSkipListMapTest.clone() produces a clone that shares the array size variable of the original, and then doubles it. So both arrays, original and clone, tell the user that each is twice as big as it actually is. The proposed fix is to simply set the clone's array size variable to null during creation. Fix and test code available. Reviews and sponsor requested. Webrev: http://cr.openjdk.java.net/~afarley/8222930.0/jdk13/webrev/ Bug: https://bugs.openjdk.java.net/browse/JDK-8222930 Best Regards Adam Farley IBM Runtimes P.S. Apparently this has been broken since JDK 10, so we should look at backporting (at least to 11 and 12) once this is in. Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From martinrb at google.com Wed Apr 24 16:41:48 2019 From: martinrb at google.com (Martin Buchholz) Date: Wed, 24 Apr 2019 09:41:48 -0700 Subject: RFR: JDK-8222930: ConcurrentSkipListMapTest.clone() broken since jdk10 In-Reply-To: References: Message-ID: Adam, Thanks for finding this. I will be your shepherd. Normally we make changes to j.u.c. via Doug's CVS. I also think we can leverage the testing infrastructure in the tck/ directory to generalize the test - we should be able to test any cloneable Map. I'll work on doing this. On Wed, Apr 24, 2019 at 9:21 AM Adam Farley8 wrote: > Hi All, > > ConcurrentSkipListMapTest.clone() produces a clone that shares the array > size variable of the original, and then doubles it. > > So both arrays, original and clone, tell the user that each is twice as > big as it actually is. > > The proposed fix is to simply set the clone's array size variable to null > during creation. > > Fix and test code available. > > Reviews and sponsor requested. > > Webrev: http://cr.openjdk.java.net/~afarley/8222930.0/jdk13/webrev/ > > Bug: https://bugs.openjdk.java.net/browse/JDK-8222930 > > Best Regards > > Adam Farley > IBM Runtimes > > P.S. Apparently this has been broken since JDK 10, so we should look at > backporting (at least to 11 and 12) once this is in. > > Unless stated otherwise above: > IBM United Kingdom Limited - Registered in England and Wales with number > 741598. > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU > From stuart.marks at oracle.com Wed Apr 24 16:59:17 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Wed, 24 Apr 2019 09:59:17 -0700 Subject: RFR: JDK-8222930: ConcurrentSkipListMapTest.clone() broken since jdk10 In-Reply-To: References: Message-ID: Hi Adam, Thanks for finding this bug! This is a bug in ConcurrentSkipListMap itself, not some test named ConcurrentSkipListMapTest. I'd suggest changing the bug summary line and the commit message accordingly. Thanks, s'marks On 4/24/19 9:20 AM, Adam Farley8 wrote: > ConcurrentSkipListMapTest.clone() produces a clone that shares the array > size variable of the original, and then doubles it. > > So both arrays, original and clone, tell the user that each is twice as > big as it actually is. > > The proposed fix is to simply set the clone's array size variable to null > during creation. > > Fix and test code available. > > Reviews and sponsor requested. > > Webrev: http://cr.openjdk.java.net/~afarley/8222930.0/jdk13/webrev/ > > Bug: https://bugs.openjdk.java.net/browse/JDK-8222930 > > Best Regards > > Adam Farley > IBM Runtimes > > P.S. Apparently this has been broken since JDK 10, so we should look at > backporting (at least to 11 and 12) once this is in. > > Unless stated otherwise above: > IBM United Kingdom Limited - Registered in England and Wales with number > 741598. > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU > From stuart.marks at oracle.com Wed Apr 24 23:48:23 2019 From: stuart.marks at oracle.com (Stuart Marks) Date: Wed, 24 Apr 2019 16:48:23 -0700 Subject: RFR(trivial): 8222394: HashMap.compute() throws CME on an empty Map if clear() called concurrently In-Reply-To: References: Message-ID: <520e1ee0-8f1c-ae46-2b45-24555c88aa05@oracle.com> Hi Patrick, I guess I'm not sure what you're proposing here. You've updated the patch; are you proposing that this change be integrated? Or are you posting code changes, not as a proposal to integrate, but merely to serve as a discussion point about the policy for throwing ConcurrentModificationException? Either way (or something else) is fine; I just don't want to run off in one direction if you had intended the other. s'marks On 4/15/19 3:51 AM, Patrick Zhang OS wrote: > Hi Stuart, > > Thanks. I intentionally modified the map in remapping functions, just like those tests in http://hg.openjdk.java.net/jdk/jdk/file/00c0906bf4d1/test/jdk/java/util/Map/FunctionalCMEs.java. My original tests were: create two threads, modify or perform read-only operations in each, and verify those CMEs. There seems some inconsistencies: > 1. clear() would modify the map completely, so it can be more 'defensible' (Martin mentioned so in Jira), while other modifying functions like put()/remove()/merge() are 'weaker', so ++modCount happens conditionally, say there would be really some structural modifications in map. > 2. compute()/computeIfAbsent() throws CME almost unconditionally, while functions like forEach()/computeIfPresent()/iterator.next() are touching the map content practically so these are wrapped by if-clauses. > > So the concern is how to undertand "throw CME on a best-effort basis", > if I want to try best to detect the risk of bugs in program, unconditionlly throwing CME can be the right way to go, e.g. do ++modCount in removeNode() without telling if the removing would really occur, > if I want to make it more logically rigorous, we might need this: http://cr.openjdk.java.net/~qpzhang/8222394/webrev.02 for compute()/computeIfAbsent(). Centainly I know it has to afford the risk of missing bugs. > > Regards > Patrick > > -----Original Message----- > From: Stuart Marks > Sent: Saturday, April 13, 2019 4:15 AM > To: Patrick Zhang OS > Cc: core-libs-dev > Subject: Re: RFR(trivial): 8222394: HashMap.compute() throws CME on an empty Map if clear() called concurrently > > [I'm about to leave for a week's vacation, so I won't be able to respond further until after I return] > > Hi Patrick, > > A bit of background about my thinking on this proposal. > > The Collections Framework has a set of weird edge cases ("tricky", as you say) that I'll describe as "state-dependent" behavior, where operations that seem illegal on their face might or might not throw an exception depending on the current state of the system. The current state potentially depends on everything that happened previously, including input to the program. > > As an example of this, consider the following code snippet: > > List list1 = Collections.emptyList(); > List list2 = getStringsFromSomewhere(); > list1.addAll(list2); > > What happens on the third line? The spec for Collections.emptyList() [1] says that the returned list is immutable. You might think, then, that addAll() will throw UnsupportedOperationException. > > What actually happens is, "it depends." > > If list2 has elements, then addAll() will throw UOE as expected. However, if > list2 happens to be empty, then addAll() returns false, because nothing was added. > > To me, the code above clearly has a bug: it's calling a mutator method on an immutable collection. The only time this doesn't throw an exception is if list2 is empty, so it can't possibly have any useful effect in this case. > Presumably getStringsFromSomewhere() will return some actual strings from time to time. If this happens rarely, we might put this code into production, and it might blow up unexpectedly when a different set of inputs causes list2 to be nonempty. > > (Aside 1: the Java 9 unmodifiable collections throw UOE unconditionally, so > List.of().addAll(List.of()) will throw UOE.) > > (Aside 2: even though it's inconsistent and arguably wrong, I don't think this behavior of emptyList() should be changed, for compatibility reasons.) > > I think you can see the analogy with HashMap.compute(). The cases from the tests essentially do this: > > var m = new HashMap(); > // possible modifications to m > m.compute(someKey, (k, v) -> { > m.clear(); > return someValue; > }); > > Looking at this code, and not knowing the state of m, it seems to me it has a bug. The spec for compute() [2] says "The remapping function should not modify this map during computation" and there's a call to clear() right there. Indeed, the current code always throws ConcurrentModificationException. > > You're proposing that it not throw CME in the case where m is empty, when > clear() has no effect. This is similar to the case above; if m is often empty, then this code appears to "work". But if the program's input were to change and m becomes non-empty, it'll throw CME unexpectedly. On the other hand, it would allow clear() in exactly the cases where it has no effect. > > Overall I don't see that the system is improved by this change. It allows a particular operation only when it has no effect (thus adding no value), and it increases the risk of bugs in programs going undetected. > > s'marks > > > [1] > https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collections.html#emptyList() > > [2] > https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Map.html#compute(K,java.util.function.BiFunction) > > > > > On 4/12/19 2:46 AM, Patrick Zhang OS wrote: >> Created a ticket to track it, welcome any comments. Thanks. >> >> JBS https://bugs.openjdk.java.net/browse/JDK-8222394 >> Webrev: http://cr.openjdk.java.net/~qpzhang/map.clear/webrev.01 >> >> Regards >> Patrick >> >> -----Original Message----- >> From: core-libs-dev On Behalf Of Patrick Zhang OS >> Sent: Saturday, March 30, 2019 1:34 PM >> To: core-libs-dev >> Subject: ConcurrentModificationException thrown by HashMap.compute() operating on an empty Map, expected/unexpected? >> >> Hi, >> Here I have a case simplified from a practical issue that throws ConcurrentModificationException (CME) unexpectedly (I think). [0] creates a HashMap, keeps it empty, and calls m.computeIfAbsent() or m.compute(), in which a "sneaky" m.clear() occurs, some of the test cases throw CME although there were no "structural" changes in fact. (A structural modification is defined as "any operation that adds or deletes one or more mappings..."). >> >> This case cannot be reproduced with jdk8u, while jdk9 and beyond can, after the bug [1] got fixed for computeIfAbsent() concurrent co-modification issues. A couple of test cases [2] were introduced at that time, and the focus was to verify the behaviors at resizing, while empty maps were not tested. >> >> A possible "fix" for this issue is to move the unconditional "modCount++" [3] into the if-clause, which indicates that a "structural" change would be happening indeed. >> >> public void clear() { >> Node[] tab; >> - modCount++; >> if ((tab = table) != null && size > 0) { >> + modCount++; >> size = 0; >> for (int i = 0; i < tab.length; ++i) >> tab[i] = null; >> } >> } >> >> Therefore, a dilemma here is "modCount++ before-if-clause but overkills some cases" vs. "modCount++ into-if-clause but weakens the CME checking potentially". I want to make balance regarding how to "throw CME on a best-effort basis" more appropriately. Any suggestion? >> >> I understand that CME here in HashMap.java cannot guarantee much and may be only for debugging purpose, any concurrent modification needs to be typically accomplished by synchronizing on some object that naturally encapsulates the map. So the mentioned issue is a just a tricky case. >> >> [0]http://cr.openjdk.java.net/~qpzhang/map.clear/webrev.01/test/jdk/java/util/concurrent/ConcurrentMap/ConcurrentModification.java.udiff.html >> [1]https://bugs.openjdk.java.net/browse/JDK-8071667 >> [2]http://hg.openjdk.java.net/jdk/jdk/file/5a9d780eb9dd/test/jdk/java/util/Map/FunctionalCMEs.java >> [3]http://hg.openjdk.java.net/jdk/jdk/file/1042cac8bc2a/src/java.base/share/classes/java/util/HashMap.java#l860 >> >> Regards >> Patrick >> From andy.herrick at oracle.com Thu Apr 25 00:44:17 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Wed, 24 Apr 2019 20:44:17 -0400 Subject: RFR: JDK-8212780: JEP 343: Packaging Tool Implementation Message-ID: <0bd5501f-9db0-f22a-c4f1-4e284a43021f@oracle.com> Please review? changes for [1] which is the implementation bug for JEP-343. The webrev at [2] is the total cumulative webrev of changes for the jpackage tool, currently in the JDK-8200758-branch branch of the open sandbox repository. The webrev at [3] shows the changes from EA-05 to EA-06. The latest EA-6 (build 49) is posted at [4]. Please send feedback to core-libs-dev at openjdk.java.net [1] https://bugs.openjdk.java.net/browse/JDK-8200758 [2] http://cr.openjdk.java.net/~herrick/8212780/webrev.05-06/ [3] http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/ [4] http://jdk.java.net/jpackage/ /Andy From andy.herrick at oracle.com Thu Apr 25 00:47:13 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Wed, 24 Apr 2019 20:47:13 -0400 Subject: RFR: JDK-8212780: JEP 343: Packaging Tool Implementation In-Reply-To: <0bd5501f-9db0-f22a-c4f1-4e284a43021f@oracle.com> References: <0bd5501f-9db0-f22a-c4f1-4e284a43021f@oracle.com> Message-ID: <3da2c640-8fad-335b-9696-69f45e1a1024@oracle.com> On 4/24/2019 8:44 PM, Andy Herrick wrote: > Please review? changes for [1] which is the implementation bug for > JEP-343. > > The webrev at [2] is the total cumulative webrev of changes for the > jpackage tool, currently in the JDK-8200758-branch branch of the open > sandbox repository. > > The webrev at [3] shows the changes from EA-05 to EA-06. sorry - the links are reversed from what is stated above. [2] is the incremental webrev since EA 05, [3] is the cumulativewebrev /Andy > > The latest EA-6 (build 49) is posted at [4]. > > Please send feedback to core-libs-dev at openjdk.java.net > > > [1] https://bugs.openjdk.java.net/browse/JDK-8200758 > > [2] http://cr.openjdk.java.net/~herrick/8212780/webrev.05-06/ > > [3] http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/ > > [4] http://jdk.java.net/jpackage/ > > > /Andy > > From patrick at os.amperecomputing.com Thu Apr 25 03:07:22 2019 From: patrick at os.amperecomputing.com (Patrick Zhang OS) Date: Thu, 25 Apr 2019 03:07:22 +0000 Subject: RFR(trivial): 8222394: HashMap.compute() throws CME on an empty Map if clear() called concurrently In-Reply-To: <520e1ee0-8f1c-ae46-2b45-24555c88aa05@oracle.com> References: <520e1ee0-8f1c-ae46-2b45-24555c88aa05@oracle.com> Message-ID: > merely to serve as a discussion point about the policy for throwing ConcurrentModificationException? Yes, for the time being, I want to see and welcome more ideas on this. It seems to me that the policy for throwing CME here is not a unified one, mostly based on experience and testing. Clear, compute, and computeIfAbsent are more special as I described. Regards Patrick -----Original Message----- From: Stuart Marks Sent: Thursday, April 25, 2019 7:48 AM To: Patrick Zhang OS Cc: core-libs-dev ; Martin Buchholz Subject: Re: RFR(trivial): 8222394: HashMap.compute() throws CME on an empty Map if clear() called concurrently Hi Patrick, I guess I'm not sure what you're proposing here. You've updated the patch; are you proposing that this change be integrated? Or are you posting code changes, not as a proposal to integrate, but merely to serve as a discussion point about the policy for throwing ConcurrentModificationException? Either way (or something else) is fine; I just don't want to run off in one direction if you had intended the other. s'marks On 4/15/19 3:51 AM, Patrick Zhang OS wrote: > Hi Stuart, > > Thanks. I intentionally modified the map in remapping functions, just like those tests in http://hg.openjdk.java.net/jdk/jdk/file/00c0906bf4d1/test/jdk/java/util/Map/FunctionalCMEs.java. My original tests were: create two threads, modify or perform read-only operations in each, and verify those CMEs. There seems some inconsistencies: > 1. clear() would modify the map completely, so it can be more 'defensible' (Martin mentioned so in Jira), while other modifying functions like put()/remove()/merge() are 'weaker', so ++modCount happens conditionally, say there would be really some structural modifications in map. > 2. compute()/computeIfAbsent() throws CME almost unconditionally, while functions like forEach()/computeIfPresent()/iterator.next() are touching the map content practically so these are wrapped by if-clauses. > > So the concern is how to undertand "throw CME on a best-effort basis", > if I want to try best to detect the risk of bugs in program, > unconditionlly throwing CME can be the right way to go, e.g. do ++modCount in removeNode() without telling if the removing would really occur, if I want to make it more logically rigorous, we might need this: http://cr.openjdk.java.net/~qpzhang/8222394/webrev.02 for compute()/computeIfAbsent(). Centainly I know it has to afford the risk of missing bugs. > > Regards > Patrick > > -----Original Message----- > From: Stuart Marks > Sent: Saturday, April 13, 2019 4:15 AM > To: Patrick Zhang OS > Cc: core-libs-dev > Subject: Re: RFR(trivial): 8222394: HashMap.compute() throws CME on an > empty Map if clear() called concurrently > > [I'm about to leave for a week's vacation, so I won't be able to > respond further until after I return] > > Hi Patrick, > > A bit of background about my thinking on this proposal. > > The Collections Framework has a set of weird edge cases ("tricky", as you say) that I'll describe as "state-dependent" behavior, where operations that seem illegal on their face might or might not throw an exception depending on the current state of the system. The current state potentially depends on everything that happened previously, including input to the program. > > As an example of this, consider the following code snippet: > > List list1 = Collections.emptyList(); > List list2 = getStringsFromSomewhere(); > list1.addAll(list2); > > What happens on the third line? The spec for Collections.emptyList() [1] says that the returned list is immutable. You might think, then, that addAll() will throw UnsupportedOperationException. > > What actually happens is, "it depends." > > If list2 has elements, then addAll() will throw UOE as expected. > However, if > list2 happens to be empty, then addAll() returns false, because nothing was added. > > To me, the code above clearly has a bug: it's calling a mutator method on an immutable collection. The only time this doesn't throw an exception is if list2 is empty, so it can't possibly have any useful effect in this case. > Presumably getStringsFromSomewhere() will return some actual strings from time to time. If this happens rarely, we might put this code into production, and it might blow up unexpectedly when a different set of inputs causes list2 to be nonempty. > > (Aside 1: the Java 9 unmodifiable collections throw UOE > unconditionally, so > List.of().addAll(List.of()) will throw UOE.) > > (Aside 2: even though it's inconsistent and arguably wrong, I don't > think this behavior of emptyList() should be changed, for > compatibility reasons.) > > I think you can see the analogy with HashMap.compute(). The cases from the tests essentially do this: > > var m = new HashMap(); > // possible modifications to m > m.compute(someKey, (k, v) -> { > m.clear(); > return someValue; > }); > > Looking at this code, and not knowing the state of m, it seems to me it has a bug. The spec for compute() [2] says "The remapping function should not modify this map during computation" and there's a call to clear() right there. Indeed, the current code always throws ConcurrentModificationException. > > You're proposing that it not throw CME in the case where m is empty, > when > clear() has no effect. This is similar to the case above; if m is often empty, then this code appears to "work". But if the program's input were to change and m becomes non-empty, it'll throw CME unexpectedly. On the other hand, it would allow clear() in exactly the cases where it has no effect. > > Overall I don't see that the system is improved by this change. It allows a particular operation only when it has no effect (thus adding no value), and it increases the risk of bugs in programs going undetected. > > s'marks > > > [1] > https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util > /Collections.html#emptyList() > > [2] > https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util > /Map.html#compute(K,java.util.function.BiFunction) > > > > > On 4/12/19 2:46 AM, Patrick Zhang OS wrote: >> Created a ticket to track it, welcome any comments. Thanks. >> >> JBS https://bugs.openjdk.java.net/browse/JDK-8222394 >> Webrev: http://cr.openjdk.java.net/~qpzhang/map.clear/webrev.01 >> >> Regards >> Patrick >> >> -----Original Message----- >> From: core-libs-dev On >> Behalf Of Patrick Zhang OS >> Sent: Saturday, March 30, 2019 1:34 PM >> To: core-libs-dev >> Subject: ConcurrentModificationException thrown by HashMap.compute() operating on an empty Map, expected/unexpected? >> >> Hi, >> Here I have a case simplified from a practical issue that throws ConcurrentModificationException (CME) unexpectedly (I think). [0] creates a HashMap, keeps it empty, and calls m.computeIfAbsent() or m.compute(), in which a "sneaky" m.clear() occurs, some of the test cases throw CME although there were no "structural" changes in fact. (A structural modification is defined as "any operation that adds or deletes one or more mappings..."). >> >> This case cannot be reproduced with jdk8u, while jdk9 and beyond can, after the bug [1] got fixed for computeIfAbsent() concurrent co-modification issues. A couple of test cases [2] were introduced at that time, and the focus was to verify the behaviors at resizing, while empty maps were not tested. >> >> A possible "fix" for this issue is to move the unconditional "modCount++" [3] into the if-clause, which indicates that a "structural" change would be happening indeed. >> >> public void clear() { >> Node[] tab; >> - modCount++; >> if ((tab = table) != null && size > 0) { >> + modCount++; >> size = 0; >> for (int i = 0; i < tab.length; ++i) >> tab[i] = null; >> } >> } >> >> Therefore, a dilemma here is "modCount++ before-if-clause but overkills some cases" vs. "modCount++ into-if-clause but weakens the CME checking potentially". I want to make balance regarding how to "throw CME on a best-effort basis" more appropriately. Any suggestion? >> >> I understand that CME here in HashMap.java cannot guarantee much and may be only for debugging purpose, any concurrent modification needs to be typically accomplished by synchronizing on some object that naturally encapsulates the map. So the mentioned issue is a just a tricky case. >> >> [0]http://cr.openjdk.java.net/~qpzhang/map.clear/webrev.01/test/jdk/j >> ava/util/concurrent/ConcurrentMap/ConcurrentModification.java.udiff.h >> tml >> [1]https://bugs.openjdk.java.net/browse/JDK-8071667 >> [2]http://hg.openjdk.java.net/jdk/jdk/file/5a9d780eb9dd/test/jdk/java >> /util/Map/FunctionalCMEs.java >> [3]http://hg.openjdk.java.net/jdk/jdk/file/1042cac8bc2a/src/java.base >> /share/classes/java/util/HashMap.java#l860 >> >> Regards >> Patrick >> From frank.yuan at oracle.com Thu Apr 25 05:32:14 2019 From: frank.yuan at oracle.com (Frank Yuan) Date: Thu, 25 Apr 2019 13:32:14 +0800 Subject: VarHandle instance methods performance In-Reply-To: <457020178.522781.1556101584784.JavaMail.zimbra@u-pem.fr> References: <044601d4fa83$525d4110$f717c330$@oracle.com> <045101d4fa86$0c56be00$25043a00$@oracle.com> <457020178.522781.1556101584784.JavaMail.zimbra@u-pem.fr> Message-ID: <061201d4fb28$3f38d5e0$bdaa81a0$@oracle.com> > > Hi Frank, > a VarHandle is a glorified integer value that correspond to the number of bytes from a pointer to a field address, > so you give it a reference and you have access to the field at the address: reference + shift, given that the shift value is the same for all the > instances of the same class, I know, but I thought they were ready once the VarHandle instance was constructed... Actually, I was looking up some way to improve library performance by VarHandle API. For example, CopyOnWriteArrayList uses a volatile variable referring to Object[] array, the writing procedure updates the volatile variable once it makes a new array completely, and then the reading procedure can read the new array by the volatile variable. Here, I think in theory, we can replace the volatile reading by getOpaque, which only requires the program does read the variable from the memory. But the actual performance of getOpaque is not better than volatile reading due to the overhead(with using static VH instance), I have to hold on my idea now. Thanks YC > it should be declared static (and final so it's a constant for the VM). > > R?mi > > ----- Mail original ----- > > De: "Frank Yuan" > > ?: "Aleksey Shipilev" > > Cc: "core-libs-dev" > > Envoy?: Mercredi 24 Avril 2019 12:11:11 > > Objet: RE: VarHandle instance methods performance > > >> On 4/24/19 11:51 AM, Frank Yuan wrote: > >> > My test code is as below: > >> > ... > >> > final VarHandle vhf; > >> > final VarHandle vhvf; > >> > ... > >> > >> Make these two "static final", initialize them in class initializer, then try > >> again. > >> > >> VarHandle (like Atomic*FieldUpdaters, MethodHandle, etc), have internal checks > >> that can only be > >> folded away when the VH/MH/A*FU instance is constant. > >> > > > > Thank you, it works! > > > > YC > > > > > -Aleksey From ivan.gerasimov at oracle.com Thu Apr 25 06:00:29 2019 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 24 Apr 2019 23:00:29 -0700 Subject: RFR 8222955 : Optimize String.replace(CharSequence, CharSequence) for Latin1 encoded strings Message-ID: Hello! This enhancement was inspired by a recent discussion at compiler-dev at openjdk.java.net. It seems to be a non-uncommon situation when String.replace(CS, CS) is called with this and both arguments being Latin1 strings, so it seems reasonable to optimize for such case. Here are the fresh benchmark results (see the webrev for the source of the benchmark): -- prior the fix: Benchmark Mode Cnt Score Error Units StringReplace.replace1_0 avgt 24 70.860 ? 5.239 ns/op StringReplace.replace1_1 avgt 24 82.661 ? 1.007 ns/op StringReplace.replace1_2 avgt 24 97.251 ? 1.186 ns/op -- after the fix: Benchmark Mode Cnt Score Error Units StringReplace.replace1_0 avgt 24 52.855 ? 0.982 ns/op StringReplace.replace1_1 avgt 24 23.849 ? 0.066 ns/op StringReplace.replace1_2 avgt 24 62.266 ? 0.552 ns/op So the speedup was x1.3, x3.4, x1.5. Would you please help review the fix? BUGURL: https://bugs.openjdk.java.net/browse/JDK-8222955 WEBREV: http://cr.openjdk.java.net/~igerasim/8222955/00/webrev/ Mach5 job is in progress and looks green so far (a few test groups are left). Thanks in advance! -- With kind regards, Ivan Gerasimov From martinrb at google.com Thu Apr 25 06:13:11 2019 From: martinrb at google.com (Martin Buchholz) Date: Wed, 24 Apr 2019 23:13:11 -0700 Subject: VarHandle instance methods performance In-Reply-To: <061201d4fb28$3f38d5e0$bdaa81a0$@oracle.com> References: <044601d4fa83$525d4110$f717c330$@oracle.com> <045101d4fa86$0c56be00$25043a00$@oracle.com> <457020178.522781.1556101584784.JavaMail.zimbra@u-pem.fr> <061201d4fb28$3f38d5e0$bdaa81a0$@oracle.com> Message-ID: There's a good chance COWAL access to the array can be optimized as you suggest using VarHandles. Write using release; read using acquire, or plain if holding the lock. Doesn't buy much on x86 but performance improvement should be measurable on ppc. On Wed, Apr 24, 2019 at 10:33 PM Frank Yuan wrote: > > > > Hi Frank, > > a VarHandle is a glorified integer value that correspond to the number > of bytes from a pointer to a field address, > > so you give it a reference and you have access to the field at the > address: reference + shift, given that the shift value is the same for all > the > > instances of the same class, > > I know, but I thought they were ready once the VarHandle instance was > constructed... > > Actually, I was looking up some way to improve library performance by > VarHandle API. > For example, CopyOnWriteArrayList uses a volatile variable referring to > Object[] array, the writing procedure updates the volatile variable once it > makes a new array completely, and then the reading procedure can read the > new array by the volatile variable. Here, I think in theory, we can replace > the volatile reading by getOpaque, which only requires the program does > read the variable from the memory. > > But the actual performance of getOpaque is not better than volatile > reading due to the overhead(with using static VH instance), I have to hold > on my idea now. > > Thanks > YC > > > > it should be declared static (and final so it's a constant for the VM). > > > > R?mi > > > > ----- Mail original ----- > > > De: "Frank Yuan" > > > ?: "Aleksey Shipilev" > > > Cc: "core-libs-dev" > > > Envoy?: Mercredi 24 Avril 2019 12:11:11 > > > Objet: RE: VarHandle instance methods performance > > > > >> On 4/24/19 11:51 AM, Frank Yuan wrote: > > >> > My test code is as below: > > >> > ... > > >> > final VarHandle vhf; > > >> > final VarHandle vhvf; > > >> > ... > > >> > > >> Make these two "static final", initialize them in class initializer, > then try > > >> again. > > >> > > >> VarHandle (like Atomic*FieldUpdaters, MethodHandle, etc), have > internal checks > > >> that can only be > > >> folded away when the VH/MH/A*FU instance is constant. > > >> > > > > > > Thank you, it works! > > > > > > YC > > > > > > > -Aleksey > > From sergei.tsypanov at yandex.ru Thu Apr 25 07:40:17 2019 From: sergei.tsypanov at yandex.ru (=?utf-8?B?0KHQtdGA0LPQtdC5INCm0YvQv9Cw0L3QvtCy?=) Date: Thu, 25 Apr 2019 09:40:17 +0200 Subject: RFR 8222955 : Optimize String.replace(CharSequence, CharSequence) for Latin1 encoded strings In-Reply-To: References: Message-ID: <39713831556178017@iva8-582db1f60497.qloud-c.yandex.net> Hi Ivan, recently looking into java.lang.String I've found out that String::split still uses old collection-to-array approach: String[] result = new String[resultSize]; return list.subList(0, resultSize).toArray(result); which should be replaced with return list.subList(0, resultSize).toArray(new String[0]); this changes is too small to create a separate ticket for this, so could I ask you to add this into your changes? Regards, Sergei Tsypanov 25.04.2019, 08:04, "Ivan Gerasimov" : > Hello! > > This enhancement was inspired by a recent discussion at > compiler-dev at openjdk.java.net. > > It seems to be a non-uncommon situation when String.replace(CS, CS) is > called with this and both arguments being Latin1 strings, so it seems > reasonable to optimize for such case. > > Here are the fresh benchmark results (see the webrev for the source of > the benchmark): > -- prior the fix: > Benchmark Mode Cnt Score Error Units > StringReplace.replace1_0 avgt 24 70.860 ? 5.239 ns/op > StringReplace.replace1_1 avgt 24 82.661 ? 1.007 ns/op > StringReplace.replace1_2 avgt 24 97.251 ? 1.186 ns/op > > -- after the fix: > Benchmark Mode Cnt Score Error Units > StringReplace.replace1_0 avgt 24 52.855 ? 0.982 ns/op > StringReplace.replace1_1 avgt 24 23.849 ? 0.066 ns/op > StringReplace.replace1_2 avgt 24 62.266 ? 0.552 ns/op > > So the speedup was x1.3, x3.4, x1.5. > > Would you please help review the fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8222955 > WEBREV: http://cr.openjdk.java.net/~igerasim/8222955/00/webrev/ > > Mach5 job is in progress and looks green so far (a few test groups are > left). > > Thanks in advance! > > -- > With kind regards, > Ivan Gerasimov From robbin.ehn at oracle.com Thu Apr 25 07:53:56 2019 From: robbin.ehn at oracle.com (Robbin Ehn) Date: Thu, 25 Apr 2019 09:53:56 +0200 Subject: RFR(S): 8222518: Remove unnecessary caching of Parker object in java.lang.Thread In-Reply-To: <4d1ad4b6-95e9-e7c9-2064-4e9ff67edae8@oracle.com> References: <4d1ad4b6-95e9-e7c9-2064-4e9ff67edae8@oracle.com> Message-ID: <9b063a96-1859-6280-7412-75d54c1a1fb6@oracle.com> Hi David, Looks good. Just a question: It seems like we could just hold the ThreadsList over p->unpark() and not rely on TSM ? Not sure in how many places we do rely on it, but it would be nice to remove TSM for parkers. The exiting thread would set parker to NULL before removing itself from the threadslist and free it when it's off. Thanks, Robbin On 4/24/19 9:12 AM, David Holmes wrote: > Bug: https://bugs.openjdk.java.net/browse/JDK-8222518 > webrev: http://cr.openjdk.java.net/~dholmes/8222518/webrev/ > > The original implementation of Unsafe.unpark simply extracted the JavaThread > reference from the java.lang.Thread oop and if non-null extracted the Parker > instance from it and invoked unpark. This was racy however as the native > JavaThread could terminate at any time and deallocate the Parker. > > That logic was fixed by JDK-6271298 which used of combination of > type-stable-memory "event" objects for the Parker, along with use of the > Threads_lock to obtain the initial reference to the Parker (from a JavaThread > guaranteed to be alive), together with caching the native Parker pointer in a > field of java.lang.Thread. Even though the native thread may have terminated the > Parker was still valid (even if associated with a different thread) and the > unpark at worst was a spurious wakeup for that other thread. > > When JDK-8167108 introduced Thread Safe-Memory-Reclaimation (SMR) the logic was > updated to always use the safe mechanism - we grab a ThreadsListHandle then > check the cached field, else lookup the native thread to see if it is alive and > locate the Parker instance that way. > With SMR the caching of the Parker pointer no longer serves any purpose - we no > longer have a lock-free use-the-cache path versus a lock-using > populate-the-cache path. With SMR we've already"paid" for the ability to ensure > the native thread can't terminate regardless of whether we lookup the field from > the java.lang.Thread or the JavaThread. So we can simplify the code and save a > little footprint by removing the cache from java.lang.Thread: > > ??? /* > ???? * JVM-private state that persists after native thread termination. > ???? */ > ??? private long nativeParkEventPointer; > > and the supporting code from unsafe.cpp and javaClass.*pp in the JVM. > > I considered restoring the fast-path use of the cache without recourse to > Thread-SMR but performance measurements failed to show any benefit in doing. See > bug report for details. > > Thanks, > David From ivan.gerasimov at oracle.com Thu Apr 25 09:24:41 2019 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Thu, 25 Apr 2019 02:24:41 -0700 Subject: RFR 8222955 : Optimize String.replace(CharSequence, CharSequence) for Latin1 encoded strings In-Reply-To: <39713831556178017@iva8-582db1f60497.qloud-c.yandex.net> References: <39713831556178017@iva8-582db1f60497.qloud-c.yandex.net> Message-ID: Hi Sergei! Thanks for sharing. However, it's not immediately obvious to me why the later is better than the former. Can you please elaborate on that? I think, it worth a separate discussion. With kind regards, Ivan On 4/25/19 12:40 AM, ?????? ??????? wrote: > Hi Ivan, > > recently looking into java.lang.String I've found out that String::split still uses old collection-to-array approach: > > String[] result = new String[resultSize]; > return list.subList(0, resultSize).toArray(result); > > which should be replaced with > > return list.subList(0, resultSize).toArray(new String[0]); > > this changes is too small to create a separate ticket for this, so could I ask you to add this into your changes? > > Regards, > Sergei Tsypanov > > > 25.04.2019, 08:04, "Ivan Gerasimov" : >> Hello! >> >> This enhancement was inspired by a recent discussion at >> compiler-dev at openjdk.java.net. >> >> It seems to be a non-uncommon situation when String.replace(CS, CS) is >> called with this and both arguments being Latin1 strings, so it seems >> reasonable to optimize for such case. >> >> Here are the fresh benchmark results (see the webrev for the source of >> the benchmark): >> -- prior the fix: >> Benchmark Mode Cnt Score Error Units >> StringReplace.replace1_0 avgt 24 70.860 ? 5.239 ns/op >> StringReplace.replace1_1 avgt 24 82.661 ? 1.007 ns/op >> StringReplace.replace1_2 avgt 24 97.251 ? 1.186 ns/op >> >> -- after the fix: >> Benchmark Mode Cnt Score Error Units >> StringReplace.replace1_0 avgt 24 52.855 ? 0.982 ns/op >> StringReplace.replace1_1 avgt 24 23.849 ? 0.066 ns/op >> StringReplace.replace1_2 avgt 24 62.266 ? 0.552 ns/op >> >> So the speedup was x1.3, x3.4, x1.5. >> >> Would you please help review the fix? >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8222955 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8222955/00/webrev/ >> >> Mach5 job is in progress and looks green so far (a few test groups are >> left). >> >> Thanks in advance! >> >> -- >> With kind regards, >> Ivan Gerasimov -- With kind regards, Ivan Gerasimov From frank.yuan at oracle.com Thu Apr 25 10:17:39 2019 From: frank.yuan at oracle.com (Frank Yuan) Date: Thu, 25 Apr 2019 18:17:39 +0800 Subject: VarHandle instance methods performance In-Reply-To: References: <044601d4fa83$525d4110$f717c330$@oracle.com> <045101d4fa86$0c56be00$25043a00$@oracle.com> <457020178.522781.1556101584784.JavaMail.zimbra@u-pem.fr> <061201d4fb28$3f38d5e0$bdaa81a0$@oracle.com> Message-ID: <06be01d4fb50$1e646b40$5b2d41c0$@oracle.com> Hi Martin There's a good chance COWAL access to the array can be optimized as you suggest using VarHandles. Write using release; read using acquire, or plain if holding the lock. I am not very sure, setRelease only ensures the ordering or has the effect that update the writing data to the memory immediately? If it only ensures the ordering, we may still need to volatile writing for this case CopyOnWriteArrayList? Doesn't buy much on x86 but performance improvement should be measurable on ppc. Oh, I realized there is no memory barrier for my volatile reading code on x86. Anyway there is performance benefit if we replace volatile writing with setRelease or releaseFence on x86. I would look for the scenarios in the library. We expect some potential performance benefit from keeping minimal memory access constraint in theory, but because the overhead of MethodHandle we may not take VarHandle api in some cases for the performance. Thanks YC On Wed, Apr 24, 2019 at 10:33 PM Frank Yuan > wrote: > > Hi Frank, > a VarHandle is a glorified integer value that correspond to the number of bytes from a pointer to a field address, > so you give it a reference and you have access to the field at the address: reference + shift, given that the shift value is the same for all the > instances of the same class, I know, but I thought they were ready once the VarHandle instance was constructed... Actually, I was looking up some way to improve library performance by VarHandle API. For example, CopyOnWriteArrayList uses a volatile variable referring to Object[] array, the writing procedure updates the volatile variable once it makes a new array completely, and then the reading procedure can read the new array by the volatile variable. Here, I think in theory, we can replace the volatile reading by getOpaque, which only requires the program does read the variable from the memory. But the actual performance of getOpaque is not better than volatile reading due to the overhead(with using static VH instance), I have to hold on my idea now. Thanks YC > it should be declared static (and final so it's a constant for the VM). > > R?mi > > ----- Mail original ----- > > De: "Frank Yuan" > > > ?: "Aleksey Shipilev" > > > Cc: "core-libs-dev" > > > Envoy?: Mercredi 24 Avril 2019 12:11:11 > > Objet: RE: VarHandle instance methods performance > > >> On 4/24/19 11:51 AM, Frank Yuan wrote: > >> > My test code is as below: > >> > ... > >> > final VarHandle vhf; > >> > final VarHandle vhvf; > >> > ... > >> > >> Make these two "static final", initialize them in class initializer, then try > >> again. > >> > >> VarHandle (like Atomic*FieldUpdaters, MethodHandle, etc), have internal checks > >> that can only be > >> folded away when the VH/MH/A*FU instance is constant. > >> > > > > Thank you, it works! > > > > YC > > > > > -Aleksey From claes.redestad at oracle.com Thu Apr 25 11:51:54 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 25 Apr 2019 13:51:54 +0200 Subject: RFR 8222955 : Optimize String.replace(CharSequence, CharSequence) for Latin1 encoded strings In-Reply-To: References: Message-ID: Hi Ivan, the changes and fast-path speed-ups look reasonable, but I'd like to see that the overhead for cases not helped by the fast paths isn't excessive, e.g., micro variants with UTF16 Strings and a mix of Latin1 and UTF16. /Claes On 2019-04-25 08:00, Ivan Gerasimov wrote: > Hello! > > This enhancement was inspired by a recent discussion at > compiler-dev at openjdk.java.net. > > It seems to be a non-uncommon situation when String.replace(CS, CS) is > called with this and both arguments being Latin1 strings, so it seems > reasonable to optimize for such case. > > Here are the fresh benchmark results (see the webrev for the source of > the benchmark): > -- prior the fix: > Benchmark???????????????? Mode? Cnt?? Score?? Error? Units > StringReplace.replace1_0? avgt?? 24? 70.860 ? 5.239? ns/op > StringReplace.replace1_1? avgt?? 24? 82.661 ? 1.007? ns/op > StringReplace.replace1_2? avgt?? 24? 97.251 ? 1.186? ns/op > > -- after the fix: > Benchmark???????????????? Mode? Cnt?? Score?? Error? Units > StringReplace.replace1_0? avgt?? 24? 52.855 ? 0.982? ns/op > StringReplace.replace1_1? avgt?? 24? 23.849 ? 0.066? ns/op > StringReplace.replace1_2? avgt?? 24? 62.266 ? 0.552? ns/op > > So the speedup was x1.3, x3.4, x1.5. > > Would you please help review the fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8222955 > WEBREV: http://cr.openjdk.java.net/~igerasim/8222955/00/webrev/ > > Mach5 job is in progress and looks green so far (a few test groups are > left). > > Thanks in advance! > From sergei.tsypanov at yandex.ru Thu Apr 25 12:14:32 2019 From: sergei.tsypanov at yandex.ru (=?utf-8?B?0KHQtdGA0LPQtdC5INCm0YvQv9Cw0L3QvtCy?=) Date: Thu, 25 Apr 2019 14:14:32 +0200 Subject: RFR 8222955 : Optimize String.replace(CharSequence, CharSequence) for Latin1 encoded strings In-Reply-To: References: <39713831556178017@iva8-582db1f60497.qloud-c.yandex.net> Message-ID: <6017521556194472@myt3-c7e5d17fe013.qloud-c.yandex.net> My assumption is based on conclusions drawn from this article: https://shipilev.net/blog/2016/arrays-wisdom-ancients/ I don't think the situation has changed much since then. However, I'll do separate benchmarking with the latest JDK just in case. 25.04.2019, 11:24, "Ivan Gerasimov" : > Hi Sergei! > > Thanks for sharing. > > However, it's not immediately obvious to me why the later is better than > the former. Can you please elaborate on that? > > I think, it worth a separate discussion. > > With kind regards, > > Ivan > > On 4/25/19 12:40 AM, ?????? ??????? wrote: >> ?Hi Ivan, >> >> ?recently looking into java.lang.String I've found out that String::split still uses old collection-to-array approach: >> >> ?String[] result = new String[resultSize]; >> ?return list.subList(0, resultSize).toArray(result); >> >> ?which should be replaced with >> >> ?return list.subList(0, resultSize).toArray(new String[0]); >> >> ?this changes is too small to create a separate ticket for this, so could I ask you to add this into your changes? >> >> ?Regards, >> ?Sergei Tsypanov >> >> ?25.04.2019, 08:04, "Ivan Gerasimov" : >>> ?Hello! >>> >>> ?This enhancement was inspired by a recent discussion at >>> ?compiler-dev at openjdk.java.net. >>> >>> ?It seems to be a non-uncommon situation when String.replace(CS, CS) is >>> ?called with this and both arguments being Latin1 strings, so it seems >>> ?reasonable to optimize for such case. >>> >>> ?Here are the fresh benchmark results (see the webrev for the source of >>> ?the benchmark): >>> ?-- prior the fix: >>> ?Benchmark Mode Cnt Score Error Units >>> ?StringReplace.replace1_0 avgt 24 70.860 ? 5.239 ns/op >>> ?StringReplace.replace1_1 avgt 24 82.661 ? 1.007 ns/op >>> ?StringReplace.replace1_2 avgt 24 97.251 ? 1.186 ns/op >>> >>> ?-- after the fix: >>> ?Benchmark Mode Cnt Score Error Units >>> ?StringReplace.replace1_0 avgt 24 52.855 ? 0.982 ns/op >>> ?StringReplace.replace1_1 avgt 24 23.849 ? 0.066 ns/op >>> ?StringReplace.replace1_2 avgt 24 62.266 ? 0.552 ns/op >>> >>> ?So the speedup was x1.3, x3.4, x1.5. >>> >>> ?Would you please help review the fix? >>> >>> ?BUGURL: https://bugs.openjdk.java.net/browse/JDK-8222955 >>> ?WEBREV: http://cr.openjdk.java.net/~igerasim/8222955/00/webrev/ >>> >>> ?Mach5 job is in progress and looks green so far (a few test groups are >>> ?left). >>> >>> ?Thanks in advance! >>> >>> ?-- >>> ?With kind regards, >>> ?Ivan Gerasimov > > -- > With kind regards, > Ivan Gerasimov From claes.redestad at oracle.com Thu Apr 25 12:20:16 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 25 Apr 2019 14:20:16 +0200 Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: <05526f62-727a-6b53-b15f-a8df3a1cb688@redhat.com> References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> <05526f62-727a-6b53-b15f-a8df3a1cb688@redhat.com> Message-ID: <2fd250ee-8711-75ec-0418-3caeeb1a0983@oracle.com> Hi, sorry for the delay, got distracted by other things. Switch back: http://cr.openjdk.java.net/~redestad/8222852/open.01/ Passed a sanity tier1 run. /Claes On 2019-04-23 13:27, Aleksey Shipilev wrote: > I'd keep the switch in the second loop, like this: > > for (RecipeElement el : recipe.getElements()) { > switch (el.getTag()) { > case TAG_ARG: > ... > break; > case TAG_CONST: > // Constants are already handled in the code above. > break; > default: > throw new StringConcatException("Unhandled tag: " + el.getTag()); > } > } From adam.farley at uk.ibm.com Thu Apr 25 12:47:11 2019 From: adam.farley at uk.ibm.com (Adam Farley8) Date: Thu, 25 Apr 2019 13:47:11 +0100 Subject: RFR: JDK-8222930: ConcurrentSkipListMapTest.clone() broken since jdk10 In-Reply-To: References: Message-ID: Hi Stuart, Whoops, typo. Thanks for catching that. Ditto for Martin, who has modified the bug. :) Best Regards Adam Farley IBM Runtimes Stuart Marks wrote on 24/04/2019 17:59:17: > From: Stuart Marks > To: Adam Farley8 > Cc: Java Core Libs > Date: 24/04/2019 17:59 > Subject: Re: RFR: JDK-8222930: ConcurrentSkipListMapTest.clone() > broken since jdk10 > > Hi Adam, > > Thanks for finding this bug! > > This is a bug in ConcurrentSkipListMap itself, not some test named > ConcurrentSkipListMapTest. I'd suggest changing the bug summary line and the > commit message accordingly. > > Thanks, > > s'marks > > On 4/24/19 9:20 AM, Adam Farley8 wrote: > > ConcurrentSkipListMapTest.clone() produces a clone that shares the array > > size variable of the original, and then doubles it. > > > > So both arrays, original and clone, tell the user that each is twice as > > big as it actually is. > > > > The proposed fix is to simply set the clone's array size variable to null > > during creation. > > > > Fix and test code available. > > > > Reviews and sponsor requested. > > > > Webrev: https://urldefense.proofpoint.com/v2/url? > u=http-3A__cr.openjdk.java.net_-7Eafarley_8222930. > 0_jdk13_webrev_&d=DwICaQ&c=jf_iaSHvJObTbx-siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=9_BHLxc2OwO4OJABunATso0Ej3_keQ0c5uQJZ4AwSfk&s=0gBgd8gUhNlM26eNWxBbpnIAsFJPwnOtsmT6qH72NPM&e= > > > > Bug: https://urldefense.proofpoint.com/v2/url? > u=https-3A__bugs.openjdk.java.net_browse_JDK-2D8222930&d=DwICaQ&c=jf_iaSHvJObTbx- > siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=9_BHLxc2OwO4OJABunATso0Ej3_keQ0c5uQJZ4AwSfk&s=vNk7C72hr8FqiYLJEVvCR69vlhPuT7zSIAiJ9Tl91JQ&e= > > > > Best Regards > > > > Adam Farley > > IBM Runtimes > > > > P.S. Apparently this has been broken since JDK 10, so we should look at > > backporting (at least to 11 and 12) once this is in. > > > > Unless stated otherwise above: > > IBM United Kingdom Limited - Registered in England and Wales with number > > 741598. > > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU > > > Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From Roger.Riggs at oracle.com Thu Apr 25 13:07:04 2019 From: Roger.Riggs at oracle.com (Roger Riggs) Date: Thu, 25 Apr 2019 09:07:04 -0400 Subject: VarHandle instance methods performance In-Reply-To: <044601d4fa83$525d4110$f717c330$@oracle.com> References: <044601d4fa83$525d4110$f717c330$@oracle.com> Message-ID: <59715067-cbb8-61da-f422-b1be98d06652@oracle.com> Hi Frank, These performance measurements would be good to add as JMH tests in open/test/micro... Thanks, Roger On 04/24/2019 05:51 AM, Frank Yuan wrote: > Hi Aleksey > > I happened to see the performance to access a field by VarHandle API is much worse than the native access. > > I tested the following situations: > 1. reading a volatile field directly > 2. calling getVolatile against this volatile field > 3. calling getVolatile against another non-volatile field > > As my expectation, Situation 2 has similar performance with situation 3, but both of them have 100 times of situation 1 execution time in my test. > > I think it should be due to some overhead, and it doesn't violate the JEP 193 performance requirement. But I still can't figure out why it's so slow after runtime compiling? Hope you can give me some point. Thanks! > > > My test code is as below: > > import java.lang.invoke.MethodHandles; > import java.lang.invoke.VarHandle; > import java.lang.management.ManagementFactory; > import java.lang.management.ThreadMXBean; > > public class Test5 { > > static final int iter_num = 100000000; > private volatile int vf = 1; > private int f = 1; > final VarHandle vhf; > final VarHandle vhvf; > final ThreadMXBean threadMXBean; > > public Test5 () throws Exception { > vhf = MethodHandles.lookup().findVarHandle( > Test5.class, "f", int.class); > vhvf = MethodHandles.lookup().findVarHandle( > Test5.class, "vf", int.class); > > threadMXBean = ManagementFactory.getThreadMXBean(); > > //System.out.println(threadMXBean.isCurrentThreadCpuTimeSupported()); > //System.out.println(threadMXBean.isThreadCpuTimeEnabled()); > } > > > public void measGetVolatileField() { > int tmpProgress = 0; > long startCpu = threadMXBean.getCurrentThreadCpuTime(); > long startUser = threadMXBean.getCurrentThreadUserTime(); > for (int i = 0; i < iter_num; ++i) { > tmpProgress += vf; > } > > long endCpu = threadMXBean.getCurrentThreadCpuTime(); > long endUser = threadMXBean.getCurrentThreadUserTime(); > > long durCpu = endCpu -startCpu; > long durUser = endUser - startUser; > System.out.println("measGetVolatileField"); > System.out.println("cpu time: " + durCpu); > System.out.println("user time: " + durUser); > System.out.println(tmpProgress); > } > > > public void measGetVolatileFieldByVHWithVolatile() { > int tmpProgress = 0; > long startCpu = threadMXBean.getCurrentThreadCpuTime(); > long startUser = threadMXBean.getCurrentThreadUserTime(); > for (int i = 0; i < iter_num; ++i) { > tmpProgress += (int) vhvf.getVolatile(this); > } > > long endCpu = threadMXBean.getCurrentThreadCpuTime(); > long endUser = threadMXBean.getCurrentThreadUserTime(); > > long durCpu = endCpu -startCpu; > long durUser = endUser - startUser; > System.out.println("measGetVolatileFieldByVHWithVolatile"); > System.out.println("cpu time: " + durCpu); > System.out.println("user time: " + durUser); > System.out.println(tmpProgress); > } > > > public void measGetFieldByVHWithVolatile() { > int tmpProgress = 0; > long startCpu = threadMXBean.getCurrentThreadCpuTime(); > long startUser = threadMXBean.getCurrentThreadUserTime(); > for (int i = 0; i < iter_num; ++i) { > tmpProgress += (int) vhf.getVolatile(this); > } > > long endCpu = threadMXBean.getCurrentThreadCpuTime(); > long endUser = threadMXBean.getCurrentThreadUserTime(); > > long durCpu = endCpu -startCpu; > long durUser = endUser - startUser; > System.out.println("measGetFieldByVHWithVolatile"); > System.out.println("cpu time: " + durCpu); > System.out.println("user time: " + durUser); > System.out.println(tmpProgress); > } > > public static void main(String[] args) throws Exception { > > for (int i = 0; i < 5; i++) { > Test5 test = new Test5 (); > > > Thread threadA = new Thread(() -> test.measGetVolatileField()); > Thread threadB = new Thread(() -> test.measGetVolatileFieldByVHWithVolatile()); > Thread threadC = new Thread(() -> test.measGetFieldByVHWithVolatile()); > > threadA.start(); > threadA.join(); > > threadB.start(); > threadB.join(); > > threadC.start(); > threadC.join(); > > } > > } > > } > > From christoph.langer at sap.com Thu Apr 25 13:19:54 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Thu, 25 Apr 2019 13:19:54 +0000 Subject: RFR: 8222440: (zipfs) JarFileSystem does not correctly handle versioned entries if no root entry is present In-Reply-To: References: <7C9075D6-69B2-4A8E-A748-CA61537B4710@oracle.com> Message-ID: Hi Lance, thanks for the review. I checked again whether I would remove an important test path for testing the ability to create mr jars with the jar tool. But I see this is tested for instance in test/jdk/java/util/jar/JarFile/mrjar and probably in other places as well. So I?ll push my change as is after running some further tests. Thanks Christoph From: Lance Andersen Sent: Dienstag, 23. April 2019 12:49 To: Langer, Christoph Cc: core-libs-dev at openjdk.java.net Subject: Re: RFR: 8222440: (zipfs) JarFileSystem does not correctly handle versioned entries if no root entry is present Hi Christoph On Apr 23, 2019, at 5:37 AM, Langer, Christoph > wrote: Hi Lance, Overall, I think the changes look good. Thanks for looking at this. Was there a reason that you did not leave the multi-release 9 test as is when you added the 10 test? Well, since I wanted to use this test as blueprint to provoke the jarfs issue, I had a closer look to it. I thought it's nicer if the structure of the jar file to test could be defined in the code rather than by directory trees checked into mercurial. But if you think, it's not a good idea to refacture this, I can also leave it untouched. I could alternatively add my test as a net new testcase. Thank you for the follow up. No the restructure of the test and getting rid of the directory tree and just building the jar within the test is good I also thought already, that I'd hereby remove a test path for the jar tool to create multi release jars... wanted to check if that's tested somewhere else still. So what do you (or others) say which way I should go? As far as removing the jar file, I would think that would still want to be done. I understand why you did this, not sure what the standard is here as most tests try to do clean up Hm, I thought, the jar file is so small that it wouldn't be ok to leave it in scratch and have jtreg do the cleanup. I'll check if I can come up with something that would take the retain policy of jtreg into account? I do not have a strong preference either way. In the past, I have been suggested to clean up anything created. I agree it can be handy if it these types of things remain after a failure I think you are good to go. Best Lance Best regards Christoph [cid:image001.gif at 01D4FB7A.550DD9E0] 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 adinn at redhat.com Thu Apr 25 16:34:31 2019 From: adinn at redhat.com (Andrew Dinn) Date: Thu, 25 Apr 2019 17:34:31 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> <9218d37f-9820-9216-b125-8f3bc2d19e3d@redhat.com> <453045f6-0259-e098-8211-0187428adb9f@oracle.com> Message-ID: <40cb2223-6d5a-4262-6293-2f187f578735@redhat.com> Also, here is a new webrev including the updated implementations for mappingAddress/Offset/Length as described below JIRA: https://bugs.openjdk.java.net/browse/JDK-8221696 webrev: http://cr.openjdk.java.net/~adinn/8221696/webrev.02 regards, Andrew Dinn ----------- On 23/04/2019 17:15, Andrew Dinn wrote: > Hi Alan, > > Thanks for looking at this. > > On 22/04/2019 16:52, Alan Bateman wrote: >> The calculation to compute the page aligned address and then the >> distance from there to the end of the region is tricky to get right. I >> think you have it right, I'm just wondering if we could leverage the >> existing mappingOffset/mappingAddress methods so that we have only one >> place to audit. For example, suppose mappingOffset is changed to take an >> index. I think this would reduce the new force method down to: >> >> long offset = mappingOffset(index); >> force0(fd, mappingAddress(offset), offset + length); > > I like this idea but I'd like to make sure I am clear about exactly how > it ought to work. If you will indulge me I will work through this by > describing first the status quo (as I perceive it) and then what my > change attempts before trying to reconcile the two. > > Currently: > > There are 4 key locations of interest in the mapped byte range > > [... map_base ... address ... address+limit ... address+capacity ...] > | | > +----- page size -----+ > > where: > - addresses to the left are numerically (i.e. as longs) lower than > those to the right > - map_base is aligned to page size -- it is obtained by rounding down > address to a page boundary > - consequently (address - map_base) is less than page size > > n.b. the mmapped region may or may not commence at map_base but it will > always include map_base. Also, it will include bytes at all subsequent > addresses up to (address + capacity). Whether it includes or extends > beyond (address + capacity) is not really important. > > mappingOffset() computes (address - map_base): > > int ps = Bits.pageSize(); > long offset = address % ps; > return (offset >= 0) ? offset : (ps + offset); > > The jiggery-pokery with ? : works round the rather unhelpful behaviour > of mod wrt negative longs. > > I think it could, equivalently, compute it directly as: > > int ps = Bits.pageSize(); > long map_base = (address & ~(ps - 1)); > return address - map_base; > > mappingAddress(mappingOffset) converts a previously retrieved > mappingOffset back to the map base: > > return (address - mappingOffset) > == (address - (address - map_base)) > == map_base > > > mappingLength(mappingOffset) computes ((address + capacity) - map_base) > i.e. the byte count from start of page map_base to the last > (potentially) /writeable/ buffer byte. > > return capacity() + mappingOffset > == capacity + (address - map_base) > == (address + capacity) - map_base > > arguably this method could just compute ((address + length) - map_base) > i.e. the byte count from map_base to the last /written/ byte -- but that > makes no real difference when performing a file-based flush. > > The call to force0 is made as > > force0(fd, mappingAddress(offset), mappingLength(offset)) > > which is equivalent to > > force0(fd, map_base, capacity + (address - map_base)) > > > My updated code: > > When looking at an indexed location there are now 7 key locations of > interest in the mapped byte range > > [... m_base ... a ... i_base ... a+i ... a+i+ln ... a+lim, a+cap ...] > | | | | > +- page size -+ +- page size -+ > > > where: > - for brevity, map_base is abbreviated to m_base, address to a, > index_base to i_base, index to i, length to ln, limit to lim > and capacity to cap > - index is identifies the start of the region to be flushed > - length is the length of the region to be flushed > - (address + index) is the address of the byte at offset index > - index_base is the largest page aligned address below (address + idx) > i.e. it is obtained by rounding down the first byte of the flush > region to a page boundary > > index_base is computed as follows > > int ps = Bits.pageSize(); > long index_base = ((address + index) & ~(ps - 1)); > > My code is calling > > force0(fd, index_base, length + ((address + index) - i_base)) > > i.e. it the flushed range starts at the nearest page boundary below or > equal to (address + index) and includes the original length bytes plus > the intervening bytes between that page boundary and address. > > When this is considered by analogy with the previous call then three > things stand out: > > 1) in place of map_base for the first argument we have index_base > 2) in place of the extra included intervening bytes between map_base > and address we have the extra included intervening bytes between > index_base and address + index > 3) in place of capacity (default) demarcated bytes to be flushed we > have length user demarcated bytes to be flushed > > So, to retain those parallels detailed in 1, 2 and 3 we need > mappingOffset and mappingAddress to be overloaded and the originals > rerouted as follows > > mappingOffset(index) > { > int ps = Bits.pageSize(); > long index_address = address + index; > long index_base = (index_address & ~(ps - 1)); > return index_address - index_base; > } > > mappingOffset() => mappingOffset(0) > > mappingAddress(mappingOffset, index) > { > long index_address = address + index; > return index_address - mappingOffset > == (index_address - (index_address - index_base)) > == index_base > } > > mappingAddress(mappingOffset) => mappingAddress(mappingOffset, 0) > > mappingLength(mappingOffset, length) > { > return length + mappingOffset > } > > mappingLength(mappingOffset) => > mappingLength(mappingOffset, (long)capacity()) > > Does that look correct? If so I will prepare a new webrev accordingly. > >> I don't expect any issues on Windows but I will test it to make sure. > Thank you. That would be very helpful. > > regards, > > > Andrew Dinn > ----------- > Senior Principal Software Engineer > Red Hat UK Ltd > Registered in England and Wales under Company Registration No. 03798903 > Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander > From lance.andersen at oracle.com Thu Apr 25 18:51:05 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 25 Apr 2019 14:51:05 -0400 Subject: RFR(JDK 13/java.xml) 8222743: Xerces 2.12.0: DOM Implementation In-Reply-To: <5CBA2D67.9000805@oracle.com> References: <5CBA2D67.9000805@oracle.com> Message-ID: <2038C43D-BD88-4024-8418-07323CFF3BE9@oracle.com> Hi Joe, Sorry for the delay but took a while to go through :-) I think your changes look good overall > On Apr 19, 2019, at 4:19 PM, Joe Wang wrote: > > Please review an update to xerces/dom. Details are as described in the JBS. XML related tests and JCK passed. > > JBS: https://bugs.openjdk.java.net/browse/JDK-8222743 > webrev: http://cr.openjdk.java.net/~joehw/jdk13/8222743/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 Thu Apr 25 19:37:45 2019 From: huizhe.wang at oracle.com (Joe Wang) Date: Thu, 25 Apr 2019 12:37:45 -0700 Subject: RFR(JDK 13/java.xml) 8222743: Xerces 2.12.0: DOM Implementation In-Reply-To: <2038C43D-BD88-4024-8418-07323CFF3BE9@oracle.com> References: <5CBA2D67.9000805@oracle.com> <2038C43D-BD88-4024-8418-07323CFF3BE9@oracle.com> Message-ID: <5CC20C89.5010109@oracle.com> Hi Lance, No problem. Thanks for reviewing the patch in between your busy schedules! Best, Joe On 4/25/19, 11:51 AM, Lance Andersen wrote: > Hi Joe, > > Sorry for the delay but took a while to go through :-) > > I think your changes look good overall > > >> On Apr 19, 2019, at 4:19 PM, Joe Wang > > wrote: >> >> Please review an update to xerces/dom. Details are as described in >> the JBS. XML related tests and JCK passed. >> >> JBS: https://bugs.openjdk.java.net/browse/JDK-8222743 >> webrev: http://cr.openjdk.java.net/~joehw/jdk13/8222743/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 philip.race at oracle.com Thu Apr 25 20:32:27 2019 From: philip.race at oracle.com (Philip Race) Date: Thu, 25 Apr 2019 13:32:27 -0700 Subject: [OpenJDK 2D-Dev] RFR: 8130266: Change the mechanism by which JDK loads the platform-specific GraphicsEnvironment class In-Reply-To: <5CC2190C.50609@oracle.com> References: <2923a8bb-bf80-d9c0-3150-d4fe05cada60@oracle.com> <5CC2190C.50609@oracle.com> Message-ID: <5CC2195B.2060008@oracle.com> And the complete CSR link is this : https://bugs.openjdk.java.net/browse/JDK-8222990 On 4/25/19, 1:31 PM, Philip Race wrote: > Sorry, meant to include core-libs on this ! > > -phil. > > On 4/25/19, 1:12 PM, Phil Race wrote: >> Bug: https://bugs.openjdk.java.net/browse/JDK-8130266 >> CSR: https://bugs.openjdk.java.net/browse/JDK- >> Webrev: http://cr.openjdk.java.net/~prr/8130266/ >> >> Please review this fix + the CSR which eliminates the >> java.awt.graphicenv System property. >> >> To replace it we have platform-specific classes which can then more >> easily embed >> platform-specific logic. For example, logic in >> java.awt.GraphicsEnvironment was >> then moved down into this class. Also isInAquaSession used on Mac was >> moved >> into that class from the Mac Toolkit class. >> >> A reference to the property in J2D Bench - just used to log / >> document the testing environment >> was removed along with similar references to two other properties >> removed in earlier fixes. >> >> This has been built + tested on Mac, Linux + Windows in headful mode >> and also >> specifying headless via -Djava.awt.headless and by letting it default >> to headless >> in an ssh session on Mac + by unsetting the DISPLAY variable on Linux. >> >> -phil. From philip.race at oracle.com Thu Apr 25 20:31:08 2019 From: philip.race at oracle.com (Philip Race) Date: Thu, 25 Apr 2019 13:31:08 -0700 Subject: [OpenJDK 2D-Dev] RFR: 8130266: Change the mechanism by which JDK loads the platform-specific GraphicsEnvironment class In-Reply-To: <2923a8bb-bf80-d9c0-3150-d4fe05cada60@oracle.com> References: <2923a8bb-bf80-d9c0-3150-d4fe05cada60@oracle.com> Message-ID: <5CC2190C.50609@oracle.com> Sorry, meant to include core-libs on this ! -phil. On 4/25/19, 1:12 PM, Phil Race wrote: > Bug: https://bugs.openjdk.java.net/browse/JDK-8130266 > CSR: https://bugs.openjdk.java.net/browse/JDK- > Webrev: http://cr.openjdk.java.net/~prr/8130266/ > > Please review this fix + the CSR which eliminates the > java.awt.graphicenv System property. > > To replace it we have platform-specific classes which can then more > easily embed > platform-specific logic. For example, logic in > java.awt.GraphicsEnvironment was > then moved down into this class. Also isInAquaSession used on Mac was > moved > into that class from the Mac Toolkit class. > > A reference to the property in J2D Bench - just used to log / document > the testing environment > was removed along with similar references to two other properties > removed in earlier fixes. > > This has been built + tested on Mac, Linux + Windows in headful mode > and also > specifying headless via -Djava.awt.headless and by letting it default > to headless > in an ssh session on Mac + by unsetting the DISPLAY variable on Linux. > > -phil. From mark.reinhold at oracle.com Thu Apr 25 21:20:30 2019 From: mark.reinhold at oracle.com (mark.reinhold at oracle.com) Date: Thu, 25 Apr 2019 14:20:30 -0700 (PDT) Subject: New candidate JEP: 353: Reimplement the Legacy Socket API Message-ID: <20190425212030.8CA2B288376@eggemoggin.niobe.net> https://openjdk.java.net/jeps/353 - Mark From naoto.sato at oracle.com Thu Apr 25 22:09:35 2019 From: naoto.sato at oracle.com (naoto.sato at oracle.com) Date: Thu, 25 Apr 2019 15:09:35 -0700 Subject: [13] RFR: 8222980: Upgrade IANA Language Subtag Registry to Version 2019-04-03 Message-ID: <2773ad1f-3df4-775a-7cee-4b7b42898748@oracle.com> Hello, Please review the changes to the following issue: https://bugs.openjdk.java.net/browse/JDK-8222980 The proposed changeset is located at: http://cr.openjdk.java.net/~naoto/8222980/webrev.00/ It is simply replacing the subtag registry file with the most up-to-date one, along with test case changes. Naoto From brian.burkhalter at oracle.com Thu Apr 25 22:56:02 2019 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Thu, 25 Apr 2019 15:56:02 -0700 Subject: [13] RFR: 8222980: Upgrade IANA Language Subtag Registry to Version 2019-04-03 In-Reply-To: <2773ad1f-3df4-775a-7cee-4b7b42898748@oracle.com> References: <2773ad1f-3df4-775a-7cee-4b7b42898748@oracle.com> Message-ID: Hi Naoto, On the surface this looks fine to me although I am not familiar with this area. Brian > On Apr 25, 2019, at 3:09 PM, naoto.sato at oracle.com wrote: > > Hello, > > Please review the changes to the following issue: > > https://bugs.openjdk.java.net/browse/JDK-8222980 > > The proposed changeset is located at: > > http://cr.openjdk.java.net/~naoto/8222980/webrev.00/ > > It is simply replacing the subtag registry file with the most up-to-date one, along with test case changes. > > Naoto From lance.andersen at oracle.com Fri Apr 26 00:52:01 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 25 Apr 2019 20:52:01 -0400 Subject: [13] RFR: 8222980: Upgrade IANA Language Subtag Registry to Version 2019-04-03 In-Reply-To: <2773ad1f-3df4-775a-7cee-4b7b42898748@oracle.com> References: <2773ad1f-3df4-775a-7cee-4b7b42898748@oracle.com> Message-ID: <79DB37EF-2128-46FA-8510-0B3EE1D20906@oracle.com> +1 > On Apr 25, 2019, at 6:09 PM, naoto.sato at oracle.com wrote: > > Hello, > > Please review the changes to the following issue: > > https://bugs.openjdk.java.net/browse/JDK-8222980 > > The proposed changeset is located at: > > http://cr.openjdk.java.net/~naoto/8222980/webrev.00/ > > It is simply replacing the subtag registry file with the most up-to-date one, along with test case changes. > > Naoto 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 brian.burkhalter at oracle.com Fri Apr 26 01:20:31 2019 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Thu, 25 Apr 2019 18:20:31 -0700 Subject: 8218280: LineNumberReader throws "Mark invalid" exception if CRLF straddles buffer. Message-ID: <45FE4FDA-9037-4713-8F06-005ADE9F7A62@oracle.com> For issue [1] please review the patch [2]. The source change merely changes mark() to use a read ahead limit one value larger than the parameter if the most recently read character is a ?\r? (carriage return). In this case if the next character in the stream is a ?\n? (line feed), the next read() would actually consume two characters instead of one. The incremented read ahead limit compensates for this. The two sub-tests of the test both fail without the implementation change and succeed with it. Thanks, Brian [1] https://bugs.openjdk.java.net/browse/JDK-8218280 [2] http://cr.openjdk.java.net/~bpb/8218280/webrev.00/ From david.holmes at oracle.com Fri Apr 26 04:57:57 2019 From: david.holmes at oracle.com (David Holmes) Date: Fri, 26 Apr 2019 14:57:57 +1000 Subject: RFR(S): 8222518: Remove unnecessary caching of Parker object in java.lang.Thread In-Reply-To: <0db0ea2a-6192-0587-3cd2-41f0d718c449@oracle.com> References: <4d1ad4b6-95e9-e7c9-2064-4e9ff67edae8@oracle.com> <0db0ea2a-6192-0587-3cd2-41f0d718c449@oracle.com> Message-ID: <0d902766-235d-66ae-a69e-966d9da1548f@oracle.com> Thanks Dan! Extraneous ; culled. David On 25/04/2019 1:16 am, Daniel D. Daugherty wrote: > On 4/24/19 3:12 AM, David Holmes wrote: >> Bug: https://bugs.openjdk.java.net/browse/JDK-8222518 >> webrev: http://cr.openjdk.java.net/~dholmes/8222518/webrev/ > > src/hotspot/share/classfile/javaClasses.cpp > ??? L1629: ? macro(_park_blocker_offset,? k, "parkBlocker", > object_signature, false); > ??????? Line ends with a ';' and the previous last line did not. When the > ? ? ? ? THREAD_FIELDS_DO macro is called, it is already followed by a ';': > > ??????? L1635: ? THREAD_FIELDS_DO(FIELD_COMPUTE_OFFSET); > ??????? L1640: ? THREAD_FIELDS_DO(FIELD_SERIALIZE_OFFSET); > > src/hotspot/share/classfile/javaClasses.hpp > ??? No comments. > > src/hotspot/share/prims/unsafe.cpp > ??? No comments. > > src/java.base/share/classes/java/lang/Thread.java > ??? No comments. > > Thumbs up.? I don't need to see another webrev if you choose to remove > the ';' on L1629. > > Dan > >> >> The original implementation of Unsafe.unpark simply extracted the >> JavaThread reference from the java.lang.Thread oop and if non-null >> extracted the Parker instance from it and invoked unpark. This was >> racy however as the native JavaThread could terminate at any time and >> deallocate the Parker. >> >> That logic was fixed by JDK-6271298 which used of combination of >> type-stable-memory "event" objects for the Parker, along with use of >> the Threads_lock to obtain the initial reference to the Parker (from a >> JavaThread guaranteed to be alive), together with caching the native >> Parker pointer in a field of java.lang.Thread. Even though the native >> thread may have terminated the Parker was still valid (even if >> associated with a different thread) and the unpark at worst was a >> spurious wakeup for that other thread. >> >> When JDK-8167108 introduced Thread Safe-Memory-Reclaimation (SMR) the >> logic was updated to always use the safe mechanism - we grab a >> ThreadsListHandle then check the cached field, else lookup the native >> thread to see if it is alive and locate the Parker instance that way. >> With SMR the caching of the Parker pointer no longer serves any >> purpose - we no longer have a lock-free use-the-cache path versus a >> lock-using populate-the-cache path. With SMR we've already"paid" for >> the ability to ensure the native thread can't terminate regardless of >> whether we lookup the field from the java.lang.Thread or the >> JavaThread. So we can simplify the code and save a little footprint by >> removing the cache from java.lang.Thread: >> >> ??? /* >> ???? * JVM-private state that persists after native thread termination. >> ???? */ >> ??? private long nativeParkEventPointer; >> >> and the supporting code from unsafe.cpp and javaClass.*pp in the JVM. >> >> I considered restoring the fast-path use of the cache without recourse >> to Thread-SMR but performance measurements failed to show any benefit >> in doing. See bug report for details. >> >> Thanks, >> David > From david.holmes at oracle.com Fri Apr 26 05:30:08 2019 From: david.holmes at oracle.com (David Holmes) Date: Fri, 26 Apr 2019 15:30:08 +1000 Subject: RFR(S): 8222518: Remove unnecessary caching of Parker object in java.lang.Thread In-Reply-To: <9b063a96-1859-6280-7412-75d54c1a1fb6@oracle.com> References: <4d1ad4b6-95e9-e7c9-2064-4e9ff67edae8@oracle.com> <9b063a96-1859-6280-7412-75d54c1a1fb6@oracle.com> Message-ID: Hi Robbin, On 25/04/2019 5:53 pm, Robbin Ehn wrote: > Hi David, > > Looks good. Thanks for the review. > Just a question: > It seems like we could just hold the ThreadsList over p->unpark() and > not rely on TSM ? Yes now it is done this way we could do the unpark while holding the TLH and avoid relying on TSM. > Not sure in how many places we do rely on it, but it would be nice to > remove TSM for parkers. TSM for Parkers was introduced by JDK-6271298 (there's a typo in the comment in park.hpp that transposes the last 2 numbers of the bug) so I think this is the only usage that relies on it. > The exiting thread would set parker to NULL before removing itself from > the threadslist and free it when it's off. I don't think we need that complexity. It should suffice change: JavaThread::~JavaThread() { // JSR166 -- return the parker to the free list Parker::Release(_parker); _parker = NULL; to do "delete _parker" instead. I'll file a RFE for that. Thanks, David > Thanks, Robbin > > On 4/24/19 9:12 AM, David Holmes wrote: >> Bug: https://bugs.openjdk.java.net/browse/JDK-8222518 >> webrev: http://cr.openjdk.java.net/~dholmes/8222518/webrev/ >> >> The original implementation of Unsafe.unpark simply extracted the >> JavaThread reference from the java.lang.Thread oop and if non-null >> extracted the Parker instance from it and invoked unpark. This was >> racy however as the native JavaThread could terminate at any time and >> deallocate the Parker. >> >> That logic was fixed by JDK-6271298 which used of combination of >> type-stable-memory "event" objects for the Parker, along with use of >> the Threads_lock to obtain the initial reference to the Parker (from a >> JavaThread guaranteed to be alive), together with caching the native >> Parker pointer in a field of java.lang.Thread. Even though the native >> thread may have terminated the Parker was still valid (even if >> associated with a different thread) and the unpark at worst was a >> spurious wakeup for that other thread. >> >> When JDK-8167108 introduced Thread Safe-Memory-Reclaimation (SMR) the >> logic was updated to always use the safe mechanism - we grab a >> ThreadsListHandle then check the cached field, else lookup the native >> thread to see if it is alive and locate the Parker instance that way. >> With SMR the caching of the Parker pointer no longer serves any >> purpose - we no longer have a lock-free use-the-cache path versus a >> lock-using populate-the-cache path. With SMR we've already"paid" for >> the ability to ensure the native thread can't terminate regardless of >> whether we lookup the field from the java.lang.Thread or the >> JavaThread. So we can simplify the code and save a little footprint by >> removing the cache from java.lang.Thread: >> >> ???? /* >> ????? * JVM-private state that persists after native thread termination. >> ????? */ >> ???? private long nativeParkEventPointer; >> >> and the supporting code from unsafe.cpp and javaClass.*pp in the JVM. >> >> I considered restoring the fast-path use of the cache without recourse >> to Thread-SMR but performance measurements failed to show any benefit >> in doing. See bug report for details. >> >> Thanks, >> David From david.holmes at oracle.com Fri Apr 26 05:32:17 2019 From: david.holmes at oracle.com (David Holmes) Date: Fri, 26 Apr 2019 15:32:17 +1000 Subject: RFR(S): 8222518: Remove unnecessary caching of Parker object in java.lang.Thread In-Reply-To: <0d902766-235d-66ae-a69e-966d9da1548f@oracle.com> References: <4d1ad4b6-95e9-e7c9-2064-4e9ff67edae8@oracle.com> <0db0ea2a-6192-0587-3cd2-41f0d718c449@oracle.com> <0d902766-235d-66ae-a69e-966d9da1548f@oracle.com> Message-ID: I pushed this today based on Dan and Robbin's reviews, but realized just after the act that I should have waited for any feedback from core-libs - apologies about that. If there are concerns I will roll it back. Thanks, David ----- On 26/04/2019 2:57 pm, David Holmes wrote: > Thanks Dan! Extraneous ; culled. > > David > > On 25/04/2019 1:16 am, Daniel D. Daugherty wrote: >> On 4/24/19 3:12 AM, David Holmes wrote: >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8222518 >>> webrev: http://cr.openjdk.java.net/~dholmes/8222518/webrev/ >> >> src/hotspot/share/classfile/javaClasses.cpp >> ???? L1629: ? macro(_park_blocker_offset,? k, "parkBlocker", >> object_signature, false); >> ???????? Line ends with a ';' and the previous last line did not. When >> the >> ?? ? ? ? THREAD_FIELDS_DO macro is called, it is already followed by a >> ';': >> >> ???????? L1635: ? THREAD_FIELDS_DO(FIELD_COMPUTE_OFFSET); >> ???????? L1640: ? THREAD_FIELDS_DO(FIELD_SERIALIZE_OFFSET); >> >> src/hotspot/share/classfile/javaClasses.hpp >> ???? No comments. >> >> src/hotspot/share/prims/unsafe.cpp >> ???? No comments. >> >> src/java.base/share/classes/java/lang/Thread.java >> ???? No comments. >> >> Thumbs up.? I don't need to see another webrev if you choose to remove >> the ';' on L1629. >> >> Dan >> >>> >>> The original implementation of Unsafe.unpark simply extracted the >>> JavaThread reference from the java.lang.Thread oop and if non-null >>> extracted the Parker instance from it and invoked unpark. This was >>> racy however as the native JavaThread could terminate at any time and >>> deallocate the Parker. >>> >>> That logic was fixed by JDK-6271298 which used of combination of >>> type-stable-memory "event" objects for the Parker, along with use of >>> the Threads_lock to obtain the initial reference to the Parker (from >>> a JavaThread guaranteed to be alive), together with caching the >>> native Parker pointer in a field of java.lang.Thread. Even though the >>> native thread may have terminated the Parker was still valid (even if >>> associated with a different thread) and the unpark at worst was a >>> spurious wakeup for that other thread. >>> >>> When JDK-8167108 introduced Thread Safe-Memory-Reclaimation (SMR) the >>> logic was updated to always use the safe mechanism - we grab a >>> ThreadsListHandle then check the cached field, else lookup the native >>> thread to see if it is alive and locate the Parker instance that way. >>> With SMR the caching of the Parker pointer no longer serves any >>> purpose - we no longer have a lock-free use-the-cache path versus a >>> lock-using populate-the-cache path. With SMR we've already"paid" for >>> the ability to ensure the native thread can't terminate regardless of >>> whether we lookup the field from the java.lang.Thread or the >>> JavaThread. So we can simplify the code and save a little footprint >>> by removing the cache from java.lang.Thread: >>> >>> ??? /* >>> ???? * JVM-private state that persists after native thread termination. >>> ???? */ >>> ??? private long nativeParkEventPointer; >>> >>> and the supporting code from unsafe.cpp and javaClass.*pp in the JVM. >>> >>> I considered restoring the fast-path use of the cache without >>> recourse to Thread-SMR but performance measurements failed to show >>> any benefit in doing. See bug report for details. >>> >>> Thanks, >>> David >> From Sergey.Bylokhov at oracle.com Fri Apr 26 06:22:15 2019 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Thu, 25 Apr 2019 23:22:15 -0700 Subject: [OpenJDK 2D-Dev] RFR: 8130266: Change the mechanism by which JDK loads the platform-specific GraphicsEnvironment class In-Reply-To: <5CC2190C.50609@oracle.com> References: <2923a8bb-bf80-d9c0-3150-d4fe05cada60@oracle.com> <5CC2190C.50609@oracle.com> Message-ID: <889dc961-acf5-c75a-e215-c498b587c396@oracle.com> Looks fine. On 25/04/2019 13:31, Philip Race wrote: > Sorry, meant to include core-libs on this ! > > -phil. > > On 4/25/19, 1:12 PM, Phil Race wrote: >> Bug: https://bugs.openjdk.java.net/browse/JDK-8130266 >> CSR: https://bugs.openjdk.java.net/browse/JDK- >> Webrev: http://cr.openjdk.java.net/~prr/8130266/ >> >> Please review this fix + the CSR which eliminates the java.awt.graphicenv System property. >> >> To replace it we have platform-specific classes which can then more easily embed >> platform-specific logic. For example, logic in java.awt.GraphicsEnvironment was >> then moved down into this class. Also isInAquaSession used on Mac was moved >> into that class from the Mac Toolkit class. >> >> A reference to the property in J2D Bench - just used to log / document the testing environment >> was removed along with similar references to two other properties removed in earlier fixes. >> >> This has been built + tested on Mac, Linux + Windows in headful mode and also >> specifying headless via -Djava.awt.headless and by letting it default to headless >> in an ssh session on Mac + by unsetting the DISPLAY variable on Linux. >> >> -phil. -- Best regards, Sergey. From robbin.ehn at oracle.com Fri Apr 26 08:14:30 2019 From: robbin.ehn at oracle.com (Robbin Ehn) Date: Fri, 26 Apr 2019 10:14:30 +0200 Subject: RFR(S): 8222518: Remove unnecessary caching of Parker object in java.lang.Thread In-Reply-To: References: <4d1ad4b6-95e9-e7c9-2064-4e9ff67edae8@oracle.com> <9b063a96-1859-6280-7412-75d54c1a1fb6@oracle.com> Message-ID: <1d4f26a1-a774-2fad-d0af-498665d37954@oracle.com> > I'll file a RFE for that. Great, thanks! /Robbin > > Thanks, > David > > > >> Thanks, Robbin >> >> On 4/24/19 9:12 AM, David Holmes wrote: >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8222518 >>> webrev: http://cr.openjdk.java.net/~dholmes/8222518/webrev/ >>> >>> The original implementation of Unsafe.unpark simply extracted the JavaThread >>> reference from the java.lang.Thread oop and if non-null extracted the Parker >>> instance from it and invoked unpark. This was racy however as the native >>> JavaThread could terminate at any time and deallocate the Parker. >>> >>> That logic was fixed by JDK-6271298 which used of combination of >>> type-stable-memory "event" objects for the Parker, along with use of the >>> Threads_lock to obtain the initial reference to the Parker (from a JavaThread >>> guaranteed to be alive), together with caching the native Parker pointer in a >>> field of java.lang.Thread. Even though the native thread may have terminated >>> the Parker was still valid (even if associated with a different thread) and >>> the unpark at worst was a spurious wakeup for that other thread. >>> >>> When JDK-8167108 introduced Thread Safe-Memory-Reclaimation (SMR) the logic >>> was updated to always use the safe mechanism - we grab a ThreadsListHandle >>> then check the cached field, else lookup the native thread to see if it is >>> alive and locate the Parker instance that way. >>> With SMR the caching of the Parker pointer no longer serves any purpose - we >>> no longer have a lock-free use-the-cache path versus a lock-using >>> populate-the-cache path. With SMR we've already"paid" for the ability to >>> ensure the native thread can't terminate regardless of whether we lookup the >>> field from the java.lang.Thread or the JavaThread. So we can simplify the >>> code and save a little footprint by removing the cache from java.lang.Thread: >>> >>> ???? /* >>> ????? * JVM-private state that persists after native thread termination. >>> ????? */ >>> ???? private long nativeParkEventPointer; >>> >>> and the supporting code from unsafe.cpp and javaClass.*pp in the JVM. >>> >>> I considered restoring the fast-path use of the cache without recourse to >>> Thread-SMR but performance measurements failed to show any benefit in doing. >>> See bug report for details. >>> >>> Thanks, >>> David From amaembo at gmail.com Fri Apr 26 08:24:13 2019 From: amaembo at gmail.com (Tagir Valeev) Date: Fri, 26 Apr 2019 15:24:13 +0700 Subject: RFR 8222955 : Optimize String.replace(CharSequence, CharSequence) for Latin1 encoded strings In-Reply-To: References: Message-ID: Hello! Great optimization! + // overflow-conscious code + int resultLen = valLen + (++p) * deltaLen; + if (Integer.MAX_VALUE / p < deltaLen || + Integer.MAX_VALUE - resultLen < 0) { + throw new OutOfMemoryError(); + } Is it really necessary to introduce unconditional division by unknown divisor in the common path? Probably this would be better (common path should be intrinsified)? int resultLen; try { resultLen = Math.addExact(valLen, Math.multiplyExact(++p, deltaLen)); } catch(ArithmeticException ignored) { throw new OutOfMemoryError(); } Or alternatively long resultLenLong = ((long)(++p)) * deltaLen + valLen; // long never overflows here int resultLen = (int)resultLenLong; if (resultLenLong != resultLen) { throw new OutOfMemoryError(); } With best regards, Tagir Valeev. On Thu, Apr 25, 2019 at 1:01 PM Ivan Gerasimov wrote: > > Hello! > > This enhancement was inspired by a recent discussion at > compiler-dev at openjdk.java.net. > > It seems to be a non-uncommon situation when String.replace(CS, CS) is > called with this and both arguments being Latin1 strings, so it seems > reasonable to optimize for such case. > > Here are the fresh benchmark results (see the webrev for the source of > the benchmark): > -- prior the fix: > Benchmark Mode Cnt Score Error Units > StringReplace.replace1_0 avgt 24 70.860 ? 5.239 ns/op > StringReplace.replace1_1 avgt 24 82.661 ? 1.007 ns/op > StringReplace.replace1_2 avgt 24 97.251 ? 1.186 ns/op > > -- after the fix: > Benchmark Mode Cnt Score Error Units > StringReplace.replace1_0 avgt 24 52.855 ? 0.982 ns/op > StringReplace.replace1_1 avgt 24 23.849 ? 0.066 ns/op > StringReplace.replace1_2 avgt 24 62.266 ? 0.552 ns/op > > So the speedup was x1.3, x3.4, x1.5. > > Would you please help review the fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8222955 > WEBREV: http://cr.openjdk.java.net/~igerasim/8222955/00/webrev/ > > Mach5 job is in progress and looks green so far (a few test groups are > left). > > Thanks in advance! > > -- > With kind regards, > Ivan Gerasimov > From peter.levart at gmail.com Fri Apr 26 09:08:26 2019 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 26 Apr 2019 11:08:26 +0200 Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: <2fd250ee-8711-75ec-0418-3caeeb1a0983@oracle.com> References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> <05526f62-727a-6b53-b15f-a8df3a1cb688@redhat.com> <2fd250ee-8711-75ec-0418-3caeeb1a0983@oracle.com> Message-ID: Hi Claes, I wonder if it is even possible to create a test that would do something like the following: ??????? String s = ... ??????? String s2 = s + "const1" + "const2" + s; ...since javac concatenates consecutive constants into a single constant. So this actually becomes: ??????? String s2 = s + "const1const2" + s; ...in bytecode. The branch of code in the StringConcatFactory for constant != null: 1591???????????????????? case TAG_CONST: { 1592???????????????????????? String constantValue = el.getValue(); 1593???????????????????????? initialLengthCoder = (long)mixer(String.class).invoke(initialLengthCoder, constantValue); 1594???????????????????????? // fold sequential constants into one 1595???????????????????????? constant = (constant != null) ? constant + constantValue : constantValue; 1596???????????????????????? break; 1597???????????????????? } ...will therefore never actually be executed in programs compiled with javac. Other bytecode compilers or generators might trigger this though. So what do you think? Is it important to test this or is it "obviously" correct? Regards, Peter On 4/25/19 2:20 PM, Claes Redestad wrote: > Hi, > > sorry for the delay, got distracted by other things. Switch back: > > http://cr.openjdk.java.net/~redestad/8222852/open.01/ > > Passed a sanity tier1 run. > > /Claes > > On 2019-04-23 13:27, Aleksey Shipilev wrote: >> I'd keep the switch in the second loop, like this: >> >> ?? for (RecipeElement el : recipe.getElements()) { >> ?????? switch (el.getTag()) { >> ?????????? case TAG_ARG: >> ?????????????? ... >> ?????????????? break; >> ?????????? case TAG_CONST: >> ?????????????? // Constants are already handled in the code above. >> ?????????????? break; >> ?????????? default: >> ?????????????? throw new StringConcatException("Unhandled tag: " + >> el.getTag()); >> ?????? } >> ?? } From peter.levart at gmail.com Fri Apr 26 09:19:46 2019 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 26 Apr 2019 11:19:46 +0200 Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> <05526f62-727a-6b53-b15f-a8df3a1cb688@redhat.com> <2fd250ee-8711-75ec-0418-3caeeb1a0983@oracle.com> Message-ID: <8f06c429-56b9-fee7-0e0c-76ccaef4358d@gmail.com> On 4/26/19 11:08 AM, Peter Levart wrote: > I wonder if it is even possible to create a test that would do > something like the following: > > ??????? String s = ... > ??????? String s2 = s + "const1" + "const2" + s; > > ...since javac concatenates consecutive constants into a single > constant. So this actually becomes: > > ??????? String s2 = s + "const1const2" + s; > > ...in bytecode. Well, you don't really have to assemble the appropriate bytecodes. You could just invoke the bootstrap method directly in the test, like: ??????? CallSite cs = StringConcatFactory.makeConcatWithConstants( ??????????? MethodHandles.lookup(), ??????????? "concat", ??????????? MethodType.methodType(String.class, String.class, String.class), ??????????? "\u0001\u0002\u0002\u0001", ??????????? "C", "D" ??????? ); ??????? MethodHandle mh = cs.dynamicInvoker(); ??????? String res = (String) mh.invokeExact("A", "B"); ??????? assert "ACDB".equals(res); Regards, Peter From Alan.Bateman at oracle.com Fri Apr 26 09:25:30 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 26 Apr 2019 10:25:30 +0100 Subject: RFR(S): 8222518: Remove unnecessary caching of Parker object in java.lang.Thread In-Reply-To: References: <4d1ad4b6-95e9-e7c9-2064-4e9ff67edae8@oracle.com> <0db0ea2a-6192-0587-3cd2-41f0d718c449@oracle.com> <0d902766-235d-66ae-a69e-966d9da1548f@oracle.com> Message-ID: <3b23c713-6913-3d20-048c-2c51deace041@oracle.com> On 26/04/2019 06:32, David Holmes wrote: > I pushed this today based on Dan and Robbin's reviews, but realized > just after the act that I should have waited for any feedback from > core-libs - apologies about that. If there are concerns I will roll it > back. I don't think there are any concerns, it is of course very welcome to remove a field from Thread. -Alan From daniel.fuchs at oracle.com Fri Apr 26 11:23:06 2019 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 26 Apr 2019 12:23:06 +0100 Subject: 8218280: LineNumberReader throws "Mark invalid" exception if CRLF straddles buffer. In-Reply-To: <45FE4FDA-9037-4713-8F06-005ADE9F7A62@oracle.com> References: <45FE4FDA-9037-4713-8F06-005ADE9F7A62@oracle.com> Message-ID: Hi Brian, I believe this looks good. I had to convince myself that there was no issue when '\r' is not followed by '\n' but I couldn't fault the logic. I wonder if adding a third test case with '\r' not followed by '\n' would be a good idea? best regards, -- daniel On 26/04/2019 02:20, Brian Burkhalter wrote: > For issue [1] please review the patch [2]. > > The source change merely changes mark() to use a read ahead limit one value larger than the parameter if the most recently read character is a ?\r? (carriage return). In this case if the next character in the stream is a ?\n? (line feed), the next read() would actually consume two characters instead of one. The incremented read ahead limit compensates for this. > > The two sub-tests of the test both fail without the implementation change and succeed with it. > > Thanks, > > Brian > > [1] https://bugs.openjdk.java.net/browse/JDK-8218280 > [2] http://cr.openjdk.java.net/~bpb/8218280/webrev.00/ > From david.holmes at oracle.com Fri Apr 26 11:56:44 2019 From: david.holmes at oracle.com (David Holmes) Date: Fri, 26 Apr 2019 21:56:44 +1000 Subject: RFR(S): 8222518: Remove unnecessary caching of Parker object in java.lang.Thread In-Reply-To: <3b23c713-6913-3d20-048c-2c51deace041@oracle.com> References: <4d1ad4b6-95e9-e7c9-2064-4e9ff67edae8@oracle.com> <0db0ea2a-6192-0587-3cd2-41f0d718c449@oracle.com> <0d902766-235d-66ae-a69e-966d9da1548f@oracle.com> <3b23c713-6913-3d20-048c-2c51deace041@oracle.com> Message-ID: On 26/04/2019 7:25 pm, Alan Bateman wrote: > On 26/04/2019 06:32, David Holmes wrote: >> I pushed this today based on Dan and Robbin's reviews, but realized >> just after the act that I should have waited for any feedback from >> core-libs - apologies about that. If there are concerns I will roll it >> back. > I don't think there are any concerns, it is of course very welcome to > remove a field from Thread. Thanks Alan! David > -Alan From christoph.langer at sap.com Fri Apr 26 12:35:51 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Fri, 26 Apr 2019 12:35:51 +0000 Subject: RFR (S): 8223015: Cleanups for zipfs tests Message-ID: Hi, please help reviewing these cleanups to the zipfs tests. In detail: - Fix warnings in test/jdk/jdk/nio/zipfs/Demo.java (not a real testcase but Demo coding) - change some calls of Runtime.version().major() to Runtime.version().feature() (the former is deprecated) - change occurences of new Integer() to Integer.valueOf() - change occurences of class.newInstance() to class.getDeclaredConstructor().newInstance() - remove unused variables - move test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java to test/jdk/jdk/nio/zipfs/JFSTester.java (not using the jarfs subfolder). There is no need for this specific subfolder, given that MultiReleaseJarTest.java neither isn't in the jarfs subfolder Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8223015.0/ Bug: https://bugs.openjdk.java.net/browse/JDK-8223015 I verified that the tests still succeed with the change. Thanks Christoph From claes.redestad at oracle.com Fri Apr 26 12:44:24 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 26 Apr 2019 14:44:24 +0200 Subject: RFR (S): 8223015: Cleanups for zipfs tests In-Reply-To: References: Message-ID: Looks good to me. I took some extra care to check that use of new Integer in MultiReleaseJarTest wasn't intentional but that doesn't seem to be the case here. Thanks! /Claes On 2019-04-26 14:35, Langer, Christoph wrote: > Hi, > > please help reviewing these cleanups to the zipfs tests. In detail: > > - Fix warnings in test/jdk/jdk/nio/zipfs/Demo.java (not a real testcase > but Demo coding) > - change some calls of Runtime.version().major() to > Runtime.version().feature() (the former is deprecated) > - change occurences of new Integer() to Integer.valueOf() > - change occurences of class.newInstance() to > class.getDeclaredConstructor().newInstance() > - remove unused variables > - move test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java to > test/jdk/jdk/nio/zipfs/JFSTester.java (not using the jarfs subfolder). > There is no need for this specific subfolder, given that > MultiReleaseJarTest.java neither isn't in the jarfs subfolder > > Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8223015.0/ > > Bug: https://bugs.openjdk.java.net/browse/JDK-8223015 > > I verified that the tests still succeed with the change. > > Thanks > > Christoph > From christoph.langer at sap.com Fri Apr 26 12:46:33 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Fri, 26 Apr 2019 12:46:33 +0000 Subject: RFR (S): 8223015: Cleanups for zipfs tests In-Reply-To: References: Message-ID: Thank you, Claes. > -----Original Message----- > From: Claes Redestad > Sent: Freitag, 26. April 2019 14:44 > To: Langer, Christoph ; core-libs- > dev at openjdk.java.net; nio-dev at openjdk.java.net > Subject: Re: RFR (S): 8223015: Cleanups for zipfs tests > > Looks good to me. > > I took some extra care to check that use of new Integer in > MultiReleaseJarTest wasn't intentional but that doesn't seem to be the > case here. > > Thanks! > > /Claes > > On 2019-04-26 14:35, Langer, Christoph wrote: > > Hi, > > > > please help reviewing these cleanups to the zipfs tests. In detail: > > > > - Fix warnings in test/jdk/jdk/nio/zipfs/Demo.java (not a real testcase > > but Demo coding) > > - change some calls of Runtime.version().major() to > > Runtime.version().feature() (the former is deprecated) > > - change occurences of new Integer() to Integer.valueOf() > > - change occurences of class.newInstance() to > > class.getDeclaredConstructor().newInstance() > > - remove unused variables > > - move test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java to > > test/jdk/jdk/nio/zipfs/JFSTester.java (not using the jarfs subfolder). > > There is no need for this specific subfolder, given that > > MultiReleaseJarTest.java neither isn't in the jarfs subfolder > > > > Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8223015.0/ > > > > Bug: https://bugs.openjdk.java.net/browse/JDK-8223015 > > > > I verified that the tests still succeed with the change. > > > > Thanks > > > > Christoph > > From pavel.rappo at oracle.com Fri Apr 26 13:16:15 2019 From: pavel.rappo at oracle.com (Pavel Rappo) Date: Fri, 26 Apr 2019 14:16:15 +0100 Subject: 8218280: LineNumberReader throws "Mark invalid" exception if CRLF straddles buffer. In-Reply-To: <45FE4FDA-9037-4713-8F06-005ADE9F7A62@oracle.com> References: <45FE4FDA-9037-4713-8F06-005ADE9F7A62@oracle.com> Message-ID: <0C1BB7D2-952F-458B-A922-04A6799CB170@oracle.com> > On 26 Apr 2019, at 02:20, Brian Burkhalter wrote: > > For issue [1] please review the patch [2]. Looks good to me. From claes.redestad at oracle.com Fri Apr 26 13:55:06 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 26 Apr 2019 15:55:06 +0200 Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> <05526f62-727a-6b53-b15f-a8df3a1cb688@redhat.com> <2fd250ee-8711-75ec-0418-3caeeb1a0983@oracle.com> Message-ID: Hi Peter, thanks for looking at this! On 2019-04-26 11:08, Peter Levart wrote: > Hi Claes, > > I wonder if it is even possible to create a test that would do something > like the following: > > ??????? String s = ... > ??????? String s2 = s + "const1" + "const2" + s; > > ...since javac concatenates consecutive constants into a single > constant. So this actually becomes: > > ??????? String s2 = s + "const1const2" + s; > > ...in bytecode. > So what do you think? Is it important to test this or is it "obviously" > correct? Adding an explicit sanity test for this seems reasonable to me, since it's a case allowable by the StringConcatFactory that is not expressible via javac: http://cr.openjdk.java.net/~redestad/8222852/open.02/ Also cleaned up a few unused imports etc. Thanks! /Claes From Alan.Bateman at oracle.com Fri Apr 26 14:46:01 2019 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 26 Apr 2019 15:46:01 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <40cb2223-6d5a-4262-6293-2f187f578735@redhat.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> <9218d37f-9820-9216-b125-8f3bc2d19e3d@redhat.com> <453045f6-0259-e098-8211-0187428adb9f@oracle.com> <40cb2223-6d5a-4262-6293-2f187f578735@redhat.com> Message-ID: On 25/04/2019 17:34, Andrew Dinn wrote: > Also, here is a new webrev including the updated implementations for > mappingAddress/Offset/Length as described below > > JIRA: https://bugs.openjdk.java.net/browse/JDK-8221696 > webrev: http://cr.openjdk.java.net/~adinn/8221696/webrev.02 > This looks right and I agree with your notes on negative addresses. As its tricky to get right then it would be good to get another set of eyes on this. A minor nit is that we don't usually use underscores in variable names here, it would be baseAddress rather than base_address, etc. -Alan From cpovirk at google.com Fri Apr 26 14:47:16 2019 From: cpovirk at google.com (Chris Povirk) Date: Fri, 26 Apr 2019 10:47:16 -0400 Subject: Stream implements Iterable, thoughts from Guava In-Reply-To: References: Message-ID: (Kevin and I have been hoping in vain to spend more time on this, so here's a dump of the additional long email I wrote last month but hadn't sent. Obviously still no pressure on you to pick this back up.) Last time, I presented anecdotes about how "Stream implements Iterable" could cause problems for Iterable-accepting methods. My hope has been to weigh those against the benefits of using Stream in foreach. Now, I'm back to argue that the benefits to foreach aren't as large as they initially sound. As the proposal points out, it's always possible to fall back to an old-style for() loop with an Iterator variable. While I agree that this is "an uncomfortable step backwards," I would argue three things: 1. It's good for there to be some friction. 2. Some people don't even think of this possibility. 3. The step doesn't actually make code much longer. In more detail: 1. It's good for there to be some friction. This has already been brought up, at least that people might prefer for() over forEach(), so I don't want to dwell on it. Anecdote: When Kevin reviewed all calls to our old Stream-to-Iterable adapter (only 15 at that point), the 1 caller who was using it for a for() loop was reimplementing collect(toMap()). So I just want to emphasize that this concern applies to more than just forEach(). (Of course you're familiar with the same basic problem from forEach() itself, which people sometimes use instead of collect(), etc.) (Naturally we don't want *too* much friction, so one way to frame this part of the debate is "How much is too much?" In my remaining points, I'll argue that it's less friction than it appears.) 2. Some people don't even think of this possibility. That's not a *good* thing, of course: We'd rather that users who really want to break out of Stream-land be able to find the way to do so. But I think this is one reason that the demand for "foreach for Streams" hasn't gone away: People just don't know about the closest alternative. Perhaps, if we more widely encouraged the old-style loop, it would reduce demand for foreach. For example, while the proposal calls out the old-style loop as a possibility, it's not mentioned in https://bugs.openjdk.java.net/browse/JDK-8148917 -- nor in most of the pages linked from there. That's fair when the problem is phrased as "How do I use Stream with foreach?" but that's arguably an XY problem: What someone wanted is {checked exceptions, break/continue/return, etc.}; what that person tried is foreach, but that might not be the best solution. 3. The step doesn't actually make code much longer. The proposal presents some code, but I'd emphasize two things: - Anyone with "foreach for Streams" will also have `var`. - Users are likely to already want to declare a variable for their Stream. So I think the comparison looks like this: var names = annotations.stream() .map(ASTHelpers::getSymbol) .filter(Objects::nonNull) .map(Symbol::getSimpleName) .map(a -> "@" + a); for (var name : names) { doSomething(name); } vs. var names = annotations.stream() .map(ASTHelpers::getSymbol) .filter(Objects::nonNull) .map(Symbol::getSimpleName) .map(a -> "@" + a) .iterator(); while (names.hasNext()) { doSomething(names.next()); } (code is adapted from https://github.com/google/error-prone/blob/61cb540c08ec63faa56dccce00049cff1f8b41ea/core/src/main/java/com/google/errorprone/bugpatterns/AnnotationPosition.java#L230, the first Stream use I found in Google open-source code) To be fair: - Sometimes users will want to extract each element into a variable. - Sometimes users *won't* have a variable for the Stream. This seems likely if the Stream is returned from a method that "does most of the work," rather than being created and used inline (if that distinction makes sense?). My impression in Google code is that most streams are created inline, but I admit I don't have numbers, and as always, we might not be representative. (In particular, I think that we and you give somewhat different guidance on when a method should return Stream.) So sometimes the comparison looks like this: for (var name : makeTheStream()) { doSomething(name); } vs. for (var names = makeTheStream().iterator(); names.hasNext(); ) { var name = names.next(); doSomething(name); } That's definitely worse. But again, it's worth noting that `var` still helps. Thanks to `var`, foreach is less important today than it was when it was first introduced. To be clear: foreach is still good! I still like it! But we're no longer competing with: for (Iterator> names = makeTheStream().iterator(); names.hasNext(); ) { Something name = names.next(); doSomething(name); } If we're considering, then, what's changed since the original decision to *not* make Stream implement Iterable, I'd include `var`. And I'd argue that it improves old-style for() loops enough that we don't much need foreach over Stream. So the question again, as I see it, is how often foreach is useful for Stream (and how much effort that saves) versus how often Iterable-ness will be used when it "shouldn't" be (and how bad that is). From christoph.langer at sap.com Fri Apr 26 15:37:25 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Fri, 26 Apr 2019 15:37:25 +0000 Subject: RFR: 8222276: (zipfs) Refactoring and cleanups to prepare for JDK-8213031 In-Reply-To: References: Message-ID: Hi, ping ?? I?ve rebased this change after the latest zipfs updates. I also made some further modifications. Apart from minor things, I modified the constructors of the ZipFileSystem.Entry class and I also made some post JDK-8222440 cleanup. Please find the new webrev here: http://cr.openjdk.java.net/~clanger/webrevs/8222276.1/ The jtreg tests for zipfs are all passing. Thanks Christoph From: Langer, Christoph Sent: Donnerstag, 11. April 2019 16:06 To: core-libs-dev ; nio-dev ; Alan Bateman ; Lance Andersen Subject: RFR: 8222276: (zipfs) Refactoring and cleanups to prepare for JDK-8213031 Hi, working on JDK-8213031 to add posix file permission support for the zipfs, I thought it makes sense to factor out some of the changes into a separate change. Those changes reorganize and clean up some parts of the code which I think makes sense in any case. Please review: Bug: https://bugs.openjdk.java.net/browse/JDK-8222276 Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8222276.0/ In detail: The main change is to the hierarchy of inner classes ZipFileSystem.IndexNode and ZipFileSystem.Entry (the latter extends the former). Both classes are static classes currently. It makes sense, though, to have those associated with the ZipFileSystem they belong to. To do that, I need to add a static superclass named ZFSNode which only holds a node name and its hashcode. This class needs to exist because of the lookup implementation to find specific nodes of tze ZipFileSystem in its node map. Then the classes IndexNode extends ZFSNode and Entry extends IndexNode can be made non-static. Further changes are: Improve error handling for ZipFileAttributeView::get methods improve handling for zip64 attribute/version minor clenaups such as adding @Override annotations, whitespace fixes, private method visibility etc. Furthermore, there is some suspicious coding in JarFileSystem:: createVersionedLinks where a temporary key node is inserted into the alias map. However, this is a singleton instance which always gets new values. I?ll open a separate bug for that and I?ll try to create a test case which demonstrates an issue with the current code. I ran the zipfs jtreg tests successfully and will put it into our internal system as well as run it through jdk-submit. Thanks Christoph From claes.redestad at oracle.com Fri Apr 26 16:13:35 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 26 Apr 2019 18:13:35 +0200 Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> <05526f62-727a-6b53-b15f-a8df3a1cb688@redhat.com> <2fd250ee-8711-75ec-0418-3caeeb1a0983@oracle.com> Message-ID: <5c57e296-f847-e090-d247-4b3455b9d252@oracle.com> Not content with the fact that we generate one tree for "foo"+bar+baz and another for foo+bar+"baz", I did a little "Hold my beer!"-style experiment with a constant folder that greedily folds prefix and suffix constants around an argument (so "foo"+bar would be prepended in one go, and bar+"baz" in one go in the other tree, making the stem of both trees shareable with no trailing constants having to be filtered in). And it works! Incremental: http://cr.openjdk.java.net/~redestad/8222852/open.02_hmb_inc/ Full: http://cr.openjdk.java.net/~redestad/8222852/open.02_hmb_full/ It doubles the amount of statically defined prependers from 14 to 28, but halves the theoretical maximum number of (larger and more expensive) MH combinator trees. While I can see significant startup improvement on a range of tests with this - and especially so for small, realistic ones - it's also a bit of a mess. I will consider doing this as an immediate follow-up RFE, if I can only clean it up to a point where the added bloat is acceptable. One way to clean things up is to move from inner classes to lambdas (like I've partially done already in this experiment). Turns out to be effectively startup neutral here. /Claes On 2019-04-26 15:55, Claes Redestad wrote: > Hi Peter, > > thanks for looking at this! > > On 2019-04-26 11:08, Peter Levart wrote: >> Hi Claes, >> >> I wonder if it is even possible to create a test that would do >> something like the following: >> >> ???????? String s = ... >> ???????? String s2 = s + "const1" + "const2" + s; >> >> ...since javac concatenates consecutive constants into a single >> constant. So this actually becomes: >> >> ???????? String s2 = s + "const1const2" + s; >> >> ...in bytecode. > >> So what do you think? Is it important to test this or is it >> "obviously" correct? > > Adding an explicit sanity test for this seems reasonable to me, since > it's a case allowable by the StringConcatFactory that is not expressible > via javac: > > http://cr.openjdk.java.net/~redestad/8222852/open.02/ > > Also cleaned up a few unused imports etc. > > Thanks! > > /Claes From lance.andersen at oracle.com Fri Apr 26 16:25:37 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Fri, 26 Apr 2019 12:25:37 -0400 Subject: RFR (S): 8223015: Cleanups for zipfs tests In-Reply-To: References: Message-ID: <5B6F2470-2E7C-4E82-B90B-7D5A4A80F809@oracle.com> Hi Christoph, Thank you for doing this. Overall the changes look good. A few minor thoughts ZIpFSTester.java - 537: Given you removed the method variable, I would tweak the printf string to make it a bit clearer that what the output its. JFSTester.java and MultiReleaseJarTest.java - I had the opposite feeling that having a jarfs subfolder adds clarity and moving MulltiReleaseJarTest.java might be the better way to go. It helps separate specific tests which are using the JarFileSystem from the ZipFileSystem especially as we add more, keeping things cleaner. Best Lance > On Apr 26, 2019, at 8:35 AM, Langer, Christoph wrote: > > Hi, > > please help reviewing these cleanups to the zipfs tests. In detail: > > - Fix warnings in test/jdk/jdk/nio/zipfs/Demo.java (not a real testcase but Demo coding) > - change some calls of Runtime.version().major() to Runtime.version().feature() (the former is deprecated) > - change occurences of new Integer() to Integer.valueOf() > - change occurences of class.newInstance() to class.getDeclaredConstructor().newInstance() > - remove unused variables > - move test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java to test/jdk/jdk/nio/zipfs/JFSTester.java (not using the jarfs subfolder). There is no need for this specific subfolder, given that MultiReleaseJarTest.java neither isn't in the jarfs subfolder > > Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8223015.0/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8223015 > > I verified that the tests still succeed with the change. > > Thanks > Christoph > 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 vicente.romero at oracle.com Fri Apr 26 16:33:11 2019 From: vicente.romero at oracle.com (Vicente Romero) Date: Fri, 26 Apr 2019 12:33:11 -0400 Subject: RFR: JDK-8219483: j.l.c.ClassDesc::nested(String, String...) doesn't throw NPE if any arg is null Message-ID: <7b71bdb8-53cb-fdd3-eca4-4e4ba89fe5a4@oracle.com> Hi, Please review fix [1] and CSR [2] for [3]. The API for method j.l.c.ClassDesc::nested(String, String...) states that it should throw NPE if any of the arguments is null. The implementation is not in sync with the API and should be corrected, Thanks, Vicente [1] http://cr.openjdk.java.net/~vromero/8219483/webrev.00/ [2] https://bugs.openjdk.java.net/browse/JDK-8223034 [3] https://bugs.openjdk.java.net/browse/JDK-8219483 From brent.christian at oracle.com Fri Apr 26 16:46:30 2019 From: brent.christian at oracle.com (Brent Christian) Date: Fri, 26 Apr 2019 09:46:30 -0700 Subject: [OpenJDK 2D-Dev] RFR: 8130266: Change the mechanism by which JDK loads the platform-specific GraphicsEnvironment class In-Reply-To: <5CC2195B.2060008@oracle.com> References: <2923a8bb-bf80-d9c0-3150-d4fe05cada60@oracle.com> <5CC2190C.50609@oracle.com> <5CC2195B.2060008@oracle.com> Message-ID: <55731071-832b-5f87-f0e6-f73a63c683b5@oracle.com> The java.base portion looks good to me. -Brent On 4/25/19 1:32 PM, Philip Race wrote: > And the complete CSR link is this : > https://bugs.openjdk.java.net/browse/JDK-8222990 > > On 4/25/19, 1:31 PM, Philip Race wrote: >> Sorry, meant to include core-libs on this ! >> >> -phil. >> >> On 4/25/19, 1:12 PM, Phil Race wrote: >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8130266 >>> CSR: https://bugs.openjdk.java.net/browse/JDK- >>> Webrev: http://cr.openjdk.java.net/~prr/8130266/ >>> >>> Please review this fix + the CSR which eliminates the >>> java.awt.graphicenv System property. >>> >>> To replace it we have platform-specific classes which can then more >>> easily embed >>> platform-specific logic. For example, logic in >>> java.awt.GraphicsEnvironment was >>> then moved down into this class. Also isInAquaSession used on Mac was >>> moved >>> into that class from the Mac Toolkit class. >>> >>> A reference to the property in J2D Bench - just used to log / >>> document the testing environment >>> was removed along with similar references to two other properties >>> removed in earlier fixes. >>> >>> This has been built + tested on Mac, Linux + Windows in headful mode >>> and also >>> specifying headless via -Djava.awt.headless and by letting it default >>> to headless >>> in an ssh session on Mac + by unsetting the DISPLAY variable on Linux. >>> >>> -phil. From lance.andersen at oracle.com Fri Apr 26 16:44:36 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Fri, 26 Apr 2019 12:44:36 -0400 Subject: RFR: 8222276: (zipfs) Refactoring and cleanups to prepare for JDK-8213031 In-Reply-To: References: Message-ID: On my todo list, will get to it either later today or over the weekend. Thank you for the reminder :-) > On Apr 26, 2019, at 11:37 AM, Langer, Christoph wrote: > > Hi, > > ping ?? > > I?ve rebased this change after the latest zipfs updates. I also made some further modifications. Apart from minor things, I modified the constructors of the ZipFileSystem.Entry class and I also made some post JDK-8222440 cleanup. > > Please find the new webrev here: http://cr.openjdk.java.net/~clanger/webrevs/8222276.1/ > > The jtreg tests for zipfs are all passing. > > Thanks > Christoph > > From: Langer, Christoph > Sent: Donnerstag, 11. April 2019 16:06 > To: core-libs-dev ; nio-dev ; Alan Bateman ; Lance Andersen > Subject: RFR: 8222276: (zipfs) Refactoring and cleanups to prepare for JDK-8213031 > > Hi, > > working on JDK-8213031 to add posix file permission support for the zipfs, I thought it makes sense to factor out some of the changes into a separate change. Those changes reorganize and clean up some parts of the code which I think makes sense in any case. > > Please review: > Bug: https://bugs.openjdk.java.net/browse/JDK-8222276 > Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8222276.0/ > > In detail: > The main change is to the hierarchy of inner classes ZipFileSystem.IndexNode and ZipFileSystem.Entry (the latter extends the former). Both classes are static classes currently. It makes sense, though, to have those associated with the ZipFileSystem they belong to. > To do that, I need to add a static superclass named ZFSNode which only holds a node name and its hashcode. This class needs to exist because of the lookup implementation to find specific nodes of tze ZipFileSystem in its node map. Then the classes IndexNode extends ZFSNode and Entry extends IndexNode can be made non-static. > > Further changes are: > Improve error handling for ZipFileAttributeView::get methods > improve handling for zip64 attribute/version > minor clenaups such as adding @Override annotations, whitespace fixes, private method visibility etc. > > Furthermore, there is some suspicious coding in JarFileSystem:: createVersionedLinks where a temporary key node is inserted into the alias map. However, this is a singleton instance which always gets new values. I?ll open a separate bug for that and I?ll try to create a test case which demonstrates an issue with the current code. > > I ran the zipfs jtreg tests successfully and will put it into our internal system as well as run it through jdk-submit. > > Thanks > Christoph 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 christoph.langer at sap.com Fri Apr 26 16:50:38 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Fri, 26 Apr 2019 16:50:38 +0000 Subject: RFR (S): 8223015: Cleanups for zipfs tests In-Reply-To: <5B6F2470-2E7C-4E82-B90B-7D5A4A80F809@oracle.com> References: <5B6F2470-2E7C-4E82-B90B-7D5A4A80F809@oracle.com> Message-ID: Hi Lance, thanks for reviewing. As for ZipFSTester: the printf is anyway commented out, probably only used for debugging. Removing the variable was just because the IDE said it's unused. I'd rather leave it as is. As for the jarfs tests: OK, it probably makes sense to separate these out into a subfolder. So I'll move MultiReleaseJarTest to the subfolder instead of moving JFSTester. OK for you if I push this without another webrev next week? Best regards Christoph From: Lance Andersen Sent: Freitag, 26. April 2019 18:26 To: Langer, Christoph Cc: core-libs-dev at openjdk.java.net; nio-dev at openjdk.java.net Subject: Re: RFR (S): 8223015: Cleanups for zipfs tests Hi Christoph, Thank you for doing this. Overall the changes look good. A few minor thoughts ZIpFSTester.java - 537: Given you removed the method variable, I would tweak the printf string to make it a bit clearer that what the output its. JFSTester.java and MultiReleaseJarTest.java - I had the opposite feeling that having a jarfs subfolder adds clarity and moving MulltiReleaseJarTest.java might be the better way to go. It helps separate specific tests which are using the JarFileSystem from the ZipFileSystem especially as we add more, keeping things cleaner. Best Lance On Apr 26, 2019, at 8:35 AM, Langer, Christoph > wrote: Hi, please help reviewing these cleanups to the zipfs tests. In detail: - Fix warnings in test/jdk/jdk/nio/zipfs/Demo.java (not a real testcase but Demo coding) - change some calls of Runtime.version().major() to Runtime.version().feature() (the former is deprecated) - change occurences of new Integer() to Integer.valueOf() - change occurences of class.newInstance() to class.getDeclaredConstructor().newInstance() - remove unused variables - move test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java to test/jdk/jdk/nio/zipfs/JFSTester.java (not using the jarfs subfolder). There is no need for this specific subfolder, given that MultiReleaseJarTest.java neither isn't in the jarfs subfolder Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8223015.0/ Bug: https://bugs.openjdk.java.net/browse/JDK-8223015 I verified that the tests still succeed with the change. Thanks Christoph [cid:image001.gif at 01D4FC60.EDECDC10] 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 christoph.langer at sap.com Fri Apr 26 16:51:16 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Fri, 26 Apr 2019 16:51:16 +0000 Subject: RFR: 8222276: (zipfs) Refactoring and cleanups to prepare for JDK-8213031 In-Reply-To: References: Message-ID: Great, thank you. This one is a bit larger and will probably need a few iterations? From: Lance Andersen Sent: Freitag, 26. April 2019 18:45 To: Langer, Christoph Cc: core-libs-dev ; nio-dev ; Alan Bateman Subject: Re: RFR: 8222276: (zipfs) Refactoring and cleanups to prepare for JDK-8213031 On my todo list, will get to it either later today or over the weekend. Thank you for the reminder :-) On Apr 26, 2019, at 11:37 AM, Langer, Christoph > wrote: Hi, ping ?? I?ve rebased this change after the latest zipfs updates. I also made some further modifications. Apart from minor things, I modified the constructors of the ZipFileSystem.Entry class and I also made some post JDK-8222440 cleanup. Please find the new webrev here: http://cr.openjdk.java.net/~clanger/webrevs/8222276.1/ The jtreg tests for zipfs are all passing. Thanks Christoph From: Langer, Christoph Sent: Donnerstag, 11. April 2019 16:06 To: core-libs-dev >; nio-dev >; Alan Bateman >; Lance Andersen > Subject: RFR: 8222276: (zipfs) Refactoring and cleanups to prepare for JDK-8213031 Hi, working on JDK-8213031 to add posix file permission support for the zipfs, I thought it makes sense to factor out some of the changes into a separate change. Those changes reorganize and clean up some parts of the code which I think makes sense in any case. Please review: Bug: https://bugs.openjdk.java.net/browse/JDK-8222276 Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8222276.0/ In detail: The main change is to the hierarchy of inner classes ZipFileSystem.IndexNode and ZipFileSystem.Entry (the latter extends the former). Both classes are static classes currently. It makes sense, though, to have those associated with the ZipFileSystem they belong to. To do that, I need to add a static superclass named ZFSNode which only holds a node name and its hashcode. This class needs to exist because of the lookup implementation to find specific nodes of tze ZipFileSystem in its node map. Then the classes IndexNode extends ZFSNode and Entry extends IndexNode can be made non-static. Further changes are: Improve error handling for ZipFileAttributeView::get methods improve handling for zip64 attribute/version minor clenaups such as adding @Override annotations, whitespace fixes, private method visibility etc. Furthermore, there is some suspicious coding in JarFileSystem:: createVersionedLinks where a temporary key node is inserted into the alias map. However, this is a singleton instance which always gets new values. I?ll open a separate bug for that and I?ll try to create a test case which demonstrates an issue with the current code. I ran the zipfs jtreg tests successfully and will put it into our internal system as well as run it through jdk-submit. Thanks Christoph [cid:image001.gif at 01D4FC61.06443E70] 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 Fri Apr 26 16:54:17 2019 From: lance.andersen at oracle.com (Lance Andersen) Date: Fri, 26 Apr 2019 12:54:17 -0400 Subject: RFR (S): 8223015: Cleanups for zipfs tests In-Reply-To: References: <5B6F2470-2E7C-4E82-B90B-7D5A4A80F809@oracle.com> Message-ID: Hi Christoph, > On Apr 26, 2019, at 12:50 PM, Langer, Christoph wrote: > > Hi Lance, > > thanks for reviewing. :-) > > As for ZipFSTester: the printf is anyway commented out, probably only used for debugging. Removing the variable was just because the IDE said it?s unused. I?d rather leave it as is. Well, i would tweak it or remove it. > > As for the jarfs tests: OK, it probably makes sense to separate these out into a subfolder. So I?ll move MultiReleaseJarTest to the subfolder instead of moving JFSTester. sounds like a plan > > OK for you if I push this without another webrev next week? Yes that is fine :-) Have a good weekend! Best Lance > > Best regards > Christoph > > From: Lance Andersen > > Sent: Freitag, 26. April 2019 18:26 > To: Langer, Christoph > > Cc: core-libs-dev at openjdk.java.net ; nio-dev at openjdk.java.net > Subject: Re: RFR (S): 8223015: Cleanups for zipfs tests > > Hi Christoph, > > Thank you for doing this. Overall the changes look good. > > A few minor thoughts > > ZIpFSTester.java - 537: Given you removed the method variable, I would tweak the printf string to make it a bit clearer that what the output its. > > JFSTester.java and MultiReleaseJarTest.java - I had the opposite feeling that having a jarfs subfolder adds clarity and moving MulltiReleaseJarTest.java might be the better way to go. It helps separate specific tests which are using the JarFileSystem from the ZipFileSystem especially as we add more, keeping things cleaner. > > Best > Lance > > > On Apr 26, 2019, at 8:35 AM, Langer, Christoph > wrote: > > Hi, > > please help reviewing these cleanups to the zipfs tests. In detail: > > - Fix warnings in test/jdk/jdk/nio/zipfs/Demo.java (not a real testcase but Demo coding) > - change some calls of Runtime.version().major() to Runtime.version().feature() (the former is deprecated) > - change occurences of new Integer() to Integer.valueOf() > - change occurences of class.newInstance() to class.getDeclaredConstructor().newInstance() > - remove unused variables > - move test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java to test/jdk/jdk/nio/zipfs/JFSTester.java (not using the jarfs subfolder). There is no need for this specific subfolder, given that MultiReleaseJarTest.java neither isn't in the jarfs subfolder > > Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8223015.0/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8223015 > > I verified that the tests still succeed with the change. > > Thanks > Christoph > > > > > 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 christoph.langer at sap.com Fri Apr 26 17:04:16 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Fri, 26 Apr 2019 17:04:16 +0000 Subject: RFR (S): 8223015: Cleanups for zipfs tests In-Reply-To: References: <5B6F2470-2E7C-4E82-B90B-7D5A4A80F809@oracle.com> Message-ID: Hi Lance, ok, then I?ll remove the commented printf in ZipFSTester altogether. In case anybody debugs this again, he or she will probably add their own printfs anyway. Have a nice weekend, too ?? /Christoph From: Lance Andersen Sent: Freitag, 26. April 2019 18:54 To: Langer, Christoph Cc: core-libs-dev at openjdk.java.net; nio-dev at openjdk.java.net Subject: Re: RFR (S): 8223015: Cleanups for zipfs tests Hi Christoph, On Apr 26, 2019, at 12:50 PM, Langer, Christoph > wrote: Hi Lance, thanks for reviewing. :-) As for ZipFSTester: the printf is anyway commented out, probably only used for debugging. Removing the variable was just because the IDE said it?s unused. I?d rather leave it as is. Well, i would tweak it or remove it. As for the jarfs tests: OK, it probably makes sense to separate these out into a subfolder. So I?ll move MultiReleaseJarTest to the subfolder instead of moving JFSTester. sounds like a plan OK for you if I push this without another webrev next week? Yes that is fine :-) Have a good weekend! Best Lance Best regards Christoph From: Lance Andersen > Sent: Freitag, 26. April 2019 18:26 To: Langer, Christoph > Cc: core-libs-dev at openjdk.java.net; nio-dev at openjdk.java.net Subject: Re: RFR (S): 8223015: Cleanups for zipfs tests Hi Christoph, Thank you for doing this. Overall the changes look good. A few minor thoughts ZIpFSTester.java - 537: Given you removed the method variable, I would tweak the printf string to make it a bit clearer that what the output its. JFSTester.java and MultiReleaseJarTest.java - I had the opposite feeling that having a jarfs subfolder adds clarity and moving MulltiReleaseJarTest.java might be the better way to go. It helps separate specific tests which are using the JarFileSystem from the ZipFileSystem especially as we add more, keeping things cleaner. Best Lance On Apr 26, 2019, at 8:35 AM, Langer, Christoph > wrote: Hi, please help reviewing these cleanups to the zipfs tests. In detail: - Fix warnings in test/jdk/jdk/nio/zipfs/Demo.java (not a real testcase but Demo coding) - change some calls of Runtime.version().major() to Runtime.version().feature() (the former is deprecated) - change occurences of new Integer() to Integer.valueOf() - change occurences of class.newInstance() to class.getDeclaredConstructor().newInstance() - remove unused variables - move test/jdk/jdk/nio/zipfs/jarfs/JFSTester.java to test/jdk/jdk/nio/zipfs/JFSTester.java (not using the jarfs subfolder). There is no need for this specific subfolder, given that MultiReleaseJarTest.java neither isn't in the jarfs subfolder Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8223015.0/ Bug: https://bugs.openjdk.java.net/browse/JDK-8223015 I verified that the tests still succeed with the change. Thanks Christoph 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 [cid:image001.gif at 01D4FC62.D708F4F0] 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 james.laskey at oracle.com Fri Apr 26 17:57:57 2019 From: james.laskey at oracle.com (Jim Laskey) Date: Fri, 26 Apr 2019 14:57:57 -0300 Subject: RFR (CSR) - JDK-8218285 ClassDesc should have a full name method Message-ID: <64194254-41EB-430C-A8AB-5E98084E33E7@oracle.com> Please review. Thank you. Cheers, -- Jim Summary: Add the method ClassDesc::displayFullName to return the fully qualified class name from a ClassDesc. Add a second method MethodTypeDesc::displayFullDescriptor which returns the MethodTypeDesc descriptor using fully qualified class names. csr: https://bugs.openjdk.java.net/browse/JDK-8218285 jbs: https://bugs.openjdk.java.net/browse/JDK-8212975 webrev: http://cr.openjdk.java.net/~jlaskey/8212975/webrev-03/index.html From brian.burkhalter at oracle.com Fri Apr 26 18:27:00 2019 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Fri, 26 Apr 2019 11:27:00 -0700 Subject: 8218280: LineNumberReader throws "Mark invalid" exception if CRLF straddles buffer. In-Reply-To: References: <45FE4FDA-9037-4713-8F06-005ADE9F7A62@oracle.com> Message-ID: <2DE0C221-4708-44A0-B282-689A82E2EBD9@oracle.com> Daniel, I modified the test as shown below. It passes both before and after the implementation change. Thanks, Brian --- a/test/jdk/java/io/LineNumberReader/MarkSplitCRLF.java +++ b/test/jdk/java/io/LineNumberReader/MarkSplitCRLF.java @@ -56,6 +56,24 @@ } @Test + public static void testCRNotFollowedByLF() throws IOException { + final String string = "foo\rbar"; + try (Reader reader = + new LineNumberReader(new StringReader(string), 5)) { + reader.read(); // 'f' + reader.read(); // 'o' + reader.read(); // 'o' + reader.read(); // '\r' + reader.mark(1); // mark position of next character + reader.read(); // 'b' + reader.reset(); // reset to position after '\n' + assertEquals(reader.read(), 'b'); + assertEquals(reader.read(), 'a'); + assertEquals(reader.read(), 'r'); + } + } + + @Test > On Apr 26, 2019, at 4:23 AM, Daniel Fuchs wrote: > > I had to convince myself that there was no issue when > '\r' is not followed by '\n' but I couldn't fault the > logic. > > I wonder if adding a third test case with '\r' not > followed by '\n' would be a good idea? From daniel.fuchs at oracle.com Fri Apr 26 18:45:40 2019 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 26 Apr 2019 19:45:40 +0100 Subject: 8218280: LineNumberReader throws "Mark invalid" exception if CRLF straddles buffer. In-Reply-To: <2DE0C221-4708-44A0-B282-689A82E2EBD9@oracle.com> References: <45FE4FDA-9037-4713-8F06-005ADE9F7A62@oracle.com> <2DE0C221-4708-44A0-B282-689A82E2EBD9@oracle.com> Message-ID: Looks good Brian! nit: > + reader.reset(); // reset to position after '\n' actually it's 'after '\r'' now. No need for new review! best regards, -- daniel On 26/04/19 19:27, Brian Burkhalter wrote: > Daniel, > > I modified the test as shown below. It passes both before and after the > implementation change. > > Thanks, > > Brian > > --- a/test/jdk/java/io/LineNumberReader/MarkSplitCRLF.java > +++ b/test/jdk/java/io/LineNumberReader/MarkSplitCRLF.java > @@ -56,6 +56,24 @@ > ?? ? } > > > ?? ? @Test > +? ? public static void testCRNotFollowedByLF() throws IOException { > +? ? ? ? final String string = "foo\rbar"; > +? ? ? ? try (Reader reader = > +? ? ? ? ? ? new LineNumberReader(new StringReader(string), 5)) { > +? ? ? ? ? ? reader.read();? // 'f' > +? ? ? ? ? ? reader.read();? // 'o' > +? ? ? ? ? ? reader.read();? // 'o' > +? ? ? ? ? ? reader.read();? // '\r' > +? ? ? ? ? ? reader.mark(1); // mark position of next character > +? ? ? ? ? ? reader.read();? // 'b' > +? ? ? ? ? ? reader.reset(); // reset to position after '\n' > +? ? ? ? ? ? assertEquals(reader.read(), 'b'); > +? ? ? ? ? ? assertEquals(reader.read(), 'a'); > +? ? ? ? ? ? assertEquals(reader.read(), 'r'); > +? ? ? ? } > +? ? } > + > +? ? @Test > >> On Apr 26, 2019, at 4:23 AM, Daniel Fuchs > > wrote: >> >> I had to convince myself that there was no issue when >> '\r' is not followed by '\n' but I couldn't fault ?the >> logic. >> >> I wonder if adding a third test case with '\r' not >> followed by '\n' would be a good idea? > From brian.burkhalter at oracle.com Fri Apr 26 18:48:39 2019 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Fri, 26 Apr 2019 11:48:39 -0700 Subject: 8218280: LineNumberReader throws "Mark invalid" exception if CRLF straddles buffer. In-Reply-To: References: <45FE4FDA-9037-4713-8F06-005ADE9F7A62@oracle.com> <2DE0C221-4708-44A0-B282-689A82E2EBD9@oracle.com> Message-ID: <4C70C797-3A25-4807-B11F-857BB0E8B632@oracle.com> Hi Daniel, I actually caught that already: the diff I included before was stale (from a scroll-up in the terminal!). Thanks! Brian > On Apr 26, 2019, at 11:45 AM, Daniel Fuchs wrote: > > Looks good Brian! > > nit: > > > + reader.reset(); // reset to position after '\n' > > actually it's 'after '\r'' now. > > No need for new review! From martinrb at google.com Fri Apr 26 19:01:23 2019 From: martinrb at google.com (Martin Buchholz) Date: Fri, 26 Apr 2019 12:01:23 -0700 Subject: VarHandle instance methods performance In-Reply-To: <59715067-cbb8-61da-f422-b1be98d06652@oracle.com> References: <044601d4fa83$525d4110$f717c330$@oracle.com> <59715067-cbb8-61da-f422-b1be98d06652@oracle.com> Message-ID: I filed https://bugs.openjdk.java.net/browse/JDK-8223039 From semyon.sadetsky at oracle.com Fri Apr 26 19:28:13 2019 From: semyon.sadetsky at oracle.com (semyon.sadetsky at oracle.com) Date: Fri, 26 Apr 2019 12:28:13 -0700 Subject: RFR: JDK-8223038: JPackage code signing fails on Mac. Message-ID: bug: https://bugs.openjdk.java.net/browse/JDK-8223038 webrev: http://cr.openjdk.java.net/~ssadetsky/8223038/webrev.00/ This is a regression of 8219683 where Java runtime was moved out from PlugIns which made codesign unable to detect the bundle type. The fix points codesign to the valid path it can recognize and sign accordingly. --Semyon From alexander.matveev at oracle.com Fri Apr 26 21:44:28 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Fri, 26 Apr 2019 14:44:28 -0700 Subject: RFR: JDK-8223038: JPackage code signing fails on Mac. In-Reply-To: References: Message-ID: <1478b837-305a-836d-12bb-694720679bd9@oracle.com> Hi Semyon, Looks good. Thanks, Alexander On 4/26/2019 12:28 PM, semyon.sadetsky at oracle.com wrote: > bug: https://bugs.openjdk.java.net/browse/JDK-8223038 > > webrev: http://cr.openjdk.java.net/~ssadetsky/8223038/webrev.00/ > > This is a regression of 8219683 where Java runtime was moved out from > PlugIns which made codesign unable to detect the bundle type. The fix > points codesign to the valid path it can recognize and sign accordingly. > > --Semyon > From joe.darcy at oracle.com Sat Apr 27 01:32:25 2019 From: joe.darcy at oracle.com (Joe Darcy) Date: Fri, 26 Apr 2019 18:32:25 -0700 Subject: RFR: JDK-8219483: j.l.c.ClassDesc::nested(String, String...) doesn't throw NPE if any arg is null In-Reply-To: <7b71bdb8-53cb-fdd3-eca4-4e4ba89fe5a4@oracle.com> References: <7b71bdb8-53cb-fdd3-eca4-4e4ba89fe5a4@oracle.com> Message-ID: <9b0ea90c-ddca-ab76-caf0-c41e2b56aa2c@oracle.com> Hi Vicente, For purposes of a better exception message, do you want to explicitly check moreNestedNames for null in some way before accessing its contents? Also, I'd commend the spec be updated slightly to ??? @throws NullPointerException if any argument or its contents is {@code null} assuming the desired behavior is a NPE if an element of moreNestedNames is null as opposed to ust moreNestedNames itself. Thanks, -Joe On 4/26/2019 9:33 AM, Vicente Romero wrote: > Hi, > > Please review fix [1] and CSR [2] for [3]. The API for method > j.l.c.ClassDesc::nested(String, String...) states that it should throw > NPE if any of the arguments is null. The implementation is not in sync > with the API and should be corrected, > > Thanks, > Vicente > > [1] http://cr.openjdk.java.net/~vromero/8219483/webrev.00/ > [2] https://bugs.openjdk.java.net/browse/JDK-8223034 > [3] https://bugs.openjdk.java.net/browse/JDK-8219483 > From philip.race at oracle.com Sun Apr 28 00:46:24 2019 From: philip.race at oracle.com (Philip Race) Date: Sat, 27 Apr 2019 17:46:24 -0700 Subject: RFR: JDK-8212780: JEP 343: Packaging Tool Implementation In-Reply-To: <3da2c640-8fad-335b-9696-69f45e1a1024@oracle.com> References: <0bd5501f-9db0-f22a-c4f1-4e284a43021f@oracle.com> <3da2c640-8fad-335b-9696-69f45e1a1024@oracle.com> Message-ID: <5CC4F7E0.7020208@oracle.com> Adding build-dev for the build changes. I don't know if these were previously reviewed there, but I am not sure what the changes in NativeCompilation.gmk have to do with jpackage. -phil. On 4/24/19, 5:47 PM, Andy Herrick wrote: > > On 4/24/2019 8:44 PM, Andy Herrick wrote: >> Please review changes for [1] which is the implementation bug for >> JEP-343. >> >> The webrev at [2] is the total cumulative webrev of changes for the >> jpackage tool, currently in the JDK-8200758-branch branch of the open >> sandbox repository. >> >> The webrev at [3] shows the changes from EA-05 to EA-06. > sorry - the links are reversed from what is stated above. [2] is the > incremental webrev since EA 05, [3] is the cumulativewebrev > /Andy >> >> The latest EA-6 (build 49) is posted at [4]. >> >> Please send feedback to core-libs-dev at openjdk.java.net >> >> >> [1] https://bugs.openjdk.java.net/browse/JDK-8200758 >> >> [2] http://cr.openjdk.java.net/~herrick/8212780/webrev.05-06/ >> >> [3] http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/ >> >> [4] http://jdk.java.net/jpackage/ >> >> >> /Andy >> >> > From aph at redhat.com Sun Apr 28 17:09:02 2019 From: aph at redhat.com (Andrew Haley) Date: Sun, 28 Apr 2019 18:09:02 +0100 Subject: RFR : 8221696: MappedByteBuffer.force method to specify range In-Reply-To: <40cb2223-6d5a-4262-6293-2f187f578735@redhat.com> References: <2c9099f0-d95d-425a-c033-b22ad5c25231@redhat.com> <4ad97801-218f-2fa5-e8b5-3f14347c4320@oracle.com> <9218d37f-9820-9216-b125-8f3bc2d19e3d@redhat.com> <453045f6-0259-e098-8211-0187428adb9f@oracle.com> <40cb2223-6d5a-4262-6293-2f187f578735@redhat.com> Message-ID: <4cda30a8-7d86-de1a-2ff9-ae1904563ead@redhat.com> On 4/25/19 5:34 PM, Andrew Dinn wrote: > long map_base = (address & ~(ps - 1)); This looks like a hard way to write long map_base = address & -ps; -- Andrew Haley Java Platform Lead Engineer Red Hat UK Ltd. EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671 From peter.levart at gmail.com Sun Apr 28 18:24:33 2019 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 28 Apr 2019 20:24:33 +0200 Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: <5c57e296-f847-e090-d247-4b3455b9d252@oracle.com> References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> <05526f62-727a-6b53-b15f-a8df3a1cb688@redhat.com> <2fd250ee-8711-75ec-0418-3caeeb1a0983@oracle.com> <5c57e296-f847-e090-d247-4b3455b9d252@oracle.com> Message-ID: <449bde44-e91f-295c-7f6f-c52cc11810d4@gmail.com> Hi Claes, If you had just one prepend method shape: ????? static long prepend(long indexCoder, byte[] buf, String prefix, long value, String suffix) { ????????? if (suffix != null) indexCoder = prepend(indexCoder, buf, suffix); ????????? indexCoder = prepend(indexCoder, buf, value); ????????? if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix); ????????? return indexCoder; ????? } ...then you could make the construction logic bind either null or non-null constants for prefix/suffix and JIT would probably eliminate dead-code paths in generated code. Meaning that specialization would be performed by JIT instead of at link time. Perhaps this would have the same max. performance with simplified wiring logic... What do you think? Regards, Peter On 4/26/19 6:13 PM, Claes Redestad wrote: > Not content with the fact that we generate one tree for "foo"+bar+baz > and another for foo+bar+"baz", I did a little "Hold my beer!"-style > experiment with a constant folder that greedily folds prefix and suffix > constants around an argument (so "foo"+bar would be prepended in one go, > and bar+"baz" in one go in the other tree, making the stem of both trees > shareable with no trailing constants having to be filtered in). > > And it works! > > Incremental: > http://cr.openjdk.java.net/~redestad/8222852/open.02_hmb_inc/ > Full: http://cr.openjdk.java.net/~redestad/8222852/open.02_hmb_full/ > > It doubles the amount of statically defined prependers from 14 to 28, > but halves the theoretical maximum number of (larger and more expensive) > MH combinator trees. > > While I can see significant startup improvement on a range of tests > with this - and especially so for small, realistic ones - it's also a > bit of a mess. I will consider doing this as an immediate follow-up RFE, > if I can only clean it up to a point where the added bloat is > acceptable. One way to clean things up is to move from inner classes to > lambdas (like I've partially done already in this experiment). Turns out > to be effectively startup neutral here. > > /Claes > > On 2019-04-26 15:55, Claes Redestad wrote: >> Hi Peter, >> >> thanks for looking at this! >> >> On 2019-04-26 11:08, Peter Levart wrote: >>> Hi Claes, >>> >>> I wonder if it is even possible to create a test that would do >>> something like the following: >>> >>> ???????? String s = ... >>> ???????? String s2 = s + "const1" + "const2" + s; >>> >>> ...since javac concatenates consecutive constants into a single >>> constant. So this actually becomes: >>> >>> ???????? String s2 = s + "const1const2" + s; >>> >>> ...in bytecode. >> >>> So what do you think? Is it important to test this or is it >>> "obviously" correct? >> >> Adding an explicit sanity test for this seems reasonable to me, since >> it's a case allowable by the StringConcatFactory that is not expressible >> via javac: >> >> http://cr.openjdk.java.net/~redestad/8222852/open.02/ >> >> Also cleaned up a few unused imports etc. >> >> Thanks! >> >> /Claes From peter.levart at gmail.com Sun Apr 28 20:14:54 2019 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 28 Apr 2019 22:14:54 +0200 Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: <449bde44-e91f-295c-7f6f-c52cc11810d4@gmail.com> References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> <05526f62-727a-6b53-b15f-a8df3a1cb688@redhat.com> <2fd250ee-8711-75ec-0418-3caeeb1a0983@oracle.com> <5c57e296-f847-e090-d247-4b3455b9d252@oracle.com> <449bde44-e91f-295c-7f6f-c52cc11810d4@gmail.com> Message-ID: Hi Claes, On 4/28/19 8:24 PM, Peter Levart wrote: > Hi Claes, > > If you had just one prepend method shape: > > ????? static long prepend(long indexCoder, byte[] buf, String prefix, > long value, String suffix) { > ????????? if (suffix != null) indexCoder = prepend(indexCoder, buf, > suffix); > ????????? indexCoder = prepend(indexCoder, buf, value); > ????????? if (prefix != null) indexCoder = prepend(indexCoder, buf, > prefix); > ????????? return indexCoder; > ????? } > > ...then you could make the construction logic bind either null or > non-null constants for prefix/suffix and JIT would probably eliminate > dead-code paths in generated code. Meaning that specialization would > be performed by JIT instead of at link time. Perhaps this would have > the same max. performance with simplified wiring logic... > > What do you think? This is what I meant by "simplified wiring logic": http://cr.openjdk.java.net/~plevart/jdk-dev/8222852_StringConcatOpt/webrev.02p/ I haven't tried this though, but if it works correctly and if JIT inlines the strategy for each call site, it should also eliminate the dead code paths that are detected from null/non-null bound constants and the end result should be equivalent machine code. But that's just in theory... Regards, Peter > > Regards, Peter > > On 4/26/19 6:13 PM, Claes Redestad wrote: >> Not content with the fact that we generate one tree for "foo"+bar+baz >> and another for foo+bar+"baz", I did a little "Hold my beer!"-style >> experiment with a constant folder that greedily folds prefix and suffix >> constants around an argument (so "foo"+bar would be prepended in one go, >> and bar+"baz" in one go in the other tree, making the stem of both trees >> shareable with no trailing constants having to be filtered in). >> >> And it works! >> >> Incremental: >> http://cr.openjdk.java.net/~redestad/8222852/open.02_hmb_inc/ >> Full: http://cr.openjdk.java.net/~redestad/8222852/open.02_hmb_full/ >> >> It doubles the amount of statically defined prependers from 14 to 28, >> but halves the theoretical maximum number of (larger and more expensive) >> MH combinator trees. >> >> While I can see significant startup improvement on a range of tests >> with this - and especially so for small, realistic ones - it's also a >> bit of a mess. I will consider doing this as an immediate follow-up RFE, >> if I can only clean it up to a point where the added bloat is >> acceptable. One way to clean things up is to move from inner classes to >> lambdas (like I've partially done already in this experiment). Turns out >> to be effectively startup neutral here. >> >> /Claes >> >> On 2019-04-26 15:55, Claes Redestad wrote: >>> Hi Peter, >>> >>> thanks for looking at this! >>> >>> On 2019-04-26 11:08, Peter Levart wrote: >>>> Hi Claes, >>>> >>>> I wonder if it is even possible to create a test that would do >>>> something like the following: >>>> >>>> ???????? String s = ... >>>> ???????? String s2 = s + "const1" + "const2" + s; >>>> >>>> ...since javac concatenates consecutive constants into a single >>>> constant. So this actually becomes: >>>> >>>> ???????? String s2 = s + "const1const2" + s; >>>> >>>> ...in bytecode. >>> >>>> So what do you think? Is it important to test this or is it >>>> "obviously" correct? >>> >>> Adding an explicit sanity test for this seems reasonable to me, >>> since it's a case allowable by the StringConcatFactory that is not >>> expressible >>> via javac: >>> >>> http://cr.openjdk.java.net/~redestad/8222852/open.02/ >>> >>> Also cleaned up a few unused imports etc. >>> >>> Thanks! >>> >>> /Claes > From claes.redestad at oracle.com Sun Apr 28 21:34:29 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Sun, 28 Apr 2019 23:34:29 +0200 Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> <05526f62-727a-6b53-b15f-a8df3a1cb688@redhat.com> <2fd250ee-8711-75ec-0418-3caeeb1a0983@oracle.com> <5c57e296-f847-e090-d247-4b3455b9d252@oracle.com> <449bde44-e91f-295c-7f6f-c52cc11810d4@gmail.com> Message-ID: <0f8c65c5-cc12-f7e5-8195-f180890b7e11@oracle.com> Hi Peter, On 2019-04-28 22:14, Peter Levart wrote: > Hi Claes, > > On 4/28/19 8:24 PM, Peter Levart wrote: >> Hi Claes, >> >> If you had just one prepend method shape: >> >> ????? static long prepend(long indexCoder, byte[] buf, String prefix, >> long value, String suffix) { >> ????????? if (suffix != null) indexCoder = prepend(indexCoder, buf, >> suffix); >> ????????? indexCoder = prepend(indexCoder, buf, value); >> ????????? if (prefix != null) indexCoder = prepend(indexCoder, buf, >> prefix); >> ????????? return indexCoder; >> ????? } >> >> ...then you could make the construction logic bind either null or >> non-null constants for prefix/suffix and JIT would probably eliminate >> dead-code paths in generated code. Meaning that specialization would >> be performed by JIT instead of at link time. Perhaps this would have >> the same max. performance with simplified wiring logic... >> >> What do you think? > > This is what I meant by "simplified wiring logic": > > http://cr.openjdk.java.net/~plevart/jdk-dev/8222852_StringConcatOpt/webrev.02p/ > > > I haven't tried this though, but if it works correctly and if JIT > inlines the strategy for each call site, it should also eliminate the > dead code paths that are detected from null/non-null bound constants and > the end result should be equivalent machine code. But that's just in > theory... thanks for picking this up and experimenting further with it! I believe this would reduce the theoretical max number of prependers we need to link from 28 to 7, and from 4 to 1 lambdas, which is nice, but also a pretty limited gain in practice. And that small gain might be eaten up by the fact every prepender would be the result of binding 2 arguments (null or non-null) to a base prepender MH. Binding operations aren't too expensive once the species and LF classes needed has been loaded/generated, but they're not free, so we want to avoid it if possible. So I think we'd be trading a small, very limited overhead for a similar but harder to estimate overhead elsewhere. And I suspect we'd end up instances of the exact same shared LF class with your patch and that we'd see profile pollution between call-sites that would mean the JIT can't DCE the extra branches, which might degrade performance somewhat when measuring something that mix say "foo" + bar + bar and bar + "foo" + bar I've cleaned up my continued experiments a bit, but won't be able to get it through any more thorough testing until Tuesday: http://cr.openjdk.java.net/~redestad/8222852/open.02_alt/ Due to the fact that String concatenation will require fewer species classes in general - and since we decide what to pre-generate at build- time based on the result of running a purpose-built utility - the static size of lib/modules actually shrinks somewhat (~5Kb) with this patch. /Claes From claes.redestad at oracle.com Mon Apr 29 09:34:11 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 29 Apr 2019 11:34:11 +0200 Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: <0f8c65c5-cc12-f7e5-8195-f180890b7e11@oracle.com> References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> <05526f62-727a-6b53-b15f-a8df3a1cb688@redhat.com> <2fd250ee-8711-75ec-0418-3caeeb1a0983@oracle.com> <5c57e296-f847-e090-d247-4b3455b9d252@oracle.com> <449bde44-e91f-295c-7f6f-c52cc11810d4@gmail.com> <0f8c65c5-cc12-f7e5-8195-f180890b7e11@oracle.com> Message-ID: <0b5e46f7-8735-23a9-e10b-eec9c78af28b@oracle.com> Hi Peter, On 2019-04-28 23:34, Claes Redestad wrote: >>> >>> What do you think? >> >> This is what I meant by "simplified wiring logic": >> >> http://cr.openjdk.java.net/~plevart/jdk-dev/8222852_StringConcatOpt/webrev.02p/ >> >> >> I haven't tried this though, but if it works correctly and if JIT >> inlines the strategy for each call site, it should also eliminate the >> dead code paths that are detected from null/non-null bound constants >> and the end result should be equivalent machine code. But that's just >> in theory... > > thanks for picking this up and experimenting further with it! having run the numbers on your patch, I'm warming to this approach: - It seems the branches testing for null do get eliminated (no regressions in neither existing nor new micro trying to provoke pollution between LFs) - Startup numbers generally a bit better, and the amortized/repeated bootstrap cost of always binding in prefix and suffix appears to be insignificant - The logic for handling constants is nicer and less spread out; bonus points for folding successive suffix constants! http://cr.openjdk.java.net/~redestad/8222852/open.03/ I merged some of the cleanups and comments and think this is good to go rather than splitting it up into a follow-up RFE. Thanks! /Claes From adam.farley at uk.ibm.com Mon Apr 29 10:15:59 2019 From: adam.farley at uk.ibm.com (Adam Farley8) Date: Mon, 29 Apr 2019 11:15:59 +0100 Subject: RFR: JDK-8222930: ConcurrentSkipListMapTest.clone() broken since jdk10 In-Reply-To: References: Message-ID: Hi All, Reviews and feedback requested for the fix. http://cr.openjdk.java.net/~afarley/8222930.1/jdk13/webrev Martin: Thanks for the testcase. I've replaced the old test in the webrev with your generalized one. :) Best Regards Adam Farley IBM Runtimes Adam Farley8/UK/IBM wrote on 25/04/2019 13:47:13: > From: Adam Farley8/UK/IBM > To: Stuart Marks > Cc: Java Core Libs > Date: 25/04/2019 13:47 > Subject: Re: RFR: JDK-8222930: ConcurrentSkipListMapTest.clone() > broken since jdk10 > > Hi Stuart, > > Whoops, typo. Thanks for catching that. > > Ditto for Martin, who has modified the bug. :) > > Best Regards > > Adam Farley > IBM Runtimes > > Stuart Marks wrote on 24/04/2019 17:59:17: > > > From: Stuart Marks > > To: Adam Farley8 > > Cc: Java Core Libs > > Date: 24/04/2019 17:59 > > Subject: Re: RFR: JDK-8222930: ConcurrentSkipListMapTest.clone() > > broken since jdk10 > > > > Hi Adam, > > > > Thanks for finding this bug! > > > > This is a bug in ConcurrentSkipListMap itself, not some test named > > ConcurrentSkipListMapTest. I'd suggest changing the bug summary > line and the > > commit message accordingly. > > > > Thanks, > > > > s'marks > > > > On 4/24/19 9:20 AM, Adam Farley8 wrote: > > > ConcurrentSkipListMapTest.clone() produces a clone that shares the array > > > size variable of the original, and then doubles it. > > > > > > So both arrays, original and clone, tell the user that each is twice as > > > big as it actually is. > > > > > > The proposed fix is to simply set the clone's array size variable to null > > > during creation. > > > > > > Fix and test code available. > > > > > > Reviews and sponsor requested. > > > > > > Webrev: https://urldefense.proofpoint.com/v2/url? > > u=http-3A__cr.openjdk.java.net_-7Eafarley_8222930. > > 0_jdk13_webrev_&d=DwICaQ&c=jf_iaSHvJObTbx-siA1ZOg&r=P5m8KWUXJf- > > > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=9_BHLxc2OwO4OJABunATso0Ej3_keQ0c5uQJZ4AwSfk&s=0gBgd8gUhNlM26eNWxBbpnIAsFJPwnOtsmT6qH72NPM&e= > > > > > > Bug: https://urldefense.proofpoint.com/v2/url? > > > u=https-3A__bugs.openjdk.java.net_browse_JDK-2D8222930&d=DwICaQ&c=jf_iaSHvJObTbx- > > siA1ZOg&r=P5m8KWUXJf- > > > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=9_BHLxc2OwO4OJABunATso0Ej3_keQ0c5uQJZ4AwSfk&s=vNk7C72hr8FqiYLJEVvCR69vlhPuT7zSIAiJ9Tl91JQ&e= > > > > > > Best Regards > > > > > > Adam Farley > > > IBM Runtimes > > > > > > P.S. Apparently this has been broken since JDK 10, so we should look at > > > backporting (at least to 11 and 12) once this is in. > > > > > > Unless stated otherwise above: > > > IBM United Kingdom Limited - Registered in England and Wales with number > > > 741598. > > > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU > > > > > > > Unless stated otherwise above: > IBM United Kingdom Limited - Registered in England and Wales with > number 741598. > Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From forax at univ-mlv.fr Mon Apr 29 11:36:20 2019 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 29 Apr 2019 13:36:20 +0200 (CEST) Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: <0b5e46f7-8735-23a9-e10b-eec9c78af28b@oracle.com> References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> <5c57e296-f847-e090-d247-4b3455b9d252@oracle.com> <449bde44-e91f-295c-7f6f-c52cc11810d4@gmail.com> <0f8c65c5-cc12-f7e5-8195-f180890b7e11@oracle.com> <0b5e46f7-8735-23a9-e10b-eec9c78af28b@oracle.com> Message-ID: <398494373.134336.1556537780848.JavaMail.zimbra@u-pem.fr> That's nice ! In StringConcatFactory, i will change prefixConstant + constantValue (resp suffixConstant + constantValue) to prefixConstant.concat(constantValue) to not depend on any string concat implementations of javac. regards, R?mi ----- Mail original ----- > De: "Claes Redestad" > ?: "Peter Levart" , "Aleksey Shipilev" , "core-libs-dev" > > Envoy?: Lundi 29 Avril 2019 11:34:11 > Objet: Re: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers > Hi Peter, > > On 2019-04-28 23:34, Claes Redestad wrote: >>>> >>>> What do you think? >>> >>> This is what I meant by "simplified wiring logic": >>> >>> http://cr.openjdk.java.net/~plevart/jdk-dev/8222852_StringConcatOpt/webrev.02p/ >>> >>> >>> I haven't tried this though, but if it works correctly and if JIT >>> inlines the strategy for each call site, it should also eliminate the >>> dead code paths that are detected from null/non-null bound constants >>> and the end result should be equivalent machine code. But that's just >>> in theory... >> >> thanks for picking this up and experimenting further with it! > > having run the numbers on your patch, I'm warming to this approach: > > - It seems the branches testing for null do get eliminated (no > regressions in neither existing nor new micro trying to provoke > pollution between LFs) > - Startup numbers generally a bit better, and the amortized/repeated > bootstrap cost of always binding in prefix and suffix appears to be > insignificant > - The logic for handling constants is nicer and less spread out; bonus > points for folding successive suffix constants! > > http://cr.openjdk.java.net/~redestad/8222852/open.03/ > > I merged some of the cleanups and comments and think this is good to > go rather than splitting it up into a follow-up RFE. > > Thanks! > > /Claes From claes.redestad at oracle.com Mon Apr 29 14:57:45 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 29 Apr 2019 16:57:45 +0200 Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: <398494373.134336.1556537780848.JavaMail.zimbra@u-pem.fr> References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> <5c57e296-f847-e090-d247-4b3455b9d252@oracle.com> <449bde44-e91f-295c-7f6f-c52cc11810d4@gmail.com> <0f8c65c5-cc12-f7e5-8195-f180890b7e11@oracle.com> <0b5e46f7-8735-23a9-e10b-eec9c78af28b@oracle.com> <398494373.134336.1556537780848.JavaMail.zimbra@u-pem.fr> Message-ID: <0d8b8d0b-b428-f02f-48c6-40487483ab3b@oracle.com> Hi R?mi, On 2019-04-29 13:36, Remi Forax wrote: > That's nice ! thanks for reviewing! > > In StringConcatFactory, i will change > prefixConstant + constantValue (resp suffixConstant + constantValue) > to > prefixConstant.concat(constantValue) > > to not depend on any string concat implementations of javac. It has some strange appeal, but it isn't necessary (java.base is explicitly excluded from using ISC). - We use regular concatenation in a few places in StringConcatFactory already - Removing all cycles (to make it possible to compile java.base with ISC enabled?) wouldn't be enough: we'd need to enforce nothing creeps back in in all code StringConcatFactory depends on (which includes much of java.lang.invoke and ASM). Not impossible, but impractical. /Claes From forax at univ-mlv.fr Mon Apr 29 15:22:52 2019 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Mon, 29 Apr 2019 17:22:52 +0200 (CEST) Subject: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers In-Reply-To: <0d8b8d0b-b428-f02f-48c6-40487483ab3b@oracle.com> References: <640ca419-f4b4-bac2-0ee2-3312569cdfba@oracle.com> <5c57e296-f847-e090-d247-4b3455b9d252@oracle.com> <449bde44-e91f-295c-7f6f-c52cc11810d4@gmail.com> <0f8c65c5-cc12-f7e5-8195-f180890b7e11@oracle.com> <0b5e46f7-8735-23a9-e10b-eec9c78af28b@oracle.com> <398494373.134336.1556537780848.JavaMail.zimbra@u-pem.fr> <0d8b8d0b-b428-f02f-48c6-40487483ab3b@oracle.com> Message-ID: <101248439.197218.1556551372473.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Claes Redestad" > ?: "Remi Forax" > Cc: "Peter Levart" , "Aleksey Shipilev" , "core-libs-dev" > > Envoy?: Lundi 29 Avril 2019 16:57:45 > Objet: Re: RFR: 8222852: Reduce String concat combinator tree shapes by folding constants into prependers > Hi R?mi, > > On 2019-04-29 13:36, Remi Forax wrote: >> That's nice ! > > thanks for reviewing! > >> >> In StringConcatFactory, i will change >> prefixConstant + constantValue (resp suffixConstant + constantValue) >> to >> prefixConstant.concat(constantValue) >> >> to not depend on any string concat implementations of javac. > > It has some strange appeal, but it isn't necessary (java.base is > explicitly excluded from using ISC). > > - We use regular concatenation in a few places in StringConcatFactory > already > - Removing all cycles (to make it possible to compile java.base with > ISC enabled?) wouldn't be enough: we'd need to enforce nothing creeps > back in in all code StringConcatFactory depends on (which includes much > of java.lang.invoke and ASM). Not impossible, but impractical. If we add lazy static final fields, we may need to define a subset of java.base, the set of classes needed to bootstrap the VM until indy/condy are available. Clearly java.base is too big and having classes of java.util or java.util.concurrent not being able to declare their constant lazy is a waste. I'm dreaming about an annotation that you have to set on classes that are part of the initialization sequence, it will be so helpful even if it's just for the documentation purpose. so you are right that some classes of java.base will never use the StringConcatFactory but others in java.base may use it in the future. > > /Claes R?mi From erik.joelsson at oracle.com Mon Apr 29 16:21:54 2019 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Mon, 29 Apr 2019 09:21:54 -0700 Subject: RFR: JDK-8212780: JEP 343: Packaging Tool Implementation In-Reply-To: <5CC4F7E0.7020208@oracle.com> References: <0bd5501f-9db0-f22a-c4f1-4e284a43021f@oracle.com> <3da2c640-8fad-335b-9696-69f45e1a1024@oracle.com> <5CC4F7E0.7020208@oracle.com> Message-ID: Hello, We did review build changes as they were done in the sandbox, but IMO this change needs a fresh review now since some things have changed in the build since those reviews took place. CompileJavaModules.gmk: The -parameters flag to javac is currently only used for jdk.aot and jdk.internal.vm.ci, where a comment is explaining why its needed in those particular cases. Why is it needed for jdk.jpackage? We would like to avoid snowflakes if possible. Modules.gmk: There is a new set of macros that should be used to check things like target OS. The new macro is called like this: ifeq ($(call isTargetOs, windows macosx linux), false) Lib-jdk.jpackage.gmk and Launcher-jdk.jpackage.gmk: Same thing with checking for target OS: ifeq ($(call isTargetOs, windows), true) Otherwise this looks good from a build perspective. /Erik On 2019-04-27 17:46, Philip Race wrote: > Adding build-dev for the build changes. I don't know if these were > previously reviewed there, > but I am not sure what the changes in NativeCompilation.gmk have to do > with jpackage. > > -phil. > > On 4/24/19, 5:47 PM, Andy Herrick wrote: >> >> On 4/24/2019 8:44 PM, Andy Herrick wrote: >>> Please review? changes for [1] which is the implementation bug for >>> JEP-343. >>> >>> The webrev at [2] is the total cumulative webrev of changes for the >>> jpackage tool, currently in the JDK-8200758-branch branch of the >>> open sandbox repository. >>> >>> The webrev at [3] shows the changes from EA-05 to EA-06. >> sorry - the links are reversed from what is stated above. [2] is the >> incremental webrev since EA 05, [3] is the cumulativewebrev >> /Andy >>> >>> The latest EA-6 (build 49) is posted at [4]. >>> >>> Please send feedback to core-libs-dev at openjdk.java.net >>> >>> >>> [1] https://bugs.openjdk.java.net/browse/JDK-8200758 >>> >>> [2] http://cr.openjdk.java.net/~herrick/8212780/webrev.05-06/ >>> >>> [3] http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/ >>> >>> [4] http://jdk.java.net/jpackage/ >>> >>> >>> /Andy >>> >>> >> From martinrb at google.com Mon Apr 29 16:39:57 2019 From: martinrb at google.com (Martin Buchholz) Date: Mon, 29 Apr 2019 09:39:57 -0700 Subject: RFR: 8223078: Add microbenchmark for array copying/clearing/resizing Message-ID: 8223078: Add microbenchmark for array copying/clearing/resizing https://cr.openjdk.java.net/~martin/webrevs/jdk/ArrayFiddle-jmh/ https://bugs.openjdk.java.net/browse/JDK-8223078 From dl at cs.oswego.edu Mon Apr 29 16:49:19 2019 From: dl at cs.oswego.edu (Doug Lea) Date: Mon, 29 Apr 2019 12:49:19 -0400 Subject: RFR: 8223078: Add microbenchmark for array copying/clearing/resizing In-Reply-To: References: Message-ID: <9830dde4-6a3b-7b6b-2cd6-f8cef52ccf13@cs.oswego.edu> On 4/29/19 12:39 PM, Martin Buchholz wrote: > 8223078: Add microbenchmark for array copying/clearing/resizing > https://cr.openjdk.java.net/~martin/webrevs/jdk/ArrayFiddle-jmh/ > https://bugs.openjdk.java.net/browse/JDK-8223078 > Looks good, although even more informative would be to try some different sizes to see if there are any size-dependent trends. -Doug From martinrb at google.com Mon Apr 29 17:03:53 2019 From: martinrb at google.com (Martin Buchholz) Date: Mon, 29 Apr 2019 10:03:53 -0700 Subject: RFR: 8223078: Add microbenchmark for array copying/clearing/resizing In-Reply-To: <9830dde4-6a3b-7b6b-2cd6-f8cef52ccf13@cs.oswego.edu> References: <9830dde4-6a3b-7b6b-2cd6-f8cef52ccf13@cs.oswego.edu> Message-ID: On Mon, Apr 29, 2019 at 9:49 AM Doug Lea

              wrote: > On 4/29/19 12:39 PM, Martin Buchholz wrote: > > 8223078: Add microbenchmark for array copying/clearing/resizing > > https://cr.openjdk.java.net/~martin/webrevs/jdk/ArrayFiddle-jmh/ > > https://bugs.openjdk.java.net/browse/JDK-8223078 > > > > Looks good, although even more informative would be to try some > different sizes to see if there are any size-dependent trends. > A future enhancement could be to @Param-ize the SIZE. doc/testing.md should explain how to set @Param values using make - it's not obvious. From andy.herrick at oracle.com Mon Apr 29 17:19:28 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Mon, 29 Apr 2019 13:19:28 -0400 Subject: RFR: JDK-8212780: JEP 343: Packaging Tool Implementation In-Reply-To: References: <0bd5501f-9db0-f22a-c4f1-4e284a43021f@oracle.com> <3da2c640-8fad-335b-9696-69f45e1a1024@oracle.com> <5CC4F7E0.7020208@oracle.com> Message-ID: <19f1ecec-b932-f096-95ea-5cf0c7c1c365@oracle.com> On 4/29/2019 12:21 PM, Erik Joelsson wrote: > There is a new set of macros that should be used to check things like > target OS. The new macro is called like this: > > ifeq ($(call isTargetOs, windows macosx linux), false) > > Lib-jdk.jpackage.gmk and Launcher-jdk.jpackage.gmk: > > Same thing with checking for target OS: > > ifeq ($(call isTargetOs, windows), true) > > Otherwise this looks good from a build perspective. I have filed JDK-8223080 to address this. /Andy From martinrb at google.com Mon Apr 29 18:00:54 2019 From: martinrb at google.com (Martin Buchholz) Date: Mon, 29 Apr 2019 11:00:54 -0700 Subject: RFR: jsr166 integration 2019-05 Message-ID: https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/overview.html 8222930: ConcurrentSkipListMap.clone() shares size variable between original and clone https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/ConcurrentSkipListMap.clone/index.html https://bugs.openjdk.java.net/browse/JDK-8222930 A real bug fix! Apologies to Adam for re-routing through jsr166 CVS. Adam, that loop is now written in Adam style. 8221120: CopyOnWriteArrayList.set should always have volatile write semantics https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/CopyOnWriteArrayList.set/index.html https://bugs.openjdk.java.net/browse/JDK-8221120 8221892: ThreadPoolExecutor: Thread.isAlive() is not equivalent to not being startable https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/isAlive/index.html https://bugs.openjdk.java.net/browse/JDK-8221892 8220248: fix headings in java.util.concurrent https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/h3/index.html https://bugs.openjdk.java.net/browse/JDK-8220248 8203662: remove increment of modCount from ArrayList and Vector replaceAll() https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/replaceAll/index.html https://bugs.openjdk.java.net/browse/JDK-8203662 This one remains in limbo. Some impartial openjdk steward should cast a tiebreaker vote or appoint someone impartial to cast a tiebreaker vote. 8219138: Miscellaneous changes imported from jsr166 CVS 2019-05 https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/miscellaneous/index.html From vicente.romero at oracle.com Mon Apr 29 21:41:35 2019 From: vicente.romero at oracle.com (Vicente Romero) Date: Mon, 29 Apr 2019 17:41:35 -0400 Subject: RFR: JDK-8219483: j.l.c.ClassDesc::nested(String, String...) doesn't throw NPE if any arg is null In-Reply-To: <9b0ea90c-ddca-ab76-caf0-c41e2b56aa2c@oracle.com> References: <7b71bdb8-53cb-fdd3-eca4-4e4ba89fe5a4@oracle.com> <9b0ea90c-ddca-ab76-caf0-c41e2b56aa2c@oracle.com> Message-ID: <042c4118-e6c2-8094-6b8e-d38c519b0196@oracle.com> Hi Joe, Thanks for the review. I have modified the patch, please see [1] . I still need a reviewer for the CSR [2], Vicente [1] http://cr.openjdk.java.net/~vromero/8219483/webrev.01/ [2] https://bugs.openjdk.java.net/browse/JDK-8223034 On 4/26/19 9:32 PM, Joe Darcy wrote: > Hi Vicente, > > For purposes of a better exception message, do you want to explicitly > check moreNestedNames for null in some way before accessing its > contents? Also, I'd commend the spec be updated slightly to > > ??? @throws NullPointerException if any argument or its contents is > {@code null} > > assuming the desired behavior is a NPE if an element of > moreNestedNames is null as opposed to ust moreNestedNames itself. > > Thanks, > > -Joe > > On 4/26/2019 9:33 AM, Vicente Romero wrote: >> Hi, >> >> Please review fix [1] and CSR [2] for [3]. The API for method >> j.l.c.ClassDesc::nested(String, String...) states that it should >> throw NPE if any of the arguments is null. The implementation is not >> in sync with the API and should be corrected, >> >> Thanks, >> Vicente >> >> [1] http://cr.openjdk.java.net/~vromero/8219483/webrev.00/ >> [2] https://bugs.openjdk.java.net/browse/JDK-8223034 >> [3] https://bugs.openjdk.java.net/browse/JDK-8219483 >> From claes.redestad at oracle.com Mon Apr 29 21:56:24 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 29 Apr 2019 23:56:24 +0200 Subject: RFR: 8223078: Add microbenchmark for array copying/clearing/resizing In-Reply-To: References: <9830dde4-6a3b-7b6b-2cd6-f8cef52ccf13@cs.oswego.edu> Message-ID: <1b5a7d4b-a277-a3f7-e444-db88b33ecda1@oracle.com> On 2019-04-29 19:03, Martin Buchholz wrote: > > On Mon, Apr 29, 2019 at 9:49 AM Doug Lea
              > wrote: > > On 4/29/19 12:39 PM, Martin Buchholz wrote: > > 8223078: Add microbenchmark for array copying/clearing/resizing > > https://cr.openjdk.java.net/~martin/webrevs/jdk/ArrayFiddle-jmh/ > > https://bugs.openjdk.java.net/browse/JDK-8223078 > > > > Looks good, although even more informative would be to try some > different sizes to see if there are any size-dependent trends. > > > A future enhancement could be to?@Param-ize the SIZE. > doc/testing.md should explain how to set?@Param values using make - it's > not obvious. This should work: make test TEST="micro:foo" MICRO="OPTIONS=-p SIZE=1024,2048" /Claes From andy.herrick at oracle.com Mon Apr 29 21:58:19 2019 From: andy.herrick at oracle.com (Andy Herrick) Date: Mon, 29 Apr 2019 17:58:19 -0400 Subject: RFR: JDK-8212780: JEP 343: Packaging Tool Implementation In-Reply-To: <0bd5501f-9db0-f22a-c4f1-4e284a43021f@oracle.com> References: <0bd5501f-9db0-f22a-c4f1-4e284a43021f@oracle.com> Message-ID: <35c5208f-449b-8df2-d652-adb7f77e3ca2@oracle.com> jpackage reviewers: We hope to move JEP 343 to "Proposed to Target" next week, so we would like expedite the review process as much as possible. The total change is huge, so I am including the below descriptions of some of the central and important classes included: jdk.jpackage.main.Main: ??? Everything starts with either Main.main() (or JPackageToolProvider.run() which calls Main.run()), but nothing other than processing @filename, --help, and --version, is done in Main.? The real work of jpackager is delegated to Arguments.processArguments(). jdk.jpackage.internal.Arguments: ??? Arguments.processArguments() processes each arg, filling the DeployParams object with the produced BundleArguments.? The DeployParams are then used to create a BundleParams object. Arguments.generateBundle() is then called with a Map of the BundleParams to actually do the work.??? Argument.generateBundle() then calls the execute() method of each required Bundler. The Parameters: ??? A BundlerParamInfo object exists for every parameter (be it a StandardBundlerParam, or one specific to a given Bundler).? These each contain the function for extracting the id, value type, value, and default value for the parameter, as well as various methods to convert to/from Strings.? Each is defined as a static final object (again in either StandardBundlerParam or one of the Bundlers) so it's name can be used to fetch its value and type. The initial list of parameters is passed to the Bundler as argument to the execute() method called by Argument.generateBundle(). The Bundlers: ??? Each platform has a collection of Bundlers, one for an Application Image, and one for each available installer type, all of which ultimately implement the Bundler interface.? For example, on windows there is WinAppBundler, WinMsiBundler, and WinExeBundler. Application Image Bundlers: ??? The Application Image Bundlers? extend AbstractImageBundler which in turn extends AbstractBundler which implements the Bundler interface.? They? will gather? the application resources, create the cfg file, and may call JLinkBundlerHelper.execute() where jlink itself will be called via the ToolProvider interface to construct the java runtime to include in the application image. (If a pre defined runtime image is provided it will be copied in as is, instead of created in JLinkBundlerHelper). Application Installer Bundlers: ??? Each Platform dependent installer-type has an associated Bundler that Extends AbstractBundler (either directly or indirectly).? This Bundler will generally prepare some specific resource template using fetchResource() or preprocessTextResource (in AbstractBundler) .? This is where user can use --resourceDir option to override the template for a specific installer type with a templat of his own.? The processed templates become input to the program that generates the installer.? An exception of this is on MacOSX, when the Info.plist must be part of the application image, so the Info.plist.template is processed when generating the Application Image Bundle, rather than when processing the Application Installer Bundler. Resources: ??? All localizable Strings are in jdk/jpackage/internal/resources, either in HelpResources.properties, MainResources.properties, or the platform dependent Resources.properties.? The "-ja" and "-zh_CN" are just copies of the english files at this time, and will be localized after this code is integrated into the JDK. Please feel free to post any questions to me while reviewing this code. /Andy On 4/24/2019 8:44 PM, Andy Herrick wrote: > Please review? changes for [1] which is the implementation bug for > JEP-343. > > The webrev at [2] is the total cumulative webrev of changes for the > jpackage tool, currently in the JDK-8200758-branch branch of the open > sandbox repository. > > The webrev at [3] shows the changes from EA-05 to EA-06. > > The latest EA-6 (build 49) is posted at [4]. > > Please send feedback to core-libs-dev at openjdk.java.net > > > [1] https://bugs.openjdk.java.net/browse/JDK-8200758 > > [2] http://cr.openjdk.java.net/~herrick/8212780/webrev.05-06/ > > [3] http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/ > > [4] http://jdk.java.net/jpackage/ > > > /Andy > > From huizhe.wang at oracle.com Mon Apr 29 22:03:56 2019 From: huizhe.wang at oracle.com (Joe Wang) Date: Mon, 29 Apr 2019 15:03:56 -0700 Subject: RFR(JDK 13/java.xml) 8222991: Xerces 2.12.0: Validation Message-ID: <5CC774CC.6040008@oracle.com> Please review an update on the Validation implementation. All XML tests and JCK passed. JBS: https://bugs.openjdk.java.net/browse/JDK-8222991 webrevs: http://cr.openjdk.java.net/~joehw/jdk13/8222991/webrev/ Thanks, Joe From ivan.gerasimov at oracle.com Tue Apr 30 04:07:22 2019 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Mon, 29 Apr 2019 21:07:22 -0700 Subject: RFR 8222955 : Optimize String.replace(CharSequence, CharSequence) for Latin1 encoded strings In-Reply-To: References: Message-ID: <7e1a73cc-3095-6535-277e-55a48938b3e6@oracle.com> Thank you Tagir for suggestion! On 4/26/19 1:24 AM, Tagir Valeev wrote: > Hello! > > Great optimization! > > + // overflow-conscious code > + int resultLen = valLen + (++p) * deltaLen; > + if (Integer.MAX_VALUE / p < deltaLen || > + Integer.MAX_VALUE - resultLen < 0) { > + throw new OutOfMemoryError(); > + } > > Is it really necessary to introduce unconditional division by unknown > divisor in the common path? Probably this would be better (common path > should be intrinsified)? > > int resultLen; > try { > resultLen = Math.addExact(valLen, Math.multiplyExact(++p, deltaLen)); > } > catch(ArithmeticException ignored) { > throw new OutOfMemoryError(); > } Personally, I like it better to see plain 32 arithmetic (assuming it is correct, of course), but I agree that using Math.xxxExact() here improves readability. Moreover, it turns out to give measurable performance improvement! Shortly, I'll send the updated webrev with this suggestion included and with some more additional work. Thanks again, Ivan > Or alternatively > long resultLenLong = ((long)(++p)) * deltaLen + valLen; // long never > overflows here > int resultLen = (int)resultLenLong; > if (resultLenLong != resultLen) { > throw new OutOfMemoryError(); > } > > With best regards, > Tagir Valeev. > > On Thu, Apr 25, 2019 at 1:01 PM Ivan Gerasimov > wrote: >> Hello! >> >> This enhancement was inspired by a recent discussion at >> compiler-dev at openjdk.java.net. >> >> It seems to be a non-uncommon situation when String.replace(CS, CS) is >> called with this and both arguments being Latin1 strings, so it seems >> reasonable to optimize for such case. >> >> Here are the fresh benchmark results (see the webrev for the source of >> the benchmark): >> -- prior the fix: >> Benchmark Mode Cnt Score Error Units >> StringReplace.replace1_0 avgt 24 70.860 ? 5.239 ns/op >> StringReplace.replace1_1 avgt 24 82.661 ? 1.007 ns/op >> StringReplace.replace1_2 avgt 24 97.251 ? 1.186 ns/op >> >> -- after the fix: >> Benchmark Mode Cnt Score Error Units >> StringReplace.replace1_0 avgt 24 52.855 ? 0.982 ns/op >> StringReplace.replace1_1 avgt 24 23.849 ? 0.066 ns/op >> StringReplace.replace1_2 avgt 24 62.266 ? 0.552 ns/op >> >> So the speedup was x1.3, x3.4, x1.5. >> >> Would you please help review the fix? >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8222955 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8222955/00/webrev/ >> >> Mach5 job is in progress and looks green so far (a few test groups are >> left). >> >> Thanks in advance! >> >> -- >> With kind regards, >> Ivan Gerasimov >> -- With kind regards, Ivan Gerasimov From ivan.gerasimov at oracle.com Tue Apr 30 04:10:28 2019 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Mon, 29 Apr 2019 21:10:28 -0700 Subject: RFR 8222955 : Optimize String.replace(CharSequence, CharSequence) for Latin1 encoded strings In-Reply-To: References: Message-ID: <8ea2767b-dd44-c923-e48f-ff795832c3b0@oracle.com> Hi Claes! On 4/25/19 4:51 AM, Claes Redestad wrote: > Hi Ivan, > > the changes and fast-path speed-ups look reasonable, but I'd like to see > that the overhead for cases not helped by the fast paths isn't > excessive, e.g., micro variants with UTF16 Strings and a mix of Latin1 > and UTF16. > Good point! After adding a few more micro-benchmarks with UTF16 strings, I realized that it can actually make sense to improve the UTF16/mixed branch as well. I'll send the updated webrev shortly. With kind regards, Ivan > /Claes > > On 2019-04-25 08:00, Ivan Gerasimov wrote: >> Hello! >> >> This enhancement was inspired by a recent discussion at >> compiler-dev at openjdk.java.net. >> >> It seems to be a non-uncommon situation when String.replace(CS, CS) >> is called with this and both arguments being Latin1 strings, so it >> seems reasonable to optimize for such case. >> >> Here are the fresh benchmark results (see the webrev for the source >> of the benchmark): >> -- prior the fix: >> Benchmark Mode Cnt Score Error Units >> StringReplace.replace1_0 avgt 24 70.860 ? 5.239 ns/op >> StringReplace.replace1_1 avgt 24 82.661 ? 1.007 ns/op >> StringReplace.replace1_2 avgt 24 97.251 ? 1.186 ns/op >> >> -- after the fix: >> Benchmark Mode Cnt Score Error Units >> StringReplace.replace1_0 avgt 24 52.855 ? 0.982 ns/op >> StringReplace.replace1_1 avgt 24 23.849 ? 0.066 ns/op >> StringReplace.replace1_2 avgt 24 62.266 ? 0.552 ns/op >> >> So the speedup was x1.3, x3.4, x1.5. >> >> Would you please help review the fix? >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8222955 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8222955/00/webrev/ >> >> Mach5 job is in progress and looks green so far (a few test groups >> are left). >> >> Thanks in advance! >> > -- With kind regards, Ivan Gerasimov From ivan.gerasimov at oracle.com Tue Apr 30 04:43:49 2019 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Mon, 29 Apr 2019 21:43:49 -0700 Subject: RFR 8222955 : Optimize String.replace(CharSequence, CharSequence) for Latin1 encoded strings In-Reply-To: References: Message-ID: <2bb0ea29-9b92-f9d2-7b26-ad56f01203b5@oracle.com> Hello everyone! Please help review the second version of the enhancement. A separate branch was added to handle UTF16 in the searched string and/or in the target and replacement. Switching to Math.xxxExact() suggested by Tagir gave ~4% of throughput on affected test cases. Also, allocating uninitialized array added ~7% for Latin1 strings. I used StringConcatHelper.newArray() to avoid bringing Unsafe into StringLatin1. In the StringLatin1.replace(), the newly allocated array is guaranteed to be filled up, and the filling code should never throw, so I believe using uninitialized arrays here is justified. Here's the updated webrev: http://cr.openjdk.java.net/~igerasim/8222955/01/webrev/ Below please find the benchmark numbers (with an additional column, showing the improvement.) Surprisingly, in one test case a slowdown was observed: Only for Latin1 string, with 1-char target, when the target string was *not* found. If I understood it correctly, this is because prior the fix the intrinsified StringLatin1.indexOf(byte[], byte[]) was called on the first place, so there were effectively a fast path for exactly this pattern. I'm not quite sure what to do about it. Maybe this is fine as it is, since the *average* improvement across different test cases is still good? - prior fix: Benchmark Mode Cnt Score Error Units *StringReplace.replace0x1_1_Latin1 avgt 15 7.116 ? 0.060 ns/op* StringReplace.replace0x1_1_UTF16 avgt 15 84.255 ? 3.381 ns/op *StringReplace.replace1x1_0_Latin1 avgt 15 63.254 ? 0.973 ns/op* StringReplace.replace1x1_0_UTF16 avgt 15 89.941 ? 3.210 ns/op *StringReplace.replace1x1_1_Latin1 avgt 15 75.662 ? 0.344 ns/op* StringReplace.replace1x1_1_UTF16 avgt 15 81.454 ? 1.986 ns/op *StringReplace.replace1x1_2_Latin1 avgt 15 89.492 ? 1.889 ns/op* StringReplace.replace1x1_2_UTF16 avgt 15 87.430 ? 1.341 ns/op *StringReplace.replace2x1_0_Latin1 avgt 15 69.575 ? 0.368 ns/op* StringReplace.replace2x1_0_UTF16 avgt 15 112.201 ? 2.836 ns/op *StringReplace.replace2x1_1_Latin1 avgt 15 83.841 ? 0.940 ns/op* StringReplace.replace2x1_1_UTF16 avgt 15 115.722 ? 2.267 ns/op *StringReplace.replace2x1_2_Latin1 avgt 15 99.266 ? 1.008 ns/op* StringReplace.replace2x1_2_UTF16 avgt 15 132.271 ? 2.365 ns/op - after fix: Benchmark Mode Cnt Score Error Units *StringReplace.replace0x1_1_Latin1 avgt 15 10.541 ? 0.826 ns/op x0.68* StringReplace.replace0x1_1_UTF16 avgt 15 31.473 ? 0.389 ns/op x2.68 *StringReplace.replace1x1_0_Latin1 avgt 15 50.455 ? 5.038 ns/op x1.25* StringReplace.replace1x1_0_UTF16 avgt 15 35.355 ? 0.074 ns/op x2.54 *StringReplace.replace1x1_1_Latin1 avgt 15 22.868 ? 0.076 ns/op x3.31* StringReplace.replace1x1_1_UTF16 avgt 15 22.290 ? 1.913 ns/op x3.65 *StringReplace.replace1x1_2_Latin1 avgt 15 51.362 ? 0.130 ns/op x1.74* StringReplace.replace1x1_2_UTF16 avgt 15 33.086 ? 0.088 ns/op x2.64 *StringReplace.replace2x1_0_Latin1 avgt 15 57.169 ? 7.165 ns/op x1.22* StringReplace.replace2x1_0_UTF16 avgt 15 50.886 ? 1.193 ns/op x2.20 *StringReplace.replace2x1_1_Latin1 avgt 15 23.320 ? 2.954 ns/op x3.60* StringReplace.replace2x1_1_UTF16 avgt 15 24.741 ? 0.229 ns/op x4.68 *StringReplace.replace2x1_2_Latin1 avgt 15 56.045 ? 0.153 ns/op x1.77* StringReplace.replace2x1_2_UTF16 avgt 15 49.795 ? 0.178 ns/op x2.66 -- With kind regards, Ivan Gerasimov From peter.levart at gmail.com Tue Apr 30 07:36:12 2019 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 30 Apr 2019 09:36:12 +0200 Subject: RFR 8222955 : Optimize String.replace(CharSequence, CharSequence) for Latin1 encoded strings In-Reply-To: <2bb0ea29-9b92-f9d2-7b26-ad56f01203b5@oracle.com> References: <2bb0ea29-9b92-f9d2-7b26-ad56f01203b5@oracle.com> Message-ID: <75d85550-f2df-e8ec-519d-2cf37d7534b7@gmail.com> On 4/30/19 6:43 AM, Ivan Gerasimov wrote: > I used StringConcatHelper.newArray() to avoid bringing Unsafe into > StringLatin1. > In the StringLatin1.replace(), the newly allocated array is guaranteed > to be filled up, and the filling code should never throw, so I believe > using uninitialized arrays here is justified. ...even if it throwed (and throwing in the middle could be provoked with for example Thread.stop), the allocated array would not escape the function. So the method just has to guarantee that when it returns normally, all bytes of array have been overwritten and that the array is published securely (i.e. assigned to a final field of an object who's reference is returned from the method)... Peter From david.holmes at oracle.com Tue Apr 30 07:51:24 2019 From: david.holmes at oracle.com (David Holmes) Date: Tue, 30 Apr 2019 17:51:24 +1000 Subject: RFR: jsr166 integration 2019-05 In-Reply-To: References: Message-ID: <77f82966-5741-3a25-41b9-f2b685957211@oracle.com> Hi Martin, On 30/04/2019 4:00 am, Martin Buchholz wrote: > https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/overview.html > > 8222930: ConcurrentSkipListMap.clone() shares size variable between > original and clone > https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/ConcurrentSkipListMap.clone/index.html > https://bugs.openjdk.java.net/browse/JDK-8222930 > A real bug fix! > Apologies to Adam for re-routing through jsr166 CVS. > Adam, that loop is now written in Adam style. > > 8221120: CopyOnWriteArrayList.set should always have volatile write > semantics > https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/CopyOnWriteArrayList.set/index.html > https://bugs.openjdk.java.net/browse/JDK-8221120 > > 8221892: ThreadPoolExecutor: Thread.isAlive() is not equivalent to not > being startable > https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/isAlive/index.html > https://bugs.openjdk.java.net/browse/JDK-8221892 That one looks good to me. Thanks, David ----- > 8220248: fix headings in java.util.concurrent > https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/h3/index.html > https://bugs.openjdk.java.net/browse/JDK-8220248 > > 8203662: remove increment of modCount from ArrayList and Vector replaceAll() > https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/replaceAll/index.html > https://bugs.openjdk.java.net/browse/JDK-8203662 > This one remains in limbo. > Some impartial openjdk steward should cast a tiebreaker vote or appoint > someone impartial to cast a tiebreaker vote. > > 8219138: Miscellaneous changes imported from jsr166 CVS 2019-05 > https://cr.openjdk.java.net/~martin/webrevs/jdk/jsr166-integration/miscellaneous/index.html > From adam.farley at uk.ibm.com Tue Apr 30 09:35:23 2019 From: adam.farley at uk.ibm.com (Adam Farley8) Date: Tue, 30 Apr 2019 10:35:23 +0100 Subject: RFR: jsr166 integration 2019-05 In-Reply-To: <77f82966-5741-3a25-41b9-f2b685957211@oracle.com> References: <77f82966-5741-3a25-41b9-f2b685957211@oracle.com> Message-ID: Hi Martin, Thanks for pushing this. :) I'm not familiar with the jsr166 CVS system though, or the process of aiding a commit to it. Is there anything further I can do here? Best Regards Adam Farley IBM Runtimes David Holmes wrote on 30/04/2019 08:51:24: > From: David Holmes > To: Martin Buchholz , core-libs-dev dev at openjdk.java.net>, Doug Lea
              , Chris Hegarty > , Adam Farley8 , > Jonathan Gibbons > Date: 30/04/2019 08:52 > Subject: Re: RFR: jsr166 integration 2019-05 > > Hi Martin, > > On 30/04/2019 4:00 am, Martin Buchholz wrote: > > https://urldefense.proofpoint.com/v2/url? > u=https-3A__cr.openjdk.java.net_-7Emartin_webrevs_jdk_jsr166-2Dintegration_overview.html&d=DwICaQ&c=jf_iaSHvJObTbx- > siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=UyEQgUhk9l9hqIrxNx78GbVK6s9kwuLB__fHsbBQEM4&s=SK8eQrSdhQKsaQ2r_3pQeul3SMmsz6cVkfsxhnbVS_Q&e= > > > > 8222930: ConcurrentSkipListMap.clone() shares size variable between > > original and clone > > https://urldefense.proofpoint.com/v2/url? > u=https-3A__cr.openjdk.java.net_-7Emartin_webrevs_jdk_jsr166-2Dintegration_ConcurrentSkipListMap.clone_index.html&d=DwICaQ&c=jf_iaSHvJObTbx- > siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=UyEQgUhk9l9hqIrxNx78GbVK6s9kwuLB__fHsbBQEM4&s=Pk- > GWACLjrVblq0LJPSJn9LMoymdwz8L-UyVD4hcza4&e= > > https://urldefense.proofpoint.com/v2/url? > u=https-3A__bugs.openjdk.java.net_browse_JDK-2D8222930&d=DwICaQ&c=jf_iaSHvJObTbx- > siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=UyEQgUhk9l9hqIrxNx78GbVK6s9kwuLB__fHsbBQEM4&s=OdJwEcMXYxKvHyJFfQ7JXlHTZe1NQbKybtHdwFTF8Qo&e= > > A real bug fix! > > Apologies to Adam for re-routing through jsr166 CVS. > > Adam, that loop is now written in Adam style. > > > > 8221120: CopyOnWriteArrayList.set should always have volatile write > > semantics > > https://urldefense.proofpoint.com/v2/url? > u=https-3A__cr.openjdk.java.net_-7Emartin_webrevs_jdk_jsr166-2Dintegration_CopyOnWriteArrayList.set_index.html&d=DwICaQ&c=jf_iaSHvJObTbx- > siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=UyEQgUhk9l9hqIrxNx78GbVK6s9kwuLB__fHsbBQEM4&s=QvLJqZYjuKPZqHfa3MTlnEvSYod575jkOWVQRnL6nQk&e= > > https://urldefense.proofpoint.com/v2/url? > u=https-3A__bugs.openjdk.java.net_browse_JDK-2D8221120&d=DwICaQ&c=jf_iaSHvJObTbx- > siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=UyEQgUhk9l9hqIrxNx78GbVK6s9kwuLB__fHsbBQEM4&s=CPMrNrvCiJkQ1qQyvWoBET9DLP3M1h6NbOa33sMZZsA&e= > > > > 8221892: ThreadPoolExecutor: Thread.isAlive() is not equivalent to not > > being startable > > https://urldefense.proofpoint.com/v2/url? > u=https-3A__cr.openjdk.java.net_-7Emartin_webrevs_jdk_jsr166-2Dintegration_isAlive_index.html&d=DwICaQ&c=jf_iaSHvJObTbx- > siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=UyEQgUhk9l9hqIrxNx78GbVK6s9kwuLB__fHsbBQEM4&s=f2aPxCj5GYNPhtJ_fGMuXXyrE7aq2ExItMruyz4p0Ys&e= > > https://urldefense.proofpoint.com/v2/url? > u=https-3A__bugs.openjdk.java.net_browse_JDK-2D8221892&d=DwICaQ&c=jf_iaSHvJObTbx- > siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=UyEQgUhk9l9hqIrxNx78GbVK6s9kwuLB__fHsbBQEM4&s=cnWwTGAK7- > FRM2vkHC0WJU0qWjSthz66uW2wLOKZnb0&e= > > That one looks good to me. > > Thanks, > David > ----- > > > 8220248: fix headings in java.util.concurrent > > https://urldefense.proofpoint.com/v2/url? > u=https-3A__cr.openjdk.java.net_-7Emartin_webrevs_jdk_jsr166-2Dintegration_h3_index.html&d=DwICaQ&c=jf_iaSHvJObTbx- > siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=UyEQgUhk9l9hqIrxNx78GbVK6s9kwuLB__fHsbBQEM4&s=oiB9FHta2Qn9vmBSQ9hE- > lPA44QB_mE1UYlogLwu_98&e= > > https://urldefense.proofpoint.com/v2/url? > u=https-3A__bugs.openjdk.java.net_browse_JDK-2D8220248&d=DwICaQ&c=jf_iaSHvJObTbx- > siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=UyEQgUhk9l9hqIrxNx78GbVK6s9kwuLB__fHsbBQEM4&s=hRaFrU7cisY70PdMxnMTNy_NZuh_3fDQIoJKxq- > scog&e= > > > > 8203662: remove increment of modCount from ArrayList and Vector replaceAll() > > https://urldefense.proofpoint.com/v2/url? > u=https-3A__cr.openjdk.java.net_-7Emartin_webrevs_jdk_jsr166-2Dintegration_replaceAll_index.html&d=DwICaQ&c=jf_iaSHvJObTbx- > siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=UyEQgUhk9l9hqIrxNx78GbVK6s9kwuLB__fHsbBQEM4&s=UcfexeMYRSBugVy8Ds6v9U-6Gr9n4CmzXI12dFyg4S8&e= > > https://urldefense.proofpoint.com/v2/url? > u=https-3A__bugs.openjdk.java.net_browse_JDK-2D8203662&d=DwICaQ&c=jf_iaSHvJObTbx- > siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=UyEQgUhk9l9hqIrxNx78GbVK6s9kwuLB__fHsbBQEM4&s=HMokVlOU1G5G46RDE- > d2oXvKBWHVE7YHGhbWhcPhwdU&e= > > This one remains in limbo. > > Some impartial openjdk steward should cast a tiebreaker vote or appoint > > someone impartial to cast a tiebreaker vote. > > > > 8219138: Miscellaneous changes imported from jsr166 CVS 2019-05 > > https://urldefense.proofpoint.com/v2/url? > u=https-3A__cr.openjdk.java.net_-7Emartin_webrevs_jdk_jsr166-2Dintegration_miscellaneous_index.html&d=DwICaQ&c=jf_iaSHvJObTbx- > siA1ZOg&r=P5m8KWUXJf- > CeVJc0hDGD9AQ2LkcXDC0PMV9ntVw5Ho&m=UyEQgUhk9l9hqIrxNx78GbVK6s9kwuLB__fHsbBQEM4&s=rtzk06a5EQ6yVVYKeZ7mWej5qmusPUM5nc8ivikv- > oA&e= > > > Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU From christoph.langer at sap.com Tue Apr 30 09:54:01 2019 From: christoph.langer at sap.com (Langer, Christoph) Date: Tue, 30 Apr 2019 09:54:01 +0000 Subject: RFR: 8222276: (zipfs) Refactoring and cleanups to prepare for JDK-8213031 In-Reply-To: References: Message-ID: Hi, it turned out that there was a regression in my last version. I needed to fix some initializations in the constructor of Entry. I also added some other fixes found by the IDE?s code analysis to ZipFileSystem.java. By accident, I updated the last webrev in-place. So, please find my most current version here: http://cr.openjdk.java.net/~clanger/webrevs/8222276.1/ Now it passes all testing. Thank you Christoph From: Langer, Christoph Sent: Freitag, 26. April 2019 17:37 To: core-libs-dev ; nio-dev ; Alan Bateman ; Lance Andersen Subject: RE: RFR: 8222276: (zipfs) Refactoring and cleanups to prepare for JDK-8213031 Hi, ping ?? I?ve rebased this change after the latest zipfs updates. I also made some further modifications. Apart from minor things, I modified the constructors of the ZipFileSystem.Entry class and I also made some post JDK-8222440 cleanup. Please find the new webrev here: http://cr.openjdk.java.net/~clanger/webrevs/8222276.1/ The jtreg tests for zipfs are all passing. Thanks Christoph From: Langer, Christoph Sent: Donnerstag, 11. April 2019 16:06 To: core-libs-dev >; nio-dev >; Alan Bateman >; Lance Andersen > Subject: RFR: 8222276: (zipfs) Refactoring and cleanups to prepare for JDK-8213031 Hi, working on JDK-8213031 to add posix file permission support for the zipfs, I thought it makes sense to factor out some of the changes into a separate change. Those changes reorganize and clean up some parts of the code which I think makes sense in any case. Please review: Bug: https://bugs.openjdk.java.net/browse/JDK-8222276 Webrev: http://cr.openjdk.java.net/~clanger/webrevs/8222276.0/ In detail: The main change is to the hierarchy of inner classes ZipFileSystem.IndexNode and ZipFileSystem.Entry (the latter extends the former). Both classes are static classes currently. It makes sense, though, to have those associated with the ZipFileSystem they belong to. To do that, I need to add a static superclass named ZFSNode which only holds a node name and its hashcode. This class needs to exist because of the lookup implementation to find specific nodes of tze ZipFileSystem in its node map. Then the classes IndexNode extends ZFSNode and Entry extends IndexNode can be made non-static. Further changes are: Improve error handling for ZipFileAttributeView::get methods improve handling for zip64 attribute/version minor clenaups such as adding @Override annotations, whitespace fixes, private method visibility etc. Furthermore, there is some suspicious coding in JarFileSystem:: createVersionedLinks where a temporary key node is inserted into the alias map. However, this is a singleton instance which always gets new values. I?ll open a separate bug for that and I?ll try to create a test case which demonstrates an issue with the current code. I ran the zipfs jtreg tests successfully and will put it into our internal system as well as run it through jdk-submit. Thanks Christoph From amaembo at gmail.com Tue Apr 30 15:57:57 2019 From: amaembo at gmail.com (Tagir Valeev) Date: Tue, 30 Apr 2019 22:57:57 +0700 Subject: RFR 8222955 : Optimize String.replace(CharSequence, CharSequence) for Latin1 encoded strings In-Reply-To: <2bb0ea29-9b92-f9d2-7b26-ad56f01203b5@oracle.com> References: <2bb0ea29-9b92-f9d2-7b26-ad56f01203b5@oracle.com> Message-ID: Hello! New webrev looks good. Probably it worth adding a testcase for overflow (assert that OOME is thrown)? I guess, something like "1".repeat(65536).replace("1", "1".repeat(65536)) would produce OOME quite fast and without allocating much memory. With best regards, Tagir Valeev. On Tue, Apr 30, 2019 at 11:43 AM Ivan Gerasimov wrote: > > Hello everyone! > > Please help review the second version of the enhancement. > A separate branch was added to handle UTF16 in the searched string and/or in the target and replacement. > > Switching to Math.xxxExact() suggested by Tagir gave ~4% of throughput on affected test cases. > > Also, allocating uninitialized array added ~7% for Latin1 strings. > I used StringConcatHelper.newArray() to avoid bringing Unsafe into StringLatin1. > In the StringLatin1.replace(), the newly allocated array is guaranteed to be filled up, and the filling code should never throw, so I believe using uninitialized arrays here is justified. > > Here's the updated webrev: > http://cr.openjdk.java.net/~igerasim/8222955/01/webrev/ > > Below please find the benchmark numbers (with an additional column, showing the improvement.) > > Surprisingly, in one test case a slowdown was observed: Only for Latin1 string, with 1-char target, when the target string was *not* found. > If I understood it correctly, this is because prior the fix the intrinsified StringLatin1.indexOf(byte[], byte[]) was called on the first place, so there were effectively a fast path for exactly this pattern. > > I'm not quite sure what to do about it. > Maybe this is fine as it is, since the *average* improvement across different test cases is still good? > > > - prior fix: > Benchmark Mode Cnt Score Error Units > StringReplace.replace0x1_1_Latin1 avgt 15 7.116 ? 0.060 ns/op > StringReplace.replace0x1_1_UTF16 avgt 15 84.255 ? 3.381 ns/op > StringReplace.replace1x1_0_Latin1 avgt 15 63.254 ? 0.973 ns/op > StringReplace.replace1x1_0_UTF16 avgt 15 89.941 ? 3.210 ns/op > StringReplace.replace1x1_1_Latin1 avgt 15 75.662 ? 0.344 ns/op > StringReplace.replace1x1_1_UTF16 avgt 15 81.454 ? 1.986 ns/op > StringReplace.replace1x1_2_Latin1 avgt 15 89.492 ? 1.889 ns/op > StringReplace.replace1x1_2_UTF16 avgt 15 87.430 ? 1.341 ns/op > StringReplace.replace2x1_0_Latin1 avgt 15 69.575 ? 0.368 ns/op > StringReplace.replace2x1_0_UTF16 avgt 15 112.201 ? 2.836 ns/op > StringReplace.replace2x1_1_Latin1 avgt 15 83.841 ? 0.940 ns/op > StringReplace.replace2x1_1_UTF16 avgt 15 115.722 ? 2.267 ns/op > StringReplace.replace2x1_2_Latin1 avgt 15 99.266 ? 1.008 ns/op > StringReplace.replace2x1_2_UTF16 avgt 15 132.271 ? 2.365 ns/op > > > - after fix: > Benchmark Mode Cnt Score Error Units > StringReplace.replace0x1_1_Latin1 avgt 15 10.541 ? 0.826 ns/op x0.68 > StringReplace.replace0x1_1_UTF16 avgt 15 31.473 ? 0.389 ns/op x2.68 > StringReplace.replace1x1_0_Latin1 avgt 15 50.455 ? 5.038 ns/op x1.25 > StringReplace.replace1x1_0_UTF16 avgt 15 35.355 ? 0.074 ns/op x2.54 > StringReplace.replace1x1_1_Latin1 avgt 15 22.868 ? 0.076 ns/op x3.31 > StringReplace.replace1x1_1_UTF16 avgt 15 22.290 ? 1.913 ns/op x3.65 > StringReplace.replace1x1_2_Latin1 avgt 15 51.362 ? 0.130 ns/op x1.74 > StringReplace.replace1x1_2_UTF16 avgt 15 33.086 ? 0.088 ns/op x2.64 > StringReplace.replace2x1_0_Latin1 avgt 15 57.169 ? 7.165 ns/op x1.22 > StringReplace.replace2x1_0_UTF16 avgt 15 50.886 ? 1.193 ns/op x2.20 > StringReplace.replace2x1_1_Latin1 avgt 15 23.320 ? 2.954 ns/op x3.60 > StringReplace.replace2x1_1_UTF16 avgt 15 24.741 ? 0.229 ns/op x4.68 > StringReplace.replace2x1_2_Latin1 avgt 15 56.045 ? 0.153 ns/op x1.77 > StringReplace.replace2x1_2_UTF16 avgt 15 49.795 ? 0.178 ns/op x2.66 > > -- > With kind regards, > Ivan Gerasimov From ivan.gerasimov at oracle.com Tue Apr 30 17:20:23 2019 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 30 Apr 2019 10:20:23 -0700 Subject: RFR 8222955 : Optimize String.replace(CharSequence, CharSequence) for Latin1 encoded strings In-Reply-To: References: <2bb0ea29-9b92-f9d2-7b26-ad56f01203b5@oracle.com> Message-ID: Hello Tagir! On 4/30/19 8:57 AM, Tagir Valeev wrote: > Hello! > > New webrev looks good. Probably it worth adding a testcase for > overflow (assert that OOME is thrown)? I guess, something like > "1".repeat(65536).replace("1", "1".repeat(65536)) would produce OOME > quite fast and without allocating much memory. Good point! Will do. With kind regards, Ivan > With best regards, > Tagir Valeev. > > On Tue, Apr 30, 2019 at 11:43 AM Ivan Gerasimov > wrote: >> Hello everyone! >> >> Please help review the second version of the enhancement. >> A separate branch was added to handle UTF16 in the searched string and/or in the target and replacement. >> >> Switching to Math.xxxExact() suggested by Tagir gave ~4% of throughput on affected test cases. >> >> Also, allocating uninitialized array added ~7% for Latin1 strings. >> I used StringConcatHelper.newArray() to avoid bringing Unsafe into StringLatin1. >> In the StringLatin1.replace(), the newly allocated array is guaranteed to be filled up, and the filling code should never throw, so I believe using uninitialized arrays here is justified. >> >> Here's the updated webrev: >> http://cr.openjdk.java.net/~igerasim/8222955/01/webrev/ >> >> Below please find the benchmark numbers (with an additional column, showing the improvement.) >> >> Surprisingly, in one test case a slowdown was observed: Only for Latin1 string, with 1-char target, when the target string was *not* found. >> If I understood it correctly, this is because prior the fix the intrinsified StringLatin1.indexOf(byte[], byte[]) was called on the first place, so there were effectively a fast path for exactly this pattern. >> >> I'm not quite sure what to do about it. >> Maybe this is fine as it is, since the *average* improvement across different test cases is still good? >> >> >> - prior fix: >> Benchmark Mode Cnt Score Error Units >> StringReplace.replace0x1_1_Latin1 avgt 15 7.116 ? 0.060 ns/op >> StringReplace.replace0x1_1_UTF16 avgt 15 84.255 ? 3.381 ns/op >> StringReplace.replace1x1_0_Latin1 avgt 15 63.254 ? 0.973 ns/op >> StringReplace.replace1x1_0_UTF16 avgt 15 89.941 ? 3.210 ns/op >> StringReplace.replace1x1_1_Latin1 avgt 15 75.662 ? 0.344 ns/op >> StringReplace.replace1x1_1_UTF16 avgt 15 81.454 ? 1.986 ns/op >> StringReplace.replace1x1_2_Latin1 avgt 15 89.492 ? 1.889 ns/op >> StringReplace.replace1x1_2_UTF16 avgt 15 87.430 ? 1.341 ns/op >> StringReplace.replace2x1_0_Latin1 avgt 15 69.575 ? 0.368 ns/op >> StringReplace.replace2x1_0_UTF16 avgt 15 112.201 ? 2.836 ns/op >> StringReplace.replace2x1_1_Latin1 avgt 15 83.841 ? 0.940 ns/op >> StringReplace.replace2x1_1_UTF16 avgt 15 115.722 ? 2.267 ns/op >> StringReplace.replace2x1_2_Latin1 avgt 15 99.266 ? 1.008 ns/op >> StringReplace.replace2x1_2_UTF16 avgt 15 132.271 ? 2.365 ns/op >> >> >> - after fix: >> Benchmark Mode Cnt Score Error Units >> StringReplace.replace0x1_1_Latin1 avgt 15 10.541 ? 0.826 ns/op x0.68 >> StringReplace.replace0x1_1_UTF16 avgt 15 31.473 ? 0.389 ns/op x2.68 >> StringReplace.replace1x1_0_Latin1 avgt 15 50.455 ? 5.038 ns/op x1.25 >> StringReplace.replace1x1_0_UTF16 avgt 15 35.355 ? 0.074 ns/op x2.54 >> StringReplace.replace1x1_1_Latin1 avgt 15 22.868 ? 0.076 ns/op x3.31 >> StringReplace.replace1x1_1_UTF16 avgt 15 22.290 ? 1.913 ns/op x3.65 >> StringReplace.replace1x1_2_Latin1 avgt 15 51.362 ? 0.130 ns/op x1.74 >> StringReplace.replace1x1_2_UTF16 avgt 15 33.086 ? 0.088 ns/op x2.64 >> StringReplace.replace2x1_0_Latin1 avgt 15 57.169 ? 7.165 ns/op x1.22 >> StringReplace.replace2x1_0_UTF16 avgt 15 50.886 ? 1.193 ns/op x2.20 >> StringReplace.replace2x1_1_Latin1 avgt 15 23.320 ? 2.954 ns/op x3.60 >> StringReplace.replace2x1_1_UTF16 avgt 15 24.741 ? 0.229 ns/op x4.68 >> StringReplace.replace2x1_2_Latin1 avgt 15 56.045 ? 0.153 ns/op x1.77 >> StringReplace.replace2x1_2_UTF16 avgt 15 49.795 ? 0.178 ns/op x2.66 >> >> -- >> With kind regards, >> Ivan Gerasimov -- With kind regards, Ivan Gerasimov From martinrb at google.com Tue Apr 30 18:11:29 2019 From: martinrb at google.com (Martin Buchholz) Date: Tue, 30 Apr 2019 11:11:29 -0700 Subject: RFR: 8223078: Add microbenchmark for array copying/clearing/resizing In-Reply-To: <1b5a7d4b-a277-a3f7-e444-db88b33ecda1@oracle.com> References: <9830dde4-6a3b-7b6b-2cd6-f8cef52ccf13@cs.oswego.edu> <1b5a7d4b-a277-a3f7-e444-db88b33ecda1@oracle.com> Message-ID: On Mon, Apr 29, 2019 at 2:56 PM Claes Redestad wrote: > > This should work: > > make test TEST="micro:foo" MICRO="OPTIONS=-p SIZE=1024,2048" > Thanks for the help! Something like this should go into doc/testing.md I found that running one value of the param at a time works best for me: (cd $(hg root) && for size in 3 16 999 999999; do make test TEST="micro:java.lang.ArrayFiddle" MICRO="FORK=2;WARMUP_ITER=4;ITER=4;OPTIONS=-opi $size -p size=$size" |& perl -ne 'print if /^Benchmark/ .. /^Finished running test/'; done) From martinrb at google.com Tue Apr 30 18:15:39 2019 From: martinrb at google.com (Martin Buchholz) Date: Tue, 30 Apr 2019 11:15:39 -0700 Subject: RFR: 8223078: Add microbenchmark for array copying/clearing/resizing In-Reply-To: References: <9830dde4-6a3b-7b6b-2cd6-f8cef52ccf13@cs.oswego.edu> <1b5a7d4b-a277-a3f7-e444-db88b33ecda1@oracle.com> Message-ID: Webrev updated. More comments. I now use @Param("999") public int size; All values of @Param are plausible, so only including one representative one. From claes.redestad at oracle.com Tue Apr 30 18:31:50 2019 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 30 Apr 2019 20:31:50 +0200 Subject: RFR: 8223078: Add microbenchmark for array copying/clearing/resizing In-Reply-To: References: <9830dde4-6a3b-7b6b-2cd6-f8cef52ccf13@cs.oswego.edu> <1b5a7d4b-a277-a3f7-e444-db88b33ecda1@oracle.com> Message-ID: <3e219c65-5609-ea88-0100-1a3b337f9918@oracle.com> I think these benchmarks looks OK. Thanks for doing this! /Claes On 2019-04-30 20:15, Martin Buchholz wrote: > Webrev updated. > More comments. > > I now use > > ? ? @Param("999") > ? ? public int size; > > All values of?@Param are plausible, so only including one representative > one. From james.laskey at oracle.com Tue Apr 30 18:41:43 2019 From: james.laskey at oracle.com (Jim Laskey) Date: Tue, 30 Apr 2019 15:41:43 -0300 Subject: RFR (CSR) - JDK-8218285 ClassDesc should have a full name method In-Reply-To: <64194254-41EB-430C-A8AB-5E98084E33E7@oracle.com> References: <64194254-41EB-430C-A8AB-5E98084E33E7@oracle.com> Message-ID: <292EE734-25CF-4FA8-B48E-326A82F610C1@oracle.com> I've had no takers. Please take the time. Thank you. -- Jim > On Apr 26, 2019, at 2:57 PM, Jim Laskey wrote: > > Please review. Thank you. > > Cheers, > > -- Jim > > > > Summary: Add the method ClassDesc::displayFullName to return the fully qualified class name from a ClassDesc. Add a second method MethodTypeDesc::displayFullDescriptor which returns the MethodTypeDesc descriptor using fully qualified class names. > > csr: https://bugs.openjdk.java.net/browse/JDK-8218285 > jbs: https://bugs.openjdk.java.net/browse/JDK-8212975 > webrev: http://cr.openjdk.java.net/~jlaskey/8212975/webrev-03/index.html > From joe.darcy at oracle.com Tue Apr 30 22:00:26 2019 From: joe.darcy at oracle.com (Joseph D. Darcy) Date: Tue, 30 Apr 2019 15:00:26 -0700 Subject: RFR: JDK-8219483: j.l.c.ClassDesc::nested(String, String...) doesn't throw NPE if any arg is null In-Reply-To: <042c4118-e6c2-8094-6b8e-d38c519b0196@oracle.com> References: <7b71bdb8-53cb-fdd3-eca4-4e4ba89fe5a4@oracle.com> <9b0ea90c-ddca-ab76-caf0-c41e2b56aa2c@oracle.com> <042c4118-e6c2-8094-6b8e-d38c519b0196@oracle.com> Message-ID: <5CC8C57A.5020906@oracle.com> Hi Vicente, CSR reviewed. I suggesting adding a test case for cd.nested("good", null) Thanks, -Joe On 4/29/2019 2:41 PM, Vicente Romero wrote: > Hi Joe, > > Thanks for the review. I have modified the patch, please see [1] . I > still need a reviewer for the CSR [2], > > Vicente > > [1] http://cr.openjdk.java.net/~vromero/8219483/webrev.01/ > [2] https://bugs.openjdk.java.net/browse/JDK-8223034 > > > On 4/26/19 9:32 PM, Joe Darcy wrote: >> Hi Vicente, >> >> For purposes of a better exception message, do you want to explicitly >> check moreNestedNames for null in some way before accessing its >> contents? Also, I'd commend the spec be updated slightly to >> >> @throws NullPointerException if any argument or its contents is >> {@code null} >> >> assuming the desired behavior is a NPE if an element of >> moreNestedNames is null as opposed to ust moreNestedNames itself. >> >> Thanks, >> >> -Joe >> >> On 4/26/2019 9:33 AM, Vicente Romero wrote: >>> Hi, >>> >>> Please review fix [1] and CSR [2] for [3]. The API for method >>> j.l.c.ClassDesc::nested(String, String...) states that it should >>> throw NPE if any of the arguments is null. The implementation is not >>> in sync with the API and should be corrected, >>> >>> Thanks, >>> Vicente >>> >>> [1] http://cr.openjdk.java.net/~vromero/8219483/webrev.00/ >>> [2] https://bugs.openjdk.java.net/browse/JDK-8223034 >>> [3] https://bugs.openjdk.java.net/browse/JDK-8219483 >>> > From philip.race at oracle.com Tue Apr 30 22:53:01 2019 From: philip.race at oracle.com (Phil Race) Date: Tue, 30 Apr 2019 15:53:01 -0700 Subject: RFR: JDK-8212780: JEP 343: Packaging Tool Implementation In-Reply-To: <19f1ecec-b932-f096-95ea-5cf0c7c1c365@oracle.com> References: <0bd5501f-9db0-f22a-c4f1-4e284a43021f@oracle.com> <3da2c640-8fad-335b-9696-69f45e1a1024@oracle.com> <5CC4F7E0.7020208@oracle.com> <19f1ecec-b932-f096-95ea-5cf0c7c1c365@oracle.com> Message-ID: <01b88418-1c69-4180-be24-5e4207c06493@oracle.com> A couple of questions / observations :- 1) setlocale http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/linux/native/jpackageapplauncher/launcher.cpp.html 52 int main(int argc, char *argv[]) { 53 int result = 1; 54 setlocale(LC_ALL, "en_US.utf8"); Why is this setlocale() call there ? What does this mean for a user whose desktop is (say) German, or French, or Japanese ? When the Java app is launched from this environment is it inheriting this US locale ? I hope not. We have the same on Mac :- http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/macosx/native/jpackageapplauncher/main.m.html and windows :- http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/windows/native/jpackageapplauncher/WinLauncher.cpp.html 64 ::setlocale(LC_ALL, "en_US.utf8"); 2) C++ files containing C src/jdk.jpackage/windows/native/libjpackage/WindowsRegistry.cpp src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp src/jdk.jpackage/windows/native/libwixhelper/libwixhelper.cpp have their entire contents wrapped in 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 159 #ifdef __cplusplus 160 } 161 #endif wouldn't it be better to put them in .c files ? -phil. From kevin.rushforth at oracle.com Tue Apr 30 23:02:09 2019 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Tue, 30 Apr 2019 16:02:09 -0700 Subject: RFR: JDK-8212780: JEP 343: Packaging Tool Implementation In-Reply-To: <01b88418-1c69-4180-be24-5e4207c06493@oracle.com> References: <0bd5501f-9db0-f22a-c4f1-4e284a43021f@oracle.com> <3da2c640-8fad-335b-9696-69f45e1a1024@oracle.com> <5CC4F7E0.7020208@oracle.com> <19f1ecec-b932-f096-95ea-5cf0c7c1c365@oracle.com> <01b88418-1c69-4180-be24-5e4207c06493@oracle.com> Message-ID: <2e0b146d-25fa-1781-2083-bb8901bb95fb@oracle.com> I have a couple nit-picky comments: 1. The change to src/jdk.jlink/share/classes/module-info.java is unrelated to jpackage and should be reverted (there is only a white-space change and a copyright date change to that file) 2. The following files have whitespace errors that will cause jcheck to fail: src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java:326: Trailing whitespace src/jdk.jpackage/share/classes/jdk/jpackage/internal/CLIHelp.java:58: Tab character src/jdk.jpackage/share/classes/jdk/jpackage/internal/JLinkBundlerHelper.java:217: Trailing whitespace src/jdk.jpackage/share/classes/jdk/jpackage/internal/ValidOptions.java:55: Trailing whitespace 3. I recommend to replace the wild-card imports with explicit imports, for example: src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java (java.util.* and java.io.*) (I think the wild-card static import is fine, just not the import every class from a package) I'll try to remember to note these as I go through the review. This one could be done as a follow-up bug rather than doing it prior to integration if you prefer. -- Kevin From alexander.matveev at oracle.com Tue Apr 30 23:22:54 2019 From: alexander.matveev at oracle.com (Alexander Matveev) Date: Tue, 30 Apr 2019 16:22:54 -0700 Subject: RFR: JDK-8212780: JEP 343: Packaging Tool Implementation In-Reply-To: <3da2c640-8fad-335b-9696-69f45e1a1024@oracle.com> References: <0bd5501f-9db0-f22a-c4f1-4e284a43021f@oracle.com> <3da2c640-8fad-335b-9696-69f45e1a1024@oracle.com> Message-ID: <5368272b-9e03-4851-4766-4a9ee276f4e6@oracle.com> Hi Andy, Looks good overall. http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/Info-lite.plist.template.html http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/Info.plist.template.html http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/Runtime-Info.plist.template.html All these files have: CFBundleSignature ???? Based on doc "CFBundleSignature is the application?s creator signature, a four-character code that identifies document files belonging to this application." Should it be unique per application? It seems that all bundles will have same signature, not sure if it is correct. http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/launchd.plist.template.html Looks like old file from daemon support. Probably no longer needed. http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties.html Line 28 and 37 - Double space between sentences. Some missing "." in some messages like line 32 and 34. http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties.html Line 47 - appRuntimeIMage -> appRuntimeImage http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/ResourceLocator.java.html Do we need this file? http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/template.iss.html Line 49-55 - Seems to be related to service support, which is not currently supported. I think this file can be cleanup. Minor issues that can be fixed as follow up cleanup task: http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java.html Line 305 - Remove if not needed. http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxRpmBundler.java.html Line 433 - Lets remove this TODO and file a bug if needed. Line 587 - Remove TODO. http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources.properties.html Line 27, 70 and 74 - No need for double space after ".". http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/linux/native/libapplauncher/LinuxPlatform.cpp.html Line 864-871 - Remove if not needed. http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppStoreBundler.java.html Line 120 - Remove if not needed. Line 314 - Remove. Line 364-365 - Remove. http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java.html Line 521 and 524 - Remove http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java.html Line 138 - Remove TODO http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/windows/native/libapplauncher/FileAttribute.h.html Line 36 and 39 - Remove. http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/src/jdk.jpackage/windows/native/libapplauncher/FilePath.cpp.html Line 389-391 - Remove Line 398-400 - Remove Thanks, Alexander On 4/24/2019 5:47 PM, Andy Herrick wrote: > > On 4/24/2019 8:44 PM, Andy Herrick wrote: >> Please review? changes for [1] which is the implementation bug for >> JEP-343. >> >> The webrev at [2] is the total cumulative webrev of changes for the >> jpackage tool, currently in the JDK-8200758-branch branch of the open >> sandbox repository. >> >> The webrev at [3] shows the changes from EA-05 to EA-06. > sorry - the links are reversed from what is stated above. [2] is the > incremental webrev since EA 05, [3] is the cumulativewebrev > /Andy >> >> The latest EA-6 (build 49) is posted at [4]. >> >> Please send feedback to core-libs-dev at openjdk.java.net >> >> >> [1] https://bugs.openjdk.java.net/browse/JDK-8200758 >> >> [2] http://cr.openjdk.java.net/~herrick/8212780/webrev.05-06/ >> >> [3] http://cr.openjdk.java.net/~herrick/8212780/webrev.ea6/ >> >> [4] http://jdk.java.net/jpackage/ >> >> >> /Andy >> >> > From amalloy at google.com Tue Apr 30 17:53:23 2019 From: amalloy at google.com (Alan Malloy) Date: Tue, 30 Apr 2019 10:53:23 -0700 Subject: RFR: 8219202: Use Unsynchronized StringBuilder in sun.net.www.ParseUtil Message-ID: Hello. Please review this patch to use StringBuilder instead of StringBuffer in sun.net.www.ParseUtil, a usage that does not need synchronization. bug: https://bugs.openjdk.java.net/browse/JDK-8219202 webrev: http://cr.openjdk.java.net/~cushon/8219202/webrev.01/ Testing: All of jtreg:test/jdk/sun/net/www pass locally. No new test added, as no behavior change is intended. Thanks, Alan From twic at urchin.earth.li Tue Apr 30 15:15:17 2019 From: twic at urchin.earth.li (Tom Anderson) Date: Tue, 30 Apr 2019 16:15:17 +0100 (BST) Subject: jpackage producing non-working binaries on Windows Message-ID: Hello, I am trying out the early-access jpackage tool. It works perfectly on Linux, but on Windows produces a binary which does not do anything when run. I would like to either fix any error i have made, or help you identify a bug, if there is one! Is this the right place to come with this problem? If not, where should i go? Is there a list of known issues other than on the download page [1]? What debugging steps should i try? Would a self-contained example be helpful to you? What other information would you like? Regards, tom [1] https://jdk.java.net/jpackage/