From martinrb at google.com Thu Mar 1 00:13:48 2018 From: martinrb at google.com (Martin Buchholz) Date: Wed, 28 Feb 2018 16:13:48 -0800 Subject: RFR 7183985: Class.getAnnotation() throws an ArrayStoreException when the annotation class not present In-Reply-To: References: <1f87dd21-701b-975c-a1c1-f1d9ed2f1eaf@oracle.com> <5A90B204.4070005@oracle.com> <5A960359.4070507@oracle.com> Message-ID: I was surprised to learn that junit has a magic assertEquals specifically for Object[] assertEquals(Object[], Object[]) but that is obviously a bad idea and junit eventually deprecated it. https://junit.org/junit4/javadoc/4.12/org/junit/Assert.html#assertEquals(java.lang.Object[], java.lang.Object[]) Follow their lead and rename your method to assertArrayEquals 124 static void assertEquals(Object[] actual, Object[] expected) { From cushon at google.com Thu Mar 1 00:26:37 2018 From: cushon at google.com (Liam Miller-Cushon) Date: Wed, 28 Feb 2018 16:26:37 -0800 Subject: RFR 7183985: Class.getAnnotation() throws an ArrayStoreException when the annotation class not present In-Reply-To: References: <1f87dd21-701b-975c-a1c1-f1d9ed2f1eaf@oracle.com> <5A90B204.4070005@oracle.com> <5A960359.4070507@oracle.com> Message-ID: On Wed, Feb 28, 2018 at 4:13 PM, Martin Buchholz wrote: > Follow their lead and rename your method to assertArrayEquals > Done: http://cr.openjdk.java.net/~cushon/7183985/webrev.04/ From paul.sandoz at oracle.com Thu Mar 1 01:29:18 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 28 Feb 2018 17:29:18 -0800 Subject: RFR JDK-8197533 move javax.transaction.xa into its own module In-Reply-To: <144F8EF0-0020-4577-8F9B-3FC86AF8ED4A@oracle.com> References: <0EC6FFD0-31EA-4D24-B82D-C4D5DCAB8E65@oracle.com> <144F8EF0-0020-4577-8F9B-3FC86AF8ED4A@oracle.com> Message-ID: > On Feb 28, 2018, at 1:22 PM, Lance Andersen wrote: > >> >> On Feb 28, 2018, at 2:20 PM, Lance Andersen > wrote: >> >> Hi Paul, >> >> Thank you for the review. >>> On Feb 28, 2018, at 1:40 PM, Paul Sandoz > wrote: >>> >>> Compatible module refactoring in action! >>> >>> Looks good, one comment: >>> >>> test/jdk/javax/transaction/xa/testng/JavaSqlModuleDriver.java >>> >>> This is not a valid Java source file can you merge the jtreg meta data into XAExceptionTests instead? >> >> As we discussed offline, I will change the above file and Driver.java. I naively assumed this was OK as the change to add Driver.java was made after I had originally added these tests in 2015. > > http://cr.openjdk.java.net/~lancea/8197533/webrev.01/ has the updated tests +1, i second Joe?s request to update package-info.java while we are opportunistically cleaning this area up. Paul. From xu.y.yin at oracle.com Thu Mar 1 02:03:57 2018 From: xu.y.yin at oracle.com (Chris Yin) Date: Thu, 1 Mar 2018 10:03:57 +0800 Subject: [JDK 11] RFR 8198821: fix test methods access for test java/text/Normalizer/NormalizerAPITest.java Message-ID: Please review the minor change for test java/text/Normalizer/NormalizerAPITest.java, thanks Added public access modifier to all ?Test_" methods so they can be recognized as test method correctly by util class bug: https://bugs.openjdk.java.net/browse/JDK-8198821 webrev: http://cr.openjdk.java.net/~xiaofeya/8198821/webrev.00/ Regards, Chris From paul.sandoz at oracle.com Thu Mar 1 02:13:23 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 28 Feb 2018 18:13:23 -0800 Subject: RFR: JDK-8197594: String#repeat In-Reply-To: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> Message-ID: Hi Jim, Looks good. I like the power of 2 copying. 2978 * @throws IllegalArgumentException if the {@code count} is 2979 * negative. 2980 */ 2981 public String repeat(int count) { Missing @since11 on the method. Like Stuart suggests, turn the explanatory text into an api note, perhaps with a small code sample. Thanks, Paul. > On Feb 28, 2018, at 8:31 AM, Jim Laskey wrote: > > Introduction of a new instance method String::repeat to allow an efficient and concise approach for generating repeated character sequences as strings. > > Performance information in JBS. > > Thank you. > > Cheers, > > ? Jim > > > JBS: https://bugs.openjdk.java.net/browse/JDK-8197594 > CSR: https://bugs.openjdk.java.net/browse/JDK-8198296 > > Webrev: http://cr.openjdk.java.net/~jlaskey/8197594/webrev-02/index.html > JavaDoc: http://cr.openjdk.java.net/~jlaskey/8197594/String.html > > > From james.laskey at oracle.com Thu Mar 1 02:26:33 2018 From: james.laskey at oracle.com (James Laskey) Date: Wed, 28 Feb 2018 22:26:33 -0400 Subject: RFR: JDK-8197594: String#repeat In-Reply-To: References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> Message-ID: <31171E62-AA90-4461-BBF4-75568B091BBA@oracle.com> Thanks Paul. Sent from my iPhone > On Feb 28, 2018, at 10:13 PM, Paul Sandoz wrote: > > Hi Jim, > > Looks good. I like the power of 2 copying. > > > 2978 * @throws IllegalArgumentException if the {@code count} is > 2979 * negative. > 2980 */ > 2981 public String repeat(int count) { > > Missing @since11 on the method. > > > Like Stuart suggests, turn the explanatory text into an api note, perhaps with a small code sample. > > Thanks, > Paul. > > >> On Feb 28, 2018, at 8:31 AM, Jim Laskey wrote: >> >> Introduction of a new instance method String::repeat to allow an efficient and concise approach for generating repeated character sequences as strings. >> >> Performance information in JBS. >> >> Thank you. >> >> Cheers, >> >> ? Jim >> >> >> JBS: https://bugs.openjdk.java.net/browse/JDK-8197594 >> CSR: https://bugs.openjdk.java.net/browse/JDK-8198296 >> >> Webrev: http://cr.openjdk.java.net/~jlaskey/8197594/webrev-02/index.html >> JavaDoc: http://cr.openjdk.java.net/~jlaskey/8197594/String.html >> >> >> > From james.laskey at oracle.com Thu Mar 1 02:34:02 2018 From: james.laskey at oracle.com (James Laskey) Date: Wed, 28 Feb 2018 22:34:02 -0400 Subject: RFR: JDK-8197594: String#repeat In-Reply-To: References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> Message-ID: Thanks Stuart. RE apinote, I was trying to follow the pattern of other older method comments (Roman-style.) Comments/Javadoc in most of these older classes are a mix of styles. Question: if you update/clean-up a method in an older class, should you bring the comment/Javadoc up-to-date as well? Cheers, ? Jim Sent from my iPhone > On Feb 28, 2018, at 6:21 PM, Stuart Marks wrote: > > Hi Jim, > > Implementation looks good. I'd suggest a couple small editorial changes to the spec: > > 2966 /** > 2967 * Returns a string whose value is the concatenation of this > 2968 * string repeated {@code count} times. > 2969 *

> 2970 * If count or length is zero then the empty string is returned. > > I went looking for a 'length' parameter, until I realized it means the length of *this string*. So maybe clarify that. (And also line 2977.) > > 2971 *

> 2972 * This method may be used to create space padding for > 2973 * formatting text or zero padding for formatting numbers. > > I don't think having this text is necessary, but if you want it, I'd suggest putting it into an @apiNote. > > 2974 * @param count number of times to repeat > 2975 * @return A string composed of this string repeated > 2976 * {@code count} times or the empty string if count > 2977 * or length is zero. > > Thanks, > > s'marks > > >> On 2/28/18 8:31 AM, Jim Laskey wrote: >> Introduction of a new instance method String::repeat to allow an efficient and concise approach for generating repeated character sequences as strings. >> Performance information in JBS. >> Thank you. >> Cheers, >> ? Jim >> JBS: https://bugs.openjdk.java.net/browse/JDK-8197594 >> CSR: https://bugs.openjdk.java.net/browse/JDK-8198296 >> >> Webrev: http://cr.openjdk.java.net/~jlaskey/8197594/webrev-02/index.html >> JavaDoc: http://cr.openjdk.java.net/~jlaskey/8197594/String.html From james at lightbend.com Thu Mar 1 03:33:14 2018 From: james at lightbend.com (James Roper) Date: Thu, 1 Mar 2018 14:33:14 +1100 Subject: Reactive Streams utility API In-Reply-To: References: Message-ID: Hi all, We've put together a simple proposal for this. Please read the README for an introduction to this proposal. https://github.com/lightbend/reactive-streams-utils Regards, James On 22 February 2018 at 11:47, James Roper wrote: > Hi all, > > This is an email to give people a heads up that we'd like to look at > creating an API, in the same vein as the JDK8 Streams API, for building > reactive streams (a la JDK9 juc.Flow). Our goals for this are: > > * To fill a gap in the JDK where if a developer wants to do even the > simplest of things with a JDK9 juc.Flow, such as map or filter, they need > to bring in a third party library that implements that. > * To produce an API that can build Publishers, Subscribers, Processors, > and complete graphs, for the purposes of consuming APIs that use reactive > streams (for example, JDK9 Http Client). > * To produce an API that aligns closely with ju.stream.Stream, using it > for inspiration for naming, scope, general API shape, and other aspects. > The purpose of this goal is to ensure familiarity of Java developers with > the new API, and to limit the number of concepts Java developers need to > understand to do the different types of streaming offered by the JDK. > * To produce an API that can be implemented by multiple providers > (including an RI in the JDK itself), using the ServiceLoader mechanism to > provide and load a default implementation (while allowing custom > implementations to be manually provided). There are a lot of concerns that > each different streams implementation provides and implements, beyond > streaming, for example monitoring/tracing, concurrency modelling, buffering > strategies, performance aspects of the streams handling including fusing, > and context (eg thread local) propagation. This will allow libraries to use > and provide contracts based on this API without depending on a particular > implementation, and allows developers to select the implementation that > meets their needs. > > Non goals: > > * To produce a kitchen sink of utilities for working with reactive > streams. There already exist a number of reactive streams implementations > that seek to meet this goal (eg, Akka Streams, Reactor, RxJava), and once > you go past the basics (map, filter, collect), and start dealing with > things like fan in/out, cycles, restarting, etc, the different approaches > to solving this start to vary greatly. The JDK should provide enough to be > useful for typical every day streaming use cases, with developers being > able to select a third party library for anything more advanced. > > We will update this list when we have something ready for public review. > This probably won't be far off. Our hope is that we can propose this as a > JEP. > > Regards, > > James > > -- > *James Roper* > *Senior Octonaut* > > Lightbend ? Build reactive apps! > Twitter: @jroper > -- *James Roper* *Senior Octonaut* Lightbend ? Build reactive apps! Twitter: @jroper From andrej.golovnin at gmail.com Thu Mar 1 07:53:15 2018 From: andrej.golovnin at gmail.com (Andrej Golovnin) Date: Thu, 1 Mar 2018 08:53:15 +0100 Subject: RFR: JDK-8197594: String#repeat In-Reply-To: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> Message-ID: Hi Jim, src/java.base/share/classes/java/lang/String.java 2972 * This method may be used to create space padding for 2973 * formatting text or zero padding for formatting numbers. 2974 * @param count number of times to repeat 2975 * @return A string composed of this string repeated 2976 * {@code count} times or the empty string if count 2977 * or length is zero. 2978 * @throws IllegalArgumentException if the {@code count} is 2979 * negative. I don't know whether the JavaDoc style guide requires it or not, but I would put an empty line before @param, @return and @ throws to improved readability. 2983 throw new IllegalArgumentException("count is negative, " + count); "count is negative, " -> "count is negative: " test/jdk/java/lang/String/StringRepeat.java 102 static void VERIFY(String result, String string, int repeat) { Why is the method name in uppercase? Best regards, Andrej Golovnin On Wed, Feb 28, 2018 at 5:31 PM, Jim Laskey wrote: > Introduction of a new instance method String::repeat to allow an efficient and concise approach for generating repeated character sequences as strings. > > Performance information in JBS. > > Thank you. > > Cheers, > > ? Jim > > > JBS: https://bugs.openjdk.java.net/browse/JDK-8197594 > CSR: https://bugs.openjdk.java.net/browse/JDK-8198296 > > Webrev: http://cr.openjdk.java.net/~jlaskey/8197594/webrev-02/index.html > JavaDoc: http://cr.openjdk.java.net/~jlaskey/8197594/String.html > > > From peter.levart at gmail.com Thu Mar 1 11:50:35 2018 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 1 Mar 2018 12:50:35 +0100 Subject: RFR: JDK-8197594: String#repeat In-Reply-To: References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> Message-ID: <80ec5e69-2ade-fbd5-69df-d8ddc70904e3@gmail.com> Hi, On 03/01/2018 03:13 AM, Paul Sandoz wrote: > Hi Jim, > > Looks good. I like the power of 2 copying. Is this really the fastest way? Say you are doing this: String s = ... 64 bytes ... s.repeat(16384); ...the last arraycopy will be copying 512 KiB from one part of memory to the other part. It means that the source 512 KiB range will not fit into L1 cache. Neither fully into L2 cache. The fastest way might be to employ power-of-two copying until the range reaches L1 caches size / 2 for example (16 K ?) and then use the same source range repeatedly as a "stamp" until the rounded end. What do you think? Regards, Peter From claes.redestad at oracle.com Thu Mar 1 12:14:48 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 1 Mar 2018 13:14:48 +0100 Subject: RFR: 8198888: Reduce string allocation churn in InvokerBytecodeGenerator Message-ID: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> Hi, two trivial optimizations that get rid of a few percent on ISC startup tests. Webrev: http://cr.openjdk.java.net/~redestad/8198888/jdk.00/ Bug: https://bugs.openjdk.java.net/browse/JDK-8198888 Thanks! /Claes From andrej.golovnin at gmail.com Thu Mar 1 12:31:33 2018 From: andrej.golovnin at gmail.com (Andrej Golovnin) Date: Thu, 1 Mar 2018 13:31:33 +0100 Subject: RFR: 8198888: Reduce string allocation churn in InvokerBytecodeGenerator In-Reply-To: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> References: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> Message-ID: Hi Claes, src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java 96 /** Internal name lookup cache. */ 97 private HashMap, String> nameMap; 617 nameMap = new HashMap<>(2); Have you tested it with IdentityHashMap? Maybe it would be even better as Class does not have own implementations of #hasCode() and #equals() methods. Best regards, Andrej Golovnin On Thu, Mar 1, 2018 at 1:14 PM, Claes Redestad wrote: > Hi, > > two trivial optimizations that get rid of a few percent on ISC startup > tests. > > Webrev: http://cr.openjdk.java.net/~redestad/8198888/jdk.00/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8198888 > > Thanks! > > /Claes From claes.redestad at oracle.com Thu Mar 1 13:02:59 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 1 Mar 2018 14:02:59 +0100 Subject: RFR: 8198888: Reduce string allocation churn in InvokerBytecodeGenerator In-Reply-To: References: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> Message-ID: Hi, as equals/hashCode on Class mirrors are already using identity semantics, I don't think we actually gain much from using an IdentityHashMap, and I don't want to add new dependencies to this java.lang.invoke (we have some ambition to reduce the number of java.util classes used from java.lang.invoke so as to make it less troublesome to use lambdas et al from java.util). Thanks! /Claes On 2018-03-01 13:31, Andrej Golovnin wrote: > Hi Claes, > > src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java > > 96 /** Internal name lookup cache. */ > 97 private HashMap, String> nameMap; > > 617 nameMap = new HashMap<>(2); > > Have you tested it with IdentityHashMap? Maybe it would be even better > as Class does not have own implementations of #hasCode() and > #equals() methods. > > Best regards, > Andrej Golovnin > > On Thu, Mar 1, 2018 at 1:14 PM, Claes Redestad > wrote: >> Hi, >> >> two trivial optimizations that get rid of a few percent on ISC startup >> tests. >> >> Webrev: http://cr.openjdk.java.net/~redestad/8198888/jdk.00/ >> Bug: https://bugs.openjdk.java.net/browse/JDK-8198888 >> >> Thanks! >> >> /Claes From peter.levart at gmail.com Thu Mar 1 13:17:33 2018 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 1 Mar 2018 14:17:33 +0100 Subject: RFR: 8198888: Reduce string allocation churn in InvokerBytecodeGenerator In-Reply-To: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> References: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> Message-ID: <077e59f6-9144-0ce1-dd98-059816c653c4@gmail.com> Hi Claes, ?623???????????? name = c.getName().replace('.', '/'); Did you know that there are 319 occurrences of .replace('.', '/') in JDK sources and tests (45 occurrences in java.base without tests)? Isn't that enough to create a special API on the java.lang.Class that would cache this or at least something in an internal java.base package? Regards, Peter On 03/01/2018 01:14 PM, Claes Redestad wrote: > Hi, > > two trivial optimizations that get rid of a few percent on ISC startup > tests. > > Webrev: http://cr.openjdk.java.net/~redestad/8198888/jdk.00/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8198888 > > Thanks! > > /Claes From claes.redestad at oracle.com Thu Mar 1 13:31:05 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 1 Mar 2018 14:31:05 +0100 Subject: RFR: 8198888: Reduce string allocation churn in InvokerBytecodeGenerator In-Reply-To: <077e59f6-9144-0ce1-dd98-059816c653c4@gmail.com> References: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> <077e59f6-9144-0ce1-dd98-059816c653c4@gmail.com> Message-ID: <359aebbf-11bf-ff6c-53de-cdb4ae86ebbb@oracle.com> That few, huh? Well, if you ask me the VM internal name and the java class names should have been synced up long ago. :-) I'd not be averse to some real API point in a future RFE. I think this has been dodged in the past to avoid leaking the VM internal representation everywhere. /Claes On 2018-03-01 14:17, Peter Levart wrote: > Hi Claes, > > ?623???????????? name = c.getName().replace('.', '/'); > > Did you know that there are 319 occurrences of .replace('.', '/') in > JDK sources and tests (45 occurrences in java.base without tests)? > > Isn't that enough to create a special API on the java.lang.Class that > would cache this or at least something in an internal java.base package? > > Regards, Peter > > On 03/01/2018 01:14 PM, Claes Redestad wrote: >> Hi, >> >> two trivial optimizations that get rid of a few percent on ISC >> startup tests. >> >> Webrev: http://cr.openjdk.java.net/~redestad/8198888/jdk.00/ >> Bug: https://bugs.openjdk.java.net/browse/JDK-8198888 >> >> Thanks! >> >> /Claes > From Roger.Riggs at Oracle.com Thu Mar 1 14:11:16 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 1 Mar 2018 09:11:16 -0500 Subject: RFR: JDK-8197594: String#repeat In-Reply-To: References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> Message-ID: <9b0d0930-7922-43be-e3c6-0a8e0b80ac23@Oracle.com> Hi Jim, Perhaps premature optimization... Have you done any JMH tests on the expected string content and sizes.? The optimization for single 8-bit characters is good but for short strings like inserting spaces for tab stops, "??? ".repeat(5), will suffer the overhead of Arraycopy for very small/short or non-8-bit strings.?? Perhaps use a regular loop below some threshold ( limit < 32). Maybe the intrinsic already handles this efficiently or it is not important enough to optimize. I would not expect to see many very long repeats or long strings being repeated. And I would leave cache-effect optimizations to the implementation of Arraycopy. Thanks, Roger On 2/28/2018 9:13 PM, Paul Sandoz wrote: > Hi Jim, > > Looks good. I like the power of 2 copying. > > > 2978 * @throws IllegalArgumentException if the {@code count} is > 2979 * negative. > 2980 */ > 2981 public String repeat(int count) { > > Missing @since11 on the method. > > > Like Stuart suggests, turn the explanatory text into an api note, perhaps with a small code sample. > > Thanks, > Paul. > > >> On Feb 28, 2018, at 8:31 AM, Jim Laskey wrote: >> >> Introduction of a new instance method String::repeat to allow an efficient and concise approach for generating repeated character sequences as strings. >> >> Performance information in JBS. >> >> Thank you. >> >> Cheers, >> >> ? Jim >> >> >> JBS: https://bugs.openjdk.java.net/browse/JDK-8197594 >> CSR: https://bugs.openjdk.java.net/browse/JDK-8198296 >> >> Webrev: http://cr.openjdk.java.net/~jlaskey/8197594/webrev-02/index.html >> JavaDoc: http://cr.openjdk.java.net/~jlaskey/8197594/String.html >> >> >> From james.laskey at oracle.com Thu Mar 1 14:12:38 2018 From: james.laskey at oracle.com (Jim Laskey) Date: Thu, 1 Mar 2018 10:12:38 -0400 Subject: RFR: JDK-8197594: String#repeat In-Reply-To: <80ec5e69-2ade-fbd5-69df-d8ddc70904e3@gmail.com> References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> <80ec5e69-2ade-fbd5-69df-d8ddc70904e3@gmail.com> Message-ID: Peter, Very reasonable and worth considering. The main reason the power of 2 copy works well is that the source is (almost) always cached. I thought about this a bit at the beginning and wondered about introducing Arrays.fill(T[] dst, T[] src) where dst is filled repeatedly from src. This can then become an intrinsic and ?do the right thing? based on hardware. String::repeat can be adapted later. I didn?t pursue because I lacked other use cases. File a performance against the implementation (once checked in) and we can see what the performance team thinks. Cheers, ? Jim > On Mar 1, 2018, at 7:50 AM, Peter Levart wrote: > > Hi, > > On 03/01/2018 03:13 AM, Paul Sandoz wrote: >> Hi Jim, >> >> Looks good. I like the power of 2 copying. > > Is this really the fastest way? Say you are doing this: > > String s = ... 64 bytes ... > > s.repeat(16384); > > ...the last arraycopy will be copying 512 KiB from one part of memory to the other part. It means that the source 512 KiB range will not fit into L1 cache. Neither fully into L2 cache. > > The fastest way might be to employ power-of-two copying until the range reaches L1 caches size / 2 for example (16 K ?) and then use the same source range repeatedly as a "stamp" until the rounded end. > > What do you think? > > Regards, Peter > From james.laskey at oracle.com Thu Mar 1 14:15:35 2018 From: james.laskey at oracle.com (Jim Laskey) Date: Thu, 1 Mar 2018 10:15:35 -0400 Subject: RFR: JDK-8197594: String#repeat In-Reply-To: <9b0d0930-7922-43be-e3c6-0a8e0b80ac23@Oracle.com> References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> <9b0d0930-7922-43be-e3c6-0a8e0b80ac23@Oracle.com> Message-ID: <585DBED5-FFF3-400F-954C-FDB632C06FAD@oracle.com> Roger, Claes did some performance tests against an earlier implementation where I was doing just that. We determined that the performance difference was lost in the noise. Cheers, ? Jim > On Mar 1, 2018, at 10:11 AM, Roger Riggs wrote: > > Hi Jim, > > Perhaps premature optimization... > > Have you done any JMH tests on the expected string content and sizes. The optimization for single 8-bit characters > is good but for short strings like inserting spaces for tab stops, " ".repeat(5), will suffer the overhead of Arraycopy > for very small/short or non-8-bit strings. Perhaps use a regular loop below some threshold ( limit < 32). > Maybe the intrinsic already handles this efficiently or it is not important enough to optimize. > > I would not expect to see many very long repeats or long strings being repeated. > And I would leave cache-effect optimizations to the implementation of Arraycopy. > > Thanks, Roger > > On 2/28/2018 9:13 PM, Paul Sandoz wrote: >> Hi Jim, >> >> Looks good. I like the power of 2 copying. >> >> >> 2978 * @throws IllegalArgumentException if the {@code count} is >> 2979 * negative. >> 2980 */ >> 2981 public String repeat(int count) { >> >> Missing @since11 on the method. >> >> >> Like Stuart suggests, turn the explanatory text into an api note, perhaps with a small code sample. >> >> Thanks, >> Paul. >> >>> On Feb 28, 2018, at 8:31 AM, Jim Laskey wrote: >>> >>> Introduction of a new instance method String::repeat to allow an efficient and concise approach for generating repeated character sequences as strings. >>> >>> Performance information in JBS. >>> >>> Thank you. >>> >>> Cheers, >>> >>> ? Jim >>> >>> >>> JBS: https://bugs.openjdk.java.net/browse/JDK-8197594 >>> CSR: https://bugs.openjdk.java.net/browse/JDK-8198296 >>> >>> Webrev: http://cr.openjdk.java.net/~jlaskey/8197594/webrev-02/index.html >>> JavaDoc: http://cr.openjdk.java.net/~jlaskey/8197594/String.html >>> >>> >>> > From claes.redestad at oracle.com Thu Mar 1 14:40:28 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 1 Mar 2018 15:40:28 +0100 Subject: RFR: JDK-8197594: String#repeat In-Reply-To: <585DBED5-FFF3-400F-954C-FDB632C06FAD@oracle.com> References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> <9b0d0930-7922-43be-e3c6-0a8e0b80ac23@Oracle.com> <585DBED5-FFF3-400F-954C-FDB632C06FAD@oracle.com> Message-ID: <79e18d7a-9cf6-4dff-09e0-9829003ee4d4@oracle.com> Yes, I think you can squeeze out a 10% improvement or so on some combinations of shortness of String and lowness of repeat count, but at the cost of adding another branch, risking costs due to profile pollution, decreasing chance the method gets inlined etc.. it didn't seem worth the trouble for something that already is a much larger performance improvement than so over existing alternatives. Thanks! /Claes On 2018-03-01 15:15, Jim Laskey wrote: > Roger, > > Claes did some performance tests against an earlier implementation where I was doing just that. We determined that the performance difference was lost in the noise. > > Cheers, > > ? Jim > > > > >> On Mar 1, 2018, at 10:11 AM, Roger Riggs wrote: >> >> Hi Jim, >> >> Perhaps premature optimization... >> >> Have you done any JMH tests on the expected string content and sizes. The optimization for single 8-bit characters >> is good but for short strings like inserting spaces for tab stops, " ".repeat(5), will suffer the overhead of Arraycopy >> for very small/short or non-8-bit strings. Perhaps use a regular loop below some threshold ( limit < 32). >> Maybe the intrinsic already handles this efficiently or it is not important enough to optimize. >> >> I would not expect to see many very long repeats or long strings being repeated. >> And I would leave cache-effect optimizations to the implementation of Arraycopy. >> >> Thanks, Roger >> >> On 2/28/2018 9:13 PM, Paul Sandoz wrote: >>> Hi Jim, >>> >>> Looks good. I like the power of 2 copying. >>> >>> >>> 2978 * @throws IllegalArgumentException if the {@code count} is >>> 2979 * negative. >>> 2980 */ >>> 2981 public String repeat(int count) { >>> >>> Missing @since11 on the method. >>> >>> >>> Like Stuart suggests, turn the explanatory text into an api note, perhaps with a small code sample. >>> >>> Thanks, >>> Paul. >>> >>>> On Feb 28, 2018, at 8:31 AM, Jim Laskey wrote: >>>> >>>> Introduction of a new instance method String::repeat to allow an efficient and concise approach for generating repeated character sequences as strings. >>>> >>>> Performance information in JBS. >>>> >>>> Thank you. >>>> >>>> Cheers, >>>> >>>> ? Jim >>>> >>>> >>>> JBS: https://bugs.openjdk.java.net/browse/JDK-8197594 >>>> CSR: https://bugs.openjdk.java.net/browse/JDK-8198296 >>>> >>>> Webrev: http://cr.openjdk.java.net/~jlaskey/8197594/webrev-02/index.html >>>> JavaDoc: http://cr.openjdk.java.net/~jlaskey/8197594/String.html >>>> >>>> >>>> From pallavi.sonal at oracle.com Thu Mar 1 14:46:29 2018 From: pallavi.sonal at oracle.com (Pallavi Sonal) Date: Thu, 1 Mar 2018 06:46:29 -0800 (PST) Subject: RFR: JDK-8144300 : Java does not honor http.nonProxyHosts value having wildcard * both at end and start Message-ID: Hi, Please review the following change to fix JDK-8144300. Bug : https://bugs.openjdk.java.net/browse/JDK-8144300 Webrev : http://cr.openjdk.java.net/~rpatil/8144300/webrev.00/ Whenever there is a wildcard(*) at either the beginning or the end of a hostname specified in the list of http.nonProxyHosts , the code works as expected and DIRECT connection is used for them. But in scenarios, where there is a wildcard both at the beginning and end of the hostname, proxy is used instead of DIRECT connection. All the tier1 and tier2 Mach 5 tests have passed. Thanks, Pallavi Sonal From ecki at zusammenkunft.net Thu Mar 1 15:04:30 2018 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Thu, 1 Mar 2018 16:04:30 +0100 Subject: JDK-8197594: String#repeat In-Reply-To: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> Message-ID: <5a98167d.6980df0a.a70a7.db6f@mx.google.com> Hello, I would not encourage makeshift number formatting by mentioning left padding as a major usecase: Just remove that part: + *

+ * This method may be used to create space padding for + * formatting text or zero padding for formatting numbers. I think this error without an Explanation can be hard to debug. It should be clear that Memory allocation was not attempted and what the actual Parameters where: + if (Integer.MAX_VALUE / count < len) { + throw new OutOfMemoryError(); + } ?Repeating ? + len + ? bytes ? + count + ? times would produce a String exceeding maximum size.? Gruss Bernd -- http://bernd.eckenfels.net Von: Jim Laskey Gesendet: Mittwoch, 28. Februar 2018 21:01 An: Core-Libs-Dev Betreff: RFR: JDK-8197594: String#repeat Introduction of a new instance method String::repeat to allow an efficient and concise approach for generating repeated character sequences as strings. Performance information in JBS. Thank you. Cheers, ? Jim JBS: https://bugs.openjdk.java.net/browse/JDK-8197594 CSR: https://bugs.openjdk.java.net/browse/JDK-8198296 Webrev: http://cr.openjdk.java.net/~jlaskey/8197594/webrev-02/index.html JavaDoc: http://cr.openjdk.java.net/~jlaskey/8197594/String.html From james.laskey at oracle.com Thu Mar 1 15:14:26 2018 From: james.laskey at oracle.com (Jim Laskey) Date: Thu, 1 Mar 2018 11:14:26 -0400 Subject: JDK-8197594: String#repeat In-Reply-To: <5a98167d.6980df0a.a70a7.db6f@mx.google.com> References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> <5a98167d.6980df0a.a70a7.db6f@mx.google.com> Message-ID: Thank you Bernd. > On Mar 1, 2018, at 11:04 AM, Bernd Eckenfels wrote: > > Hello, > > I would not encourage makeshift number formatting by mentioning left padding as a major usecase: > > Just remove that part: > > + *

> + * This method may be used to create space padding for > + * formatting text or zero padding for formatting numbers. > > I think this error without an Explanation can be hard to debug. It should be clear that Memory allocation was not attempted and what the actual Parameters where: > > + if (Integer.MAX_VALUE / count < len) { > + throw new OutOfMemoryError(); > + } > > ?Repeating ? + len + ? bytes ? + count + ? times would produce a String exceeding maximum size.? > > Gruss > Bernd > -- > http://bernd.eckenfels.net > > Von: Jim Laskey > Gesendet: Mittwoch, 28. Februar 2018 21:01 > An: Core-Libs-Dev > Betreff: RFR: JDK-8197594: String#repeat > > Introduction of a new instance method String::repeat to allow an efficient and concise approach for generating repeated character sequences as strings. > > Performance information in JBS. > > Thank you. > > Cheers, > > ? Jim > > > JBS: https://bugs.openjdk.java.net/browse/JDK-8197594 > CSR: https://bugs.openjdk.java.net/browse/JDK-8198296 > > Webrev: http://cr.openjdk.java.net/~jlaskey/8197594/webrev-02/index.html > JavaDoc: http://cr.openjdk.java.net/~jlaskey/8197594/String.html From lance.andersen at oracle.com Thu Mar 1 16:59:08 2018 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 1 Mar 2018 11:59:08 -0500 Subject: RFR JDK-8197533 move javax.transaction.xa into its own module In-Reply-To: References: <0EC6FFD0-31EA-4D24-B82D-C4D5DCAB8E65@oracle.com> <144F8EF0-0020-4577-8F9B-3FC86AF8ED4A@oracle.com> Message-ID: > On Feb 28, 2018, at 8:29 PM, Paul Sandoz wrote: > > > >> On Feb 28, 2018, at 1:22 PM, Lance Andersen > wrote: >> >>> >>> On Feb 28, 2018, at 2:20 PM, Lance Andersen > wrote: >>> >>> Hi Paul, >>> >>> Thank you for the review. >>>> On Feb 28, 2018, at 1:40 PM, Paul Sandoz > wrote: >>>> >>>> Compatible module refactoring in action! >>>> >>>> Looks good, one comment: >>>> >>>> test/jdk/javax/transaction/xa/testng/JavaSqlModuleDriver.java >>>> >>>> This is not a valid Java source file can you merge the jtreg meta data into XAExceptionTests instead? >>> >>> As we discussed offline, I will change the above file and Driver.java. I naively assumed this was OK as the change to add Driver.java was made after I had originally added these tests in 2015. >> >> http://cr.openjdk.java.net/~lancea/8197533/webrev.01/ has the updated tests > > +1, i second Joe?s request to update package-info.java while we are opportunistically cleaning this area up. Per your and Joe?s request, please see cr.openjdk.java.net/~lancea/8197533/webrev.02 which has your suggested update to use package-info.java Thank you both Best Lance > > Paul. 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 paul.sandoz at oracle.com Thu Mar 1 17:04:57 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 1 Mar 2018 09:04:57 -0800 Subject: RFR: JDK-8197594: String#repeat In-Reply-To: References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> <80ec5e69-2ade-fbd5-69df-d8ddc70904e3@gmail.com> Message-ID: <0B622292-CDF6-4A3C-AD2F-05E22F7790E7@oracle.com> > On Mar 1, 2018, at 6:12 AM, Jim Laskey wrote: > > Peter, > > Very reasonable and worth considering. The main reason the power of 2 copy works well is that the source is (almost) always cached. > That was my thinking too, the current approach is fine for anticipated string sizes and repeats. We could consider more optimal and general cache friendly approaches but the API cost is likely higher than the benefit e.g. if we add a method to Arrays then 8 + 9 others (all primitives + ref and offset accepting methods) tend to come along for the ride. Paul. > I thought about this a bit at the beginning and wondered about introducing Arrays.fill(T[] dst, T[] src) where dst is filled repeatedly from src. This can then become an intrinsic and ?do the right thing? based on hardware. String::repeat can be adapted later. I didn?t pursue because I lacked other use cases. > > File a performance against the implementation (once checked in) and we can see what the performance team thinks. > > Cheers, > > ? Jim From paul.sandoz at oracle.com Thu Mar 1 17:37:19 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 1 Mar 2018 09:37:19 -0800 Subject: RFR JDK-8197533 move javax.transaction.xa into its own module In-Reply-To: References: <0EC6FFD0-31EA-4D24-B82D-C4D5DCAB8E65@oracle.com> <144F8EF0-0020-4577-8F9B-3FC86AF8ED4A@oracle.com> Message-ID: <945D4802-2632-4082-8970-2E983320C55A@oracle.com> +1 > On Mar 1, 2018, at 8:59 AM, Lance Andersen wrote: >> >> +1, i second Joe?s request to update package-info.java while we are opportunistically cleaning this area up. > > Per your and Joe?s request, please see cr.openjdk.java.net/~lancea/8197533/webrev.02 which has your suggested update to use package-info.java > > Thank you both > > Best > Lance From paul.sandoz at oracle.com Thu Mar 1 17:53:18 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 1 Mar 2018 09:53:18 -0800 Subject: RFR: 8198888: Reduce string allocation churn in InvokerBytecodeGenerator In-Reply-To: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> References: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> Message-ID: <92CF4155-6C95-4DFD-8D6B-B59B898DE1DC@oracle.com> > On Mar 1, 2018, at 4:14 AM, Claes Redestad wrote: > > Hi, > > two trivial optimizations that get rid of a few percent on ISC startup tests. > > Webrev: http://cr.openjdk.java.net/~redestad/8198888/jdk.00/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8198888 > Looks good. Unsurprising that int is so common given it?s the basic carrier for other primitive types. Paul. From paul.sandoz at oracle.com Thu Mar 1 17:57:54 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 1 Mar 2018 09:57:54 -0800 Subject: RFR: 8198888: Reduce string allocation churn in InvokerBytecodeGenerator In-Reply-To: <359aebbf-11bf-ff6c-53de-cdb4ae86ebbb@oracle.com> References: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> <077e59f6-9144-0ce1-dd98-059816c653c4@gmail.com> <359aebbf-11bf-ff6c-53de-cdb4ae86ebbb@oracle.com> Message-ID: It?s not just the internal VM name, it's also a descriptor in byte code. I hope the symbolic ref API currently being designed in the amber repo will help here. Until that settles i would be reluctant to consider adding public ?toDescriptor? methods, or even do something internally right now if we can sweep it all up later on. (Further, the symbolic ref API may also be an opportunity to clean up the parsing side of things too.) Pau. > On Mar 1, 2018, at 5:31 AM, Claes Redestad wrote: > > That few, huh? Well, if you ask me the VM internal name and the java class names should have been synced up long ago. :-) > > I'd not be averse to some real API point in a future RFE. I think this has been dodged in the past to avoid leaking the VM internal representation everywhere. > > /Claes > > On 2018-03-01 14:17, Peter Levart wrote: >> Hi Claes, >> >> 623 name = c.getName().replace('.', '/'); >> >> Did you know that there are 319 occurrences of .replace('.', '/') in JDK sources and tests (45 occurrences in java.base without tests)? >> >> Isn't that enough to create a special API on the java.lang.Class that would cache this or at least something in an internal java.base package? >> >> Regards, Peter >> >> On 03/01/2018 01:14 PM, Claes Redestad wrote: >>> Hi, >>> >>> two trivial optimizations that get rid of a few percent on ISC startup tests. >>> >>> Webrev: http://cr.openjdk.java.net/~redestad/8198888/jdk.00/ >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8198888 >>> >>> Thanks! >>> >>> /Claes >> > From naoto.sato at oracle.com Thu Mar 1 18:26:53 2018 From: naoto.sato at oracle.com (Naoto Sato) Date: Thu, 1 Mar 2018 10:26:53 -0800 Subject: [JDK 11] RFR 8198821: fix test methods access for test java/text/Normalizer/NormalizerAPITest.java In-Reply-To: References: Message-ID: +1 Naoto On 2/28/18 6:03 PM, Chris Yin wrote: > Please review the minor change for test java/text/Normalizer/NormalizerAPITest.java, thanks > > Added public access modifier to all ?Test_" methods so they can be recognized as test method correctly by util class > > bug: https://bugs.openjdk.java.net/browse/JDK-8198821 > webrev: http://cr.openjdk.java.net/~xiaofeya/8198821/webrev.00/ > > Regards, > Chris > From ecki at zusammenkunft.net Thu Mar 1 18:39:22 2018 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Thu, 1 Mar 2018 19:39:22 +0100 Subject: 8198888: Reduce string allocation churn inInvokerBytecodeGenerator In-Reply-To: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> References: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> Message-ID: <5a9848da.4a8a1c0a.9ac85.1fe0@mx.google.com> + if (nameMap == null) { + nameMap = new HashMap<>(2); What is the typical size the map ends up with? If it stays this small linearly searching an Array (or ?last value?) may be faster. If the map typically grows more than a few entries having some more initial buckets will decrease collissions and avoid resizes. Especially considering the fact that HashMap is a rather fat object, it does not hurt to start with a bigger initial table. Does the lazy initialisation actually help anything? Single entry alternative ---------------- Object lastClass; String lastName; If (lastClass == c) return lastName; lastClass = c; lastName = c.getName().replace(?.?, ?/?); return lastName; (or make it a x Slot Version?): ------------------- Object tab_obj = new tab_obj[8]; String tab_val = new String[8]; for(int i=0; i < tab_obj.length; i++) { If (tab_obj[i] == c); return tab_val[i]; } i = (i+1 % tab_obj.length); tab_obj[i] = c; return (tab_val[i] = c.getName().replace()); (not sure about the concurrent semantics and having this static may actually help) Gruss Bernd -- http://bernd.eckenfels.net Von: Claes Redestad Gesendet: Donnerstag, 1. M?rz 2018 16:15 An: core-libs-dev Betreff: RFR: 8198888: Reduce string allocation churn inInvokerBytecodeGenerator Hi, two trivial optimizations that get rid of a few percent on ISC startup tests. Webrev: http://cr.openjdk.java.net/~redestad/8198888/jdk.00/ Bug: https://bugs.openjdk.java.net/browse/JDK-8198888 Thanks! /Claes From ecki at zusammenkunft.net Thu Mar 1 18:42:12 2018 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Thu, 1 Mar 2018 19:42:12 +0100 Subject: RFR: 8198888: Reduce string allocation churn inInvokerBytecodeGenerator In-Reply-To: <92CF4155-6C95-4DFD-8D6B-B59B898DE1DC@oracle.com> References: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> <92CF4155-6C95-4DFD-8D6B-B59B898DE1DC@oracle.com> Message-ID: <5a984985.c7581c0a.cfe47.c1d4@mx.google.com> Another question is it safe to keep an unbounded strong reference to classes here? Maybe better Cache getName() results? -- http://bernd.eckenfels.net Von: Paul Sandoz Gesendet: Donnerstag, 1. M?rz 2018 19:05 An: Claes Redestad Cc: core-libs-dev Betreff: Re: RFR: 8198888: Reduce string allocation churn inInvokerBytecodeGenerator > On Mar 1, 2018, at 4:14 AM, Claes Redestad wrote: > > Hi, > > two trivial optimizations that get rid of a few percent on ISC startup tests. > > Webrev: http://cr.openjdk.java.net/~redestad/8198888/jdk.00/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8198888 > Looks good. Unsurprising that int is so common given it?s the basic carrier for other primitive types. Paul. From claes.redestad at oracle.com Thu Mar 1 19:05:29 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 1 Mar 2018 20:05:29 +0100 Subject: 8198888: Reduce string allocation churn inInvokerBytecodeGenerator In-Reply-To: <5a9848da.4a8a1c0a.9ac85.1fe0@mx.google.com> References: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> <5a9848da.4a8a1c0a.9ac85.1fe0@mx.google.com> Message-ID: <3a24e1ac-889a-fd3c-8894-aeeadab5c442@oracle.com> Hi Bernd, to dispel your concerns about keeping references to classes then InvokerBytecodeGenerators are shortlived and go out of scope after they've been used to generate an invoker (or LF) class, so the impl. here should be safe from a class leak perspective. A static cache is tempting, but would then of course require the use of weak (or soft) references and a concurrent collection, which might make it cost more than it'd save us. It does seem the typical answer for the number of entries that get put into each generator's cache is exactly one, so a single entry cache isn't an unreasonable alternative here. /Claes On 2018-03-01 19:39, Bernd Eckenfels wrote: > + if (nameMap == null) { > + nameMap = new HashMap<>(2); > > What is the typical size the map ends up with? If it stays this small linearly searching an Array (or ?last value?) may be faster. > > If the map typically grows more than a few entries having some more initial buckets will decrease collissions and avoid resizes. Especially considering the fact that HashMap is a rather fat object, it does not hurt to start with a bigger initial table. Does the lazy initialisation actually help anything? > > Single entry alternative > ---------------- > Object lastClass; String lastName; > > If (lastClass == c) > return lastName; > lastClass = c; > lastName = c.getName().replace(?.?, ?/?); > return lastName; > > (or make it a x Slot Version?): > ------------------- > Object tab_obj = new tab_obj[8]; > String tab_val = new String[8]; > > for(int i=0; i < tab_obj.length; i++) > { > If (tab_obj[i] == c); > return tab_val[i]; > } > i = (i+1 % tab_obj.length); > tab_obj[i] = c; > return (tab_val[i] = c.getName().replace()); > > (not sure about the concurrent semantics and having this static may actually help) > > Gruss > Bernd From huizhe.wang at oracle.com Thu Mar 1 19:10:58 2018 From: huizhe.wang at oracle.com (Joe Wang) Date: Thu, 1 Mar 2018 11:10:58 -0800 Subject: Oracle Java 8u161 regression in XML Schema Factory In-Reply-To: <799388aea3444b16985205aa08316eb5@sap.com> References: <14b3a54d-dfd3-b9a8-7d66-ebfe7feee1a1@oracle.com> <618b0785b9dd4e1ca47df9b448f30637@sap.com> <5A8DDB86.1020006@oracle.com> <799388aea3444b16985205aa08316eb5@sap.com> Message-ID: <3561f634-7866-2a54-9d99-abfab62d3b4d@oracle.com> Hi Christoph and all, Just wanted to let you know that we're in progress to update the release notes for 6u181/7u171/8u161 with a doc for this change. Thanks, Joe On 2/22/2018 12:47 AM, Langer, Christoph wrote: > Hi Joe, > > thanks for the clarification. It would be good to have a place of documentation where one could refer customers to. > > Thanks > Christoph > >> -----Original Message----- >> From: Joe Wang [mailto:huizhe.wang at oracle.com] >> Sent: Mittwoch, 21. Februar 2018 21:50 >> To: Langer, Christoph >> Cc: Bernd ; OpenJDK Dev list > dev at openjdk.java.net> >> Subject: Re: Oracle Java 8u161 regression in XML Schema Factory >> >> >>> @Joe: Is there some documentation for this change in default behavior >> that came with JDK8u161? I assume it is for higher security and cannot be >> reverted (e.g. by setting the feature default for >> Djdk.xml.overrideDefaultParser to true). >> >> It is indeed. It was a customer's request. Customers' complaints were >> that a factory created through the official API could in many cases, >> unknowingly to the customers, load 3rd party parsers that didn't >> necessarily implement the security features added since JDK7u40 and 8. >> For customers, this behavior was a security concern. It was particularly >> inconvenient to users who might have some 3rd party libraries that just >> happen to be in their environment. >> >> This change was not mentioned in the release notes. I'll check whether >> we could find a right place for a note of this change. The 8u161 release >> notes would have been a good place to do so. >> >> Best, >> Joe >> >>> Best regards >>> Christoph >>> >>>> -----Original Message----- >>>> From: core-libs-dev [mailto:core-libs-dev-bounces at openjdk.java.net] On >>>> Behalf Of Bernd >>>> Sent: Dienstag, 13. Februar 2018 22:55 >>>> To: OpenJDK Dev list >>>> Subject: Re: Oracle Java 8u161 regression in XML Schema Factory >>>> >>>> Hello, >>>> >>>> >>>> 2018-01-25 17:41 GMT+01:00 Se?n Coffey: >>>> >>>>> Classes nearer to those below were touched via JDK-8186080: Transform >>>> XML >>>>> interfaces >>>>> http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/cb84156d54b2 >>>>> http://hg.openjdk.java.net/jdk8u/jdk8u/jaxp/rev/08a44c164993 >>>>> >>>>> This may be connected with some tools trying to redefine the classes >>>>> perhaps. Needs more investigating. Perhaps the XMLSchemaLoader >>>> changes are >>>>> a factor ? >>>>> >>>> I have ben able to extract a minimal reproducer. It is not related to >>>> XMLUnit, only to powermock. If it instruments com.sun but not javax.xml >>>> (and other combinations) then it fails. >>>> >>>> For details see the readme in this maven project: >>>> >>>> https://github.com/ecki/reproduce-schemaex >>>> >>>> I also found a way to make it work with both versions, so its no longer an >>>> issue for me, but there is definitely some changes (which might also be >>>> triggered in AppServers or OSGi containers with partially reconfigured >>>> implementations. Not sure if you want to investigate deeper). >>>> >>>> Gruss >>>> Bernd >>>> >>>> >>>> Here is the stacktrace anyway: >>>>>> com.sun.org.apache.xerces.internal.impl.dv.DVFactoryException: >> Schema >>>>>> factory class >>>>>> com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl >>>> does >>>>>> not >>>>>> extend from SchemaDVFactory. >>>>>> at >>>>>> com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory. >>>>>> getInstance(SchemaDVFactory.java:75) >>>>>> at >>>>>> com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory. >>>>>> getInstance(SchemaDVFactory.java:57) >>>>>> at >>>>>> com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader. >>>>>> reset(XMLSchemaLoader.java:1024) >>>>>> at >>>>>> com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader. >>>>>> loadGrammar(XMLSchemaLoader.java:556) >>>>>> at >>>>>> com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader. >>>>>> loadGrammar(XMLSchemaLoader.java:535) >>>>>> at >>>>>> com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchema >>>>>> Factory.newSchema(XMLSchemaFactory.java:254) >>>>>> at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory. >>>>>> java:638) >>>>>> at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory. >>>>>> java:654) >>>>>> at >>>>>> com.seeburger.api.test.helpers.BuilderTestHelper.getCRSchema >>>>>> Validator(BuilderTestHelper.java:57) >>>>>> at >>>>>> com.seeburger.api.test.helpers.BuilderTestHelper.validateAnd >>>>>> Compare(BuilderTestHelper.java:73) >>>>>> at >>>>>> com.seeburger.api.test.KSMBuilderTest.testDeletePGP(KSMBuild >>>>>> erTest.java:196) >>>>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>>>>> at >>>>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce >>>>>> ssorImpl.java:62) >>>>>> at >>>>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe >>>>>> thodAccessorImpl.java:43) >>>>>> at java.lang.reflect.Method.invoke(Method.java:498) >>>>>> at >> org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68) >>>>>> at >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R >>>>>> >> unnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod >>>>>> (PowerMockJUnit44RunnerDelegateImpl.java:310) >>>>>> at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie. >>>>>> java:89) >>>>>> at >>>>>> org.junit.internal.runners.MethodRoadie.runBeforesThenTestTh >>>>>> enAfters(MethodRoadie.java:97) >>>>>> at >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R >>>>>> unnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(P >>>>>> owerMockJUnit44RunnerDelegateImpl.java:294) >>>>>> at >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit47R >>>>>> unnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestIn >>>>>> Super(PowerMockJUnit47RunnerDelegateImpl.java:127) >>>>>> at >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit47R >>>>>> unnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(P >>>>>> owerMockJUnit47RunnerDelegateImpl.java:82) >>>>>> at >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R >>>>>> >> unnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThe >>>>>> nTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282) >>>>>> at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie >>>>>> .java:87) >>>>>> at >>>> org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50) >>>>>> at >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R >>>>>> unnerDelegateImpl.invokeTestMethod(PowerMockJUni >>>>>> t44RunnerDelegateImpl.java:207) >>>>>> at >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R >>>>>> >> unnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.ja >>>> va:146) >>>>>> at >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R >>>>>> >> unnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120) >>>>>> at >>>>>> org.junit.internal.runners.ClassRoadie.runUnprotected(ClassR >>>>>> oadie.java:34) >>>>>> at >>>>>> >> org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) >>>>>> at >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R >>>>>> >> unnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122) >>>>>> at >>>>>> org.powermock.modules.junit4.common.internal.impl.JUnit4Test >>>>>> SuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106) >>>>>> at >>>>>> org.powermock.modules.junit4.common.internal.impl.AbstractCo >>>>>> >> mmonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) >>>>>> at >>>>>> >> org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner. >>>> java:59) >>>>>> at >>>>>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference. >>>>>> run(JUnit4TestReference.java:86) >>>>>> at >>>>>> org.eclipse.jdt.internal.junit.runner.TestExecution.run( >>>>>> TestExecution.java:38) >>>>>> at >>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTe >>>>>> sts(RemoteTestRunner.java:539) >>>>>> at >>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTe >>>>>> sts(RemoteTestRunner.java:761) >>>>>> at >>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run( >>>>>> RemoteTestRunner.java:461) >>>>>> at >>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main( >>>>>> RemoteTestRunner.java:207) >>>>>> >>>>>> on the classpath jaxb-impl-2.2.5.jar but the specific packages are only >>>>>> loaded from rt.jar and redefined. I asume the later is done by >>>> Powermock. >>>>>> Line 611: [Loaded >>>>>> com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory from >>>>>> C:\Program >>>>>> Files\Java\jdk1.8.0_161\jre\lib\rt.jar] >>>>>> Line 616: [Loaded >>>>>> com.sun.org.apache.xerces.internal.impl.dv.xs.BaseSchemaDVFactory >>>> from >>>>>> C:\Program Files\Java\jdk1.8.0_161\jre\lib\rt.jar] >>>>>> Line 617: [Loaded >>>>>> com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl >>>> from >>>>>> C:\Program Files\Java\jdk1.8.0_161\jre\lib\rt.jar] >>>>>> Line 618: [Loaded >>>>>> com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory from >>>>>> __JVM_DefineClass__] >>>>>> Line 619: [Loaded >>>>>> com.sun.org.apache.xerces.internal.impl.dv.xs.BaseSchemaDVFactory >>>> from >>>>>> __JVM_DefineClass__] >>>>>> Line 620: [Loaded >>>>>> com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl >>>> from >>>>>> __JVM_DefineClass__] >>>>>> >>>>>> Is that something you are concerned? >>>>>> >>>>>> Gruss >>>>>> Bernd >>>>>> From Roger.Riggs at Oracle.com Thu Mar 1 19:42:52 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 1 Mar 2018 14:42:52 -0500 Subject: RFR JDK-8187653: Lock in CoderResult.Cache becomes performance bottleneck In-Reply-To: <5A90BF44.3030005@oracle.com> References: <5A90BF44.3030005@oracle.com> Message-ID: <9e0de953-b082-f566-cc3e-51e215933202@Oracle.com> Hi Sherman, Looks to be a good fix with predictable behavior and performance. +1, Roger On 2/23/2018 8:26 PM, Xueming Shen wrote: > Hi, > > Please help review the proposed change to remove the potential > performance > bottleneck in CoderResult caused by the "over" synchronization the cache > mechanism. > > issue: https://bugs.openjdk.java.net/browse/JDK-8187653 > webrev: http://cr.openjdk.java.net/~sherman/8187653/webrev > > Notes: > While the original test case (new String/String.getBytes() with UTF8 > as showed in the > stacktrace) described in the bug report might no longer be > reproducible in jdk9, as > we have been optimizing lots of String related? char[]/byte[] coding > path away from > the paths that use CoderResult. But it is still a concern/issue for > the "general" > CharsetDe/Encoder.de/encode() operation, in which the malformed or > unmappable > CoderResult object is returned. > > As showed in the "[synchronized]" section in bm.scores [1], which is > from the simple > jmh benchmark test CoderResultBM.java [2], the sores are getting > significant worse > when the number of concurrent de/encoding threads gets bigger. > > It appears the easy fix is to replace the sync mechanism from "method > synchronized > + HashMap" to? "ConcurrentHashMap" solves the problem, as showed in > the same bm > result [1] in [ConcurrentHashMap] section, because most of the > accesses to the caching > HashMap is read operation. The ConcurrentHahsMap's "almost non-block > for retrieval > operation" really helps here. > > There is another fact that might help us optimize further here. For > most of our charsets > in JDK repository (with couple exceptions), the length of malformed > and unmappable > CoderResult that these charsets might trigger actually is never longer > than 4. So we might > not need to access the ConcurrentHashMap cache at all in normal use > scenario. I'm putting > a CoderResult[4] on top the hashmap cache in proposed webrev. It does > not improve the > performance significantly, but when the thread number gets bigger, a > 10%+ improvement > is observed. So I would assume it might be something worth doing, > given its cost is really > low. > > Thanks, > Sherman > > > [1] http://cr.openjdk.java.net/~sherman/8187653/bm.scores > [2] http://cr.openjdk.java.net/~sherman/8187653/CoderResultBM.java > [3] http://cr.openjdk.java.net/~sherman/8187653/bm.scores.ms932 > From ecki at zusammenkunft.net Thu Mar 1 19:45:59 2018 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Thu, 1 Mar 2018 20:45:59 +0100 Subject: 8198888: Reduce string allocation churninInvokerBytecodeGenerator In-Reply-To: <3a24e1ac-889a-fd3c-8894-aeeadab5c442@oracle.com> References: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> <5a9848da.4a8a1c0a.9ac85.1fe0@mx.google.com> <3a24e1ac-889a-fd3c-8894-aeeadab5c442@oracle.com> Message-ID: <5a985877.e4a6df0a.566bd.e543@mx.google.com> Cool, the lastClass varient then is pretty tempting (and I wont fix the multi-slot Version below, it misses a ?lastUsedSlot? field) Unrelated to this patch I feel that unifying internal names and external names will be a hard task, so Class#getInternalName() looks temting for a lot of similiar usecases mid term. Gruss Bernd -- http://bernd.eckenfels.net Von: Claes Redestad Gesendet: Donnerstag, 1. M?rz 2018 20:05 An: core-libs-dev at openjdk.java.net; ecki at zusammenkunft.net Betreff: Re: 8198888: Reduce string allocation churninInvokerBytecodeGenerator Hi Bernd, to dispel your concerns about keeping references to classes then InvokerBytecodeGenerators are shortlived and go out of scope after they've been used to generate an invoker (or LF) class, so the impl. here should be safe from a class leak perspective. A static cache is tempting, but would then of course require the use of weak (or soft) references and a concurrent collection, which might make it cost more than it'd save us. It does seem the typical answer for the number of entries that get put into each generator's cache is exactly one, so a single entry cache isn't an unreasonable alternative here. /Claes On 2018-03-01 19:39, Bernd Eckenfels wrote: > + if (nameMap == null) { > + nameMap = new HashMap<>(2); > > What is the typical size the map ends up with? If it stays this small linearly searching an Array (or ?last value?) may be faster. > > If the map typically grows more than a few entries having some more initial buckets will decrease collissions and avoid resizes. Especially considering the fact that HashMap is a rather fat object, it does not hurt to start with a bigger initial table. Does the lazy initialisation actually help anything? > > Single entry alternative > ---------------- > Object lastClass; String lastName; > > If (lastClass == c) > return lastName; > lastClass = c; > lastName = c.getName().replace(?.?, ?/?); > return lastName; > > (or make it a x Slot Version?): > ------------------- > Object tab_obj = new tab_obj[8]; > String tab_val = new String[8]; > > for(int i=0; i < tab_obj.length; i++) > { > If (tab_obj[i] == c); > return tab_val[i]; > } > i = (i+1 % tab_obj.length); > tab_obj[i] = c; > return (tab_val[i] = c.getName().replace()); > > (not sure about the concurrent semantics and having this static may actually help) > > Gruss > Bernd From Roger.Riggs at Oracle.com Thu Mar 1 19:59:58 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 1 Mar 2018 14:59:58 -0500 Subject: JDK-6372077: JarFile.getManifest() should handle manifest attribute names up to 70 bytes In-Reply-To: References: <9a4edee0-4edd-caaa-9970-61df083d39df@paratix.ch> <02abcb68-2294-c733-5048-b1f81ee99435@oracle.com> <88b89995-cfe0-d439-d63d-699c628e2315@paratix.ch> <07e62d8d-ae3a-9ffa-d426-81ab548ad252@Oracle.com> <9a08b2c0-3659-1833-f113-23aaceca84bc@Oracle.com> <39bd4f58-bdf6-8fff-4c21-37c2b1f4a340@Oracle.com> Message-ID: Hi Alan, Thanks for the review. I added: "There must be a colon and a SPACE after the name; the combined length will not exceed 72 characters." Webrev updated in place: ?? http://cr.openjdk.java.net/~rriggs/webrev-jar-6372077.patch/ Thanks, Roger On 2/26/2018 6:50 AM, Alan Bateman wrote: > On 23/02/2018 19:58, Roger Riggs wrote: >> Please review this contribution from Philipp Kunz to handle manifest >> attribute names up to 70 bytes. >> >> The change passes the available regression tests. >> Manifest handling is somewhat sensitive so an additional review is >> appreciated. >> >> Webrev: (rebased from the original patch of 2/22/18) >> http://cr.openjdk.java.net/~rriggs/webrev-jar-6372077.patch/ >> >> Issue: >> https://bugs.openjdk.java.net/browse/JDK-6372077 > I looked at the changes to the manifest code and I think they are > okay. I don't have time to study the tests in detail. > > I think it would be useful to copy the clarification note "(there must > be a colon and a SPACE after the name)" from the JAR file spec to the > equivalent sentence in the Attributes class description. That will > help anyone wondering why the limit is 70 rather than 72. This change > shouldn't need a CSR as it's not adding any new assertions. > > -Alan From Alan.Bateman at oracle.com Thu Mar 1 20:00:36 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 1 Mar 2018 20:00:36 +0000 Subject: RFR JDK-8187653: Lock in CoderResult.Cache becomes performance bottleneck In-Reply-To: <9e0de953-b082-f566-cc3e-51e215933202@Oracle.com> References: <5A90BF44.3030005@oracle.com> <9e0de953-b082-f566-cc3e-51e215933202@Oracle.com> Message-ID: On 01/03/2018 19:42, Roger Riggs wrote: > Hi Sherman, > > Looks to be a good fix with predictable behavior and performance. > > +1, Roger I assume malformed4 and unmappable4 should be final, the XXXCache fields too. -Alan From xueming.shen at oracle.com Thu Mar 1 20:10:21 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Thu, 01 Mar 2018 12:10:21 -0800 Subject: RFR JDK-8187653: Lock in CoderResult.Cache becomes performance bottleneck In-Reply-To: References: <5A90BF44.3030005@oracle.com> <9e0de953-b082-f566-cc3e-51e215933202@Oracle.com> Message-ID: <5A985E2D.40402@oracle.com> On 03/01/2018 12:00 PM, Alan Bateman wrote: > > > On 01/03/2018 19:42, Roger Riggs wrote: >> Hi Sherman, >> >> Looks to be a good fix with predictable behavior and performance. >> >> +1, Roger > I assume malformed4 and unmappable4 should be final, the XXXCache fields too. > > -Alan Right, they all should be final. webrev has been updated accordingly. -sherman From ivan.gerasimov at oracle.com Thu Mar 1 20:20:09 2018 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Thu, 1 Mar 2018 12:20:09 -0800 Subject: RFR: JDK-8197594: String#repeat In-Reply-To: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> Message-ID: <3e1345d6-800a-9afc-ac10-74823cf95b79@oracle.com> Hi Jim! I think the copying-loop can be slightly simplified, like this: for (; copied < limit - copied; copied <<= 1) { System.arraycopy(multiple, 0, multiple, copied, copied); } (didn't actually run it to check for correctness.) With kind regards, Ivan On 2/28/18 8:31 AM, Jim Laskey wrote: > Introduction of a new instance method String::repeat to allow an efficient and concise approach for generating repeated character sequences as strings. > > Performance information in JBS. > > Thank you. > > Cheers, > > ? Jim > > > JBS: https://bugs.openjdk.java.net/browse/JDK-8197594 > CSR: https://bugs.openjdk.java.net/browse/JDK-8198296 > > Webrev: http://cr.openjdk.java.net/~jlaskey/8197594/webrev-02/index.html > JavaDoc: http://cr.openjdk.java.net/~jlaskey/8197594/String.html > > > > -- With kind regards, Ivan Gerasimov From Alan.Bateman at oracle.com Thu Mar 1 20:27:05 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 1 Mar 2018 20:27:05 +0000 Subject: JDK-6372077: JarFile.getManifest() should handle manifest attribute names up to 70 bytes In-Reply-To: References: <9a4edee0-4edd-caaa-9970-61df083d39df@paratix.ch> <02abcb68-2294-c733-5048-b1f81ee99435@oracle.com> <88b89995-cfe0-d439-d63d-699c628e2315@paratix.ch> <07e62d8d-ae3a-9ffa-d426-81ab548ad252@Oracle.com> <9a08b2c0-3659-1833-f113-23aaceca84bc@Oracle.com> <39bd4f58-bdf6-8fff-4c21-37c2b1f4a340@Oracle.com> Message-ID: <762dcf22-a386-95ba-7c49-0a727b03bbdb@oracle.com> On 01/03/2018 19:59, Roger Riggs wrote: > Hi Alan, > > Thanks for the review. I added: > > "There must be a colon and a SPACE after the name; the combined length > will not exceed 72 characters." > > Webrev updated in place: > http://cr.openjdk.java.net/~rriggs/webrev-jar-6372077.patch/ Thanks, looks okay to me now. -Alan From Alan.Bateman at oracle.com Thu Mar 1 20:27:40 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 1 Mar 2018 20:27:40 +0000 Subject: RFR JDK-8187653: Lock in CoderResult.Cache becomes performance bottleneck In-Reply-To: <5A985E2D.40402@oracle.com> References: <5A90BF44.3030005@oracle.com> <9e0de953-b082-f566-cc3e-51e215933202@Oracle.com> <5A985E2D.40402@oracle.com> Message-ID: On 01/03/2018 20:10, Xueming Shen wrote: > > Right, they all should be final. > webrev has been updated accordingly. Thanks, it looks okay now. From xueming.shen at oracle.com Thu Mar 1 20:31:25 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Thu, 01 Mar 2018 12:31:25 -0800 Subject: JDK-6372077: JarFile.getManifest() should handle manifest attribute names up to 70 bytes In-Reply-To: References: <9a4edee0-4edd-caaa-9970-61df083d39df@paratix.ch> <02abcb68-2294-c733-5048-b1f81ee99435@oracle.com> <88b89995-cfe0-d439-d63d-699c628e2315@paratix.ch> <07e62d8d-ae3a-9ffa-d426-81ab548ad252@Oracle.com> <9a08b2c0-3659-1833-f113-23aaceca84bc@Oracle.com> <39bd4f58-bdf6-8fff-4c21-37c2b1f4a340@Oracle.com> Message-ID: <5A98631D.3090909@oracle.com> +1 On 03/01/2018 11:59 AM, Roger Riggs wrote: > Hi Alan, > > Thanks for the review. I added: > > "There must be a colon and a SPACE after the name; the combined length will not exceed 72 characters." > > Webrev updated in place: > http://cr.openjdk.java.net/~rriggs/webrev-jar-6372077.patch/ > > Thanks, Roger > > > On 2/26/2018 6:50 AM, Alan Bateman wrote: >> On 23/02/2018 19:58, Roger Riggs wrote: >>> Please review this contribution from Philipp Kunz to handle manifest attribute names up to 70 bytes. >>> >>> The change passes the available regression tests. >>> Manifest handling is somewhat sensitive so an additional review is appreciated. >>> >>> Webrev: (rebased from the original patch of 2/22/18) >>> http://cr.openjdk.java.net/~rriggs/webrev-jar-6372077.patch/ >>> >>> Issue: >>> https://bugs.openjdk.java.net/browse/JDK-6372077 >> I looked at the changes to the manifest code and I think they are okay. I don't have time to study the tests in detail. >> >> I think it would be useful to copy the clarification note "(there must be a colon and a SPACE after the name)" from the JAR file spec to the equivalent sentence in the Attributes class description. That will help anyone wondering why the limit is 70 rather than 72. This change shouldn't need a CSR as it's not adding any new assertions. >> >> -Alan > From james.laskey at oracle.com Thu Mar 1 20:37:48 2018 From: james.laskey at oracle.com (Jim Laskey) Date: Thu, 1 Mar 2018 16:37:48 -0400 Subject: RFR: JDK-8197594: String#repeat In-Reply-To: <3e1345d6-800a-9afc-ac10-74823cf95b79@oracle.com> References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> <3e1345d6-800a-9afc-ac10-74823cf95b79@oracle.com> Message-ID: <38E0F007-713A-4585-9CE9-F9A1D7CF7B55@oracle.com> Ivan, The code is now checked in if you want to test. Cheers, ? Jim > On Mar 1, 2018, at 4:20 PM, Ivan Gerasimov wrote: > > Hi Jim! > > I think the copying-loop can be slightly simplified, like this: > > for (; copied < limit - copied; copied <<= 1) { > System.arraycopy(multiple, 0, multiple, copied, copied); > } > > (didn't actually run it to check for correctness.) > > With kind regards, > Ivan > > > On 2/28/18 8:31 AM, Jim Laskey wrote: >> Introduction of a new instance method String::repeat to allow an efficient and concise approach for generating repeated character sequences as strings. >> >> Performance information in JBS. >> >> Thank you. >> >> Cheers, >> >> ? Jim >> >> >> JBS: https://bugs.openjdk.java.net/browse/JDK-8197594 >> CSR: https://bugs.openjdk.java.net/browse/JDK-8198296 >> >> Webrev: http://cr.openjdk.java.net/~jlaskey/8197594/webrev-02/index.html >> JavaDoc: http://cr.openjdk.java.net/~jlaskey/8197594/String.html >> >> >> >> > > -- > With kind regards, > Ivan Gerasimov From claes.redestad at oracle.com Thu Mar 1 20:56:15 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 1 Mar 2018 21:56:15 +0100 Subject: 8198888: Reduce string allocation churninInvokerBytecodeGenerator In-Reply-To: <5a985877.e4a6df0a.566bd.e543@mx.google.com> References: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> <5a9848da.4a8a1c0a.9ac85.1fe0@mx.google.com> <3a24e1ac-889a-fd3c-8894-aeeadab5c442@oracle.com> <5a985877.e4a6df0a.566bd.e543@mx.google.com> Message-ID: <84cba4a9-838a-fa11-9b12-ad1bf5b3eb66@oracle.com> Hi, On 2018-03-01 20:45, Bernd Eckenfels wrote: > Cool, the lastClass varient then is pretty tempting (and I wont fix the multi-slot Version below, it misses a ?lastUsedSlot? field) yes, for the startup metrics I'm concerned with then a single element implementation is even ever so slightly better: http://cr.openjdk.java.net/~redestad/8198888/jdk.01/ > > Unrelated to this patch I feel that unifying internal names and external names will be a hard task, so Class#getInternalName() looks temting for a lot of similiar usecases mid term. See Paul's replies elsewhere in this thread about ongoing work on a symbolic ref API, which may end up allowing us to express these things without having to go via smelly string representations. /Claes From mandy.chung at oracle.com Thu Mar 1 22:51:57 2018 From: mandy.chung at oracle.com (mandy chung) Date: Thu, 1 Mar 2018 14:51:57 -0800 Subject: 8198888: Reduce string allocation churninInvokerBytecodeGenerator In-Reply-To: <84cba4a9-838a-fa11-9b12-ad1bf5b3eb66@oracle.com> References: <80b44bef-a5de-50de-49e5-6de2b1389df4@oracle.com> <5a9848da.4a8a1c0a.9ac85.1fe0@mx.google.com> <3a24e1ac-889a-fd3c-8894-aeeadab5c442@oracle.com> <5a985877.e4a6df0a.566bd.e543@mx.google.com> <84cba4a9-838a-fa11-9b12-ad1bf5b3eb66@oracle.com> Message-ID: <590bc262-4d14-6685-16a3-2b250bb8058e@oracle.com> On 3/1/18 12:56 PM, Claes Redestad wrote: > > yes, for the startup metrics I'm concerned with then a single element > implementation is even ever so slightly better: > > http://cr.openjdk.java.net/~redestad/8198888/jdk.01/ Looks good to me. Mandy From david.holmes at oracle.com Fri Mar 2 00:35:00 2018 From: david.holmes at oracle.com (David Holmes) Date: Fri, 2 Mar 2018 10:35:00 +1000 Subject: RFR JDK-8187653: Lock in CoderResult.Cache becomes performance bottleneck In-Reply-To: <5A90BF44.3030005@oracle.com> References: <5A90BF44.3030005@oracle.com> Message-ID: <1467288f-e4a6-6160-a566-ef1045d8fd84@oracle.com> Hi Sherman, On 24/02/2018 11:26 AM, Xueming Shen wrote: > Hi, > > Please help review the proposed change to remove the potential performance > bottleneck in CoderResult caused by the "over" synchronization the cache > mechanism. > > issue: https://bugs.openjdk.java.net/browse/JDK-8187653 > webrev: http://cr.openjdk.java.net/~sherman/8187653/webrev > > Notes: > While the original test case (new String/String.getBytes() with UTF8 as > showed in the > stacktrace) described in the bug report might no longer be reproducible > in jdk9, as > we have been optimizing lots of String related? char[]/byte[] coding > path away from > the paths that use CoderResult. But it is still a concern/issue for the > "general" > CharsetDe/Encoder.de/encode() operation, in which the malformed or > unmappable > CoderResult object is returned. > > As showed in the "[synchronized]" section in bm.scores [1], which is > from the simple > jmh benchmark test CoderResultBM.java [2], the sores are getting > significant worse > when the number of concurrent de/encoding threads gets bigger. > > It appears the easy fix is to replace the sync mechanism from "method > synchronized > + HashMap" to? "ConcurrentHashMap" solves the problem, as showed in the > same bm > result [1] in [ConcurrentHashMap] section, because most of the accesses > to the caching > HashMap is read operation. The ConcurrentHahsMap's "almost non-block for > retrieval > operation" really helps here. When you replace synchronized code with concurrent data structures you introduce race conditions that are precluded in the synchronized code. These need to be examined carefully to ensure they are safe. For example, whenever you replace a HashMap with a ConcurrentHashMap you need to see if put() needs to be replaced by putIfAbsent(). David ----- > There is another fact that might help us optimize further here. For most > of our charsets > in JDK repository (with couple exceptions), the length of malformed and > unmappable > CoderResult that these charsets might trigger actually is never longer > than 4. So we might > not need to access the ConcurrentHashMap cache at all in normal use > scenario. I'm putting > a CoderResult[4] on top the hashmap cache in proposed webrev. It does > not improve the > performance significantly, but when the thread number gets bigger, a > 10%+ improvement > is observed. So I would assume it might be something worth doing, given > its cost is really > low. > > Thanks, > Sherman > > > [1] http://cr.openjdk.java.net/~sherman/8187653/bm.scores > [2] http://cr.openjdk.java.net/~sherman/8187653/CoderResultBM.java > [3] http://cr.openjdk.java.net/~sherman/8187653/bm.scores.ms932 > From lance.andersen at oracle.com Fri Mar 2 00:41:30 2018 From: lance.andersen at oracle.com (Lance Andersen) Date: Thu, 1 Mar 2018 19:41:30 -0500 Subject: RFR JDK-8197533 move javax.transaction.xa into its own module In-Reply-To: <945D4802-2632-4082-8970-2E983320C55A@oracle.com> References: <0EC6FFD0-31EA-4D24-B82D-C4D5DCAB8E65@oracle.com> <144F8EF0-0020-4577-8F9B-3FC86AF8ED4A@oracle.com> <945D4802-2632-4082-8970-2E983320C55A@oracle.com> Message-ID: <1E0E8829-52B1-4B86-9DFD-95637C8D9FAA@oracle.com> While running the JDK regression tests, I found a test that needed to be updated, test/langtools/tools/jdeps/modules/DotFileTest.java, due to the update to the java.sql module The updated webrev is at http://cr.openjdk.java.net/~lancea/8197533/webrev.03/ Best Lance > On Mar 1, 2018, at 12:37 PM, Paul Sandoz wrote: > > +1 > >> On Mar 1, 2018, at 8:59 AM, Lance Andersen > wrote: >>> >>> +1, i second Joe?s request to update package-info.java while we are opportunistically cleaning this area up. >> >> Per your and Joe?s request, please see cr.openjdk.java.net/~lancea/8197533/webrev.02 which has your suggested update to use package-info.java >> >> Thank you both >> >> Best >> Lance > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From paul.sandoz at oracle.com Fri Mar 2 00:44:33 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 1 Mar 2018 16:44:33 -0800 Subject: RFR JDK-8197533 move javax.transaction.xa into its own module In-Reply-To: <1E0E8829-52B1-4B86-9DFD-95637C8D9FAA@oracle.com> References: <0EC6FFD0-31EA-4D24-B82D-C4D5DCAB8E65@oracle.com> <144F8EF0-0020-4577-8F9B-3FC86AF8ED4A@oracle.com> <945D4802-2632-4082-8970-2E983320C55A@oracle.com> <1E0E8829-52B1-4B86-9DFD-95637C8D9FAA@oracle.com> Message-ID: > On Mar 1, 2018, at 4:41 PM, Lance Andersen wrote: > > While running the JDK regression tests, I found a test that needed to be updated, test/langtools/tools/jdeps/modules/DotFileTest.java, due to the update to the java.sql module > > The updated webrev is at http://cr.openjdk.java.net/~lancea/8197533/webrev.03/ > +1 Paul. From xu.y.yin at oracle.com Fri Mar 2 01:25:19 2018 From: xu.y.yin at oracle.com (Chris Yin) Date: Fri, 2 Mar 2018 09:25:19 +0800 Subject: [JDK 11] RFR 8198821: fix test methods access for test java/text/Normalizer/NormalizerAPITest.java In-Reply-To: References: Message-ID: <19B8DF23-0444-48F3-B4D3-F9F320D28935@oracle.com> Thank you, Naoto Regards, Chris > On 2 Mar 2018, at 2:26 AM, Naoto Sato wrote: > > +1 > > Naoto > > On 2/28/18 6:03 PM, Chris Yin wrote: >> Please review the minor change for test java/text/Normalizer/NormalizerAPITest.java, thanks >> Added public access modifier to all ?Test_" methods so they can be recognized as test method correctly by util class >> bug: https://bugs.openjdk.java.net/browse/JDK-8198821 >> webrev: http://cr.openjdk.java.net/~xiaofeya/8198821/webrev.00/ >> Regards, >> Chris From xueming.shen at oracle.com Fri Mar 2 02:09:29 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Thu, 01 Mar 2018 18:09:29 -0800 Subject: RFR JDK-8187653: Lock in CoderResult.Cache becomes performance bottleneck In-Reply-To: <1467288f-e4a6-6160-a566-ef1045d8fd84@oracle.com> References: <5A90BF44.3030005@oracle.com> <1467288f-e4a6-6160-a566-ef1045d8fd84@oracle.com> Message-ID: <5A98B259.3060600@oracle.com> On 3/1/18, 4:35 PM, David Holmes wrote: > When you replace synchronized code with concurrent data structures you > introduce race conditions that are precluded in the synchronized code. > These need to be examined carefully to ensure they are safe. For > example, whenever you replace a HashMap with a ConcurrentHashMap you > need to see if put() needs to be replaced by putIfAbsent(). > Hi David, The assumption here is that putIfAbsent() does not help/save anything as the value object would have been created already when it reaches here. And it appears there is no need here to have the check&put to be atomic, replacing any existing key/value pair is fine in this use scenario. Was thinking about computIfAbsent(), but concluded it's just little overdone (wonder why we decided to use the WeakReference in this case, it probably is not worth it, but keep it as is for "compatibility" concern). -Sherman From david.holmes at oracle.com Fri Mar 2 02:20:19 2018 From: david.holmes at oracle.com (David Holmes) Date: Fri, 2 Mar 2018 12:20:19 +1000 Subject: RFR JDK-8187653: Lock in CoderResult.Cache becomes performance bottleneck In-Reply-To: <5A98B259.3060600@oracle.com> References: <5A90BF44.3030005@oracle.com> <1467288f-e4a6-6160-a566-ef1045d8fd84@oracle.com> <5A98B259.3060600@oracle.com> Message-ID: On 2/03/2018 12:09 PM, Xueming Shen wrote: > On 3/1/18, 4:35 PM, David Holmes wrote: > >> When you replace synchronized code with concurrent data structures you >> introduce race conditions that are precluded in the synchronized code. >> These need to be examined carefully to ensure they are safe. For >> example, whenever you replace a HashMap with a ConcurrentHashMap you >> need to see if put() needs to be replaced by putIfAbsent(). >> > > Hi David, > > The assumption here is that putIfAbsent() does not help/save anything as > the value object > would have been created already when it reaches here. And it appears > there is no need here > to have the check&put to be atomic, replacing any existing key/value > pair is fine in this use As long as create(len) is idempotent that should be fine. As Claes pointed out offline you're also risking creating more than one CHM instance. Again if create(len) is idempotent this should be harmless but it is somewhat messy. Also this: 195 private Map> cache = null; should now be volatile. Cheers, David > scenario.? Was thinking about computIfAbsent(), but concluded it's just > little overdone (wonder > why we decided to use the WeakReference in this case, it probably is not > worth it, but keep it as > is for "compatibility" concern). > > -Sherman From naoto.sato at oracle.com Fri Mar 2 02:47:51 2018 From: naoto.sato at oracle.com (naoto.sato at oracle.com) Date: Thu, 1 Mar 2018 18:47:51 -0800 Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method Message-ID: Hi, Please review the fix to the following issue: https://bugs.openjdk.java.net/browse/JDK-4993841 The proposed changeset is located at: http://cr.openjdk.java.net/~naoto/4993841/webrev.03/ This stems from the recent discussion regarding String.repeat().[1] The corresponding CSR has already been approved. Naoto -- [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051568.html From martinrb at google.com Fri Mar 2 03:05:34 2018 From: martinrb at google.com (Martin Buchholz) Date: Thu, 1 Mar 2018 19:05:34 -0800 Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method In-Reply-To: References: Message-ID: + * @param codepoint a {@code codePoint}. does not match the formal parameter. javadoc -private should give an error on that. From martinrb at google.com Fri Mar 2 03:32:05 2018 From: martinrb at google.com (Martin Buchholz) Date: Thu, 1 Mar 2018 19:32:05 -0800 Subject: RFR: Here are some URLClassPath patches In-Reply-To: References: <912a66bb-45d3-0248-7f8e-b43da9b33ff9@oracle.com> <684a8186-6d29-1e52-34cd-3ceb13b2ff4f@oracle.com> <90892fc9-31f0-1da8-46f9-56c91865cb99@oracle.com> Message-ID: On Wed, Feb 28, 2018 at 3:58 PM, Martin Buchholz wrote: > > > 8198810: URLClassLoader does not specify behavior when URL array contains > null > http://cr.openjdk.java.net/~martin/webrevs/jdk/URLClassLoader-NPE/ > https://bugs.openjdk.java.net/browse/JDK-8198810 > Pushed. Can someone at Oracle help with the release note? From martinrb at google.com Fri Mar 2 03:42:42 2018 From: martinrb at google.com (Martin Buchholz) Date: Thu, 1 Mar 2018 19:42:42 -0800 Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method In-Reply-To: References: Message-ID: The multiple redundant bounds checks bother me, but I don't know how to fix them without abandoning a bit of modularization. if (cp >= 0) { if (COMPACT_STRINGS && cp < 0x100) return latin1encode() if (cp < MIN_SURROGATE || (cp > MAX_SURROGATE && cp < MIN_SUPPLEMENTARY_CODEPOINT) return bmpencode() if (cp >= MIN_SUPPLEMENTARY_CODEPOINT && cp <= MAX_CODEPOINT) return suppEncode() } throw ... + static byte[] toBytes(int cp) { + if (Character.isBmpCodePoint(cp)) { + return toBytes((char)cp); + } else { + byte[] result = new byte[4]; + putChar(result, 0, Character.highSurrogate(cp)); + putChar(result, 1, Character.lowSurrogate(cp)); + return result; + } + } We should continue to assume that supplementary characters are very rare, even in this context, so the supplementary character code could be moved to a separate cold method. From martinrb at google.com Fri Mar 2 04:21:28 2018 From: martinrb at google.com (Martin Buchholz) Date: Thu, 1 Mar 2018 20:21:28 -0800 Subject: RFR: Here are some URLClassPath patches In-Reply-To: References: <912a66bb-45d3-0248-7f8e-b43da9b33ff9@oracle.com> <684a8186-6d29-1e52-34cd-3ceb13b2ff4f@oracle.com> <90892fc9-31f0-1da8-46f9-56c91865cb99@oracle.com> Message-ID: Ooooops. 8198810 is the id of the CSR, not the real bug - I should have used 8198803. So I may have broken a jira invariant. Probably jcheck should have caught my mistake. What now? changeset: 49117:0a93645a57f1 qparent user: martin date: 2018-03-01 19:01 -0800 8198810: URLClassLoader does not specify behavior when URL array contains null Reviewed-by: alanb, darcy, dholmes On Thu, Mar 1, 2018 at 7:32 PM, Martin Buchholz wrote: > > > On Wed, Feb 28, 2018 at 3:58 PM, Martin Buchholz > wrote: > >> >> >> 8198810: URLClassLoader does not specify behavior when URL array contains >> null >> http://cr.openjdk.java.net/~martin/webrevs/jdk/URLClassLoader-NPE/ >> https://bugs.openjdk.java.net/browse/JDK-8198810 >> > > Pushed. Can someone at Oracle help with the release note? > > From martinrb at google.com Fri Mar 2 04:59:28 2018 From: martinrb at google.com (Martin Buchholz) Date: Thu, 1 Mar 2018 20:59:28 -0800 Subject: RFR: Here are some URLClassPath patches In-Reply-To: References: <912a66bb-45d3-0248-7f8e-b43da9b33ff9@oracle.com> <684a8186-6d29-1e52-34cd-3ceb13b2ff4f@oracle.com> <90892fc9-31f0-1da8-46f9-56c91865cb99@oracle.com> Message-ID: I have a patch to move those old jdi tests out of the ProblemList jail. I thought we had an existing bug in hotspot-svc to do this, but now I can't find it. We can just use well-formed URLs. http://cr.openjdk.java.net/~martin/webrevs/jdk/jdi-tests-malformed-urls/ From david.holmes at oracle.com Fri Mar 2 04:59:48 2018 From: david.holmes at oracle.com (David Holmes) Date: Fri, 2 Mar 2018 14:59:48 +1000 Subject: RFR: Here are some URLClassPath patches In-Reply-To: References: <912a66bb-45d3-0248-7f8e-b43da9b33ff9@oracle.com> <684a8186-6d29-1e52-34cd-3ceb13b2ff4f@oracle.com> <90892fc9-31f0-1da8-46f9-56c91865cb99@oracle.com> Message-ID: <6092aabe-0079-4e4e-573d-fadcad52bf98@oracle.com> On 2/03/2018 2:21 PM, Martin Buchholz wrote: > Ooooops. 8198810 is the id of the CSR, not the real bug - I should have > used 8198803. So I may have broken a jira invariant. Probably jcheck > should have caught my mistake. What now? Now you have to manually update the real bug with the changeset info and change its state etc. It will be fixed in build "master" initially then when the change hits a promoted build it will need to be changed to the actual build number. And add a comment to the real bug about the incorrect number being used. Thanks, David > changeset: 49117:0a93645a57f1 qparent > user: martin > date: 2018-03-01 19:01 -0800 > 8198810: URLClassLoader does not specify behavior when URL array contains > null > Reviewed-by: alanb, darcy, dholmes > > > On Thu, Mar 1, 2018 at 7:32 PM, Martin Buchholz wrote: > >> >> >> On Wed, Feb 28, 2018 at 3:58 PM, Martin Buchholz >> wrote: >> >>> >>> >>> 8198810: URLClassLoader does not specify behavior when URL array contains >>> null >>> http://cr.openjdk.java.net/~martin/webrevs/jdk/URLClassLoader-NPE/ >>> https://bugs.openjdk.java.net/browse/JDK-8198810 >>> >> >> Pushed. Can someone at Oracle help with the release note? >> >> From david.holmes at oracle.com Fri Mar 2 05:07:53 2018 From: david.holmes at oracle.com (David Holmes) Date: Fri, 2 Mar 2018 15:07:53 +1000 Subject: RFR: Here are some URLClassPath patches In-Reply-To: References: <912a66bb-45d3-0248-7f8e-b43da9b33ff9@oracle.com> <684a8186-6d29-1e52-34cd-3ceb13b2ff4f@oracle.com> <90892fc9-31f0-1da8-46f9-56c91865cb99@oracle.com> Message-ID: On 2/03/2018 2:59 PM, Martin Buchholz wrote: > I have a patch to move those old jdi tests out of the ProblemList jail. > I thought we had an existing bug in hotspot-svc to do this, but now I > can't find it. I've created a sub-task of 8198803 for this and assigned it to you. https://bugs.openjdk.java.net/browse/JDK-8198933 > We can just use well-formed URLs. > > http://cr.openjdk.java.net/~martin/webrevs/jdk/jdi-tests-malformed-urls/ Looks fine. The proof is in the testing of course :) Thanks, David From christoph.langer at sap.com Fri Mar 2 07:47:29 2018 From: christoph.langer at sap.com (Langer, Christoph) Date: Fri, 2 Mar 2018 07:47:29 +0000 Subject: Oracle Java 8u161 regression in XML Schema Factory In-Reply-To: <3561f634-7866-2a54-9d99-abfab62d3b4d@oracle.com> References: <14b3a54d-dfd3-b9a8-7d66-ebfe7feee1a1@oracle.com> <618b0785b9dd4e1ca47df9b448f30637@sap.com> <5A8DDB86.1020006@oracle.com> <799388aea3444b16985205aa08316eb5@sap.com> <3561f634-7866-2a54-9d99-abfab62d3b4d@oracle.com> Message-ID: <48b5e21ff33e4ae7b2c093e4d8ffd92c@sap.com> Thanks, Joe. > -----Original Message----- > From: Joe Wang [mailto:huizhe.wang at oracle.com] > Sent: Donnerstag, 1. M?rz 2018 20:11 > To: Langer, Christoph > Cc: OpenJDK Dev list > Subject: Re: Oracle Java 8u161 regression in XML Schema Factory > > Hi Christoph and all, > > Just wanted to let you know that we're in progress to update the release > notes for 6u181/7u171/8u161 with a doc for this change. > > Thanks, > Joe > > On 2/22/2018 12:47 AM, Langer, Christoph wrote: > > Hi Joe, > > > > thanks for the clarification. It would be good to have a place of > documentation where one could refer customers to. > > > > Thanks > > Christoph > > > >> -----Original Message----- > >> From: Joe Wang [mailto:huizhe.wang at oracle.com] > >> Sent: Mittwoch, 21. Februar 2018 21:50 > >> To: Langer, Christoph > >> Cc: Bernd ; OpenJDK Dev list >> dev at openjdk.java.net> > >> Subject: Re: Oracle Java 8u161 regression in XML Schema Factory > >> > >> > >>> @Joe: Is there some documentation for this change in default behavior > >> that came with JDK8u161? I assume it is for higher security and cannot be > >> reverted (e.g. by setting the feature default for > >> Djdk.xml.overrideDefaultParser to true). > >> > >> It is indeed. It was a customer's request. Customers' complaints were > >> that a factory created through the official API could in many cases, > >> unknowingly to the customers, load 3rd party parsers that didn't > >> necessarily implement the security features added since JDK7u40 and 8. > >> For customers, this behavior was a security concern. It was particularly > >> inconvenient to users who might have some 3rd party libraries that just > >> happen to be in their environment. > >> > >> This change was not mentioned in the release notes. I'll check whether > >> we could find a right place for a note of this change. The 8u161 release > >> notes would have been a good place to do so. > >> > >> Best, > >> Joe > >> > >>> Best regards > >>> Christoph > >>> > >>>> -----Original Message----- > >>>> From: core-libs-dev [mailto:core-libs-dev-bounces at openjdk.java.net] > On > >>>> Behalf Of Bernd > >>>> Sent: Dienstag, 13. Februar 2018 22:55 > >>>> To: OpenJDK Dev list > >>>> Subject: Re: Oracle Java 8u161 regression in XML Schema Factory > >>>> > >>>> Hello, > >>>> > >>>> > >>>> 2018-01-25 17:41 GMT+01:00 Se?n Coffey: > >>>> > >>>>> Classes nearer to those below were touched via JDK-8186080: > Transform > >>>> XML > >>>>> interfaces > >>>>> http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/cb84156d54b2 > >>>>> http://hg.openjdk.java.net/jdk8u/jdk8u/jaxp/rev/08a44c164993 > >>>>> > >>>>> This may be connected with some tools trying to redefine the classes > >>>>> perhaps. Needs more investigating. Perhaps the XMLSchemaLoader > >>>> changes are > >>>>> a factor ? > >>>>> > >>>> I have ben able to extract a minimal reproducer. It is not related to > >>>> XMLUnit, only to powermock. If it instruments com.sun but not > javax.xml > >>>> (and other combinations) then it fails. > >>>> > >>>> For details see the readme in this maven project: > >>>> > >>>> https://github.com/ecki/reproduce-schemaex > >>>> > >>>> I also found a way to make it work with both versions, so its no longer > an > >>>> issue for me, but there is definitely some changes (which might also be > >>>> triggered in AppServers or OSGi containers with partially reconfigured > >>>> implementations. Not sure if you want to investigate deeper). > >>>> > >>>> Gruss > >>>> Bernd > >>>> > >>>> > >>>> Here is the stacktrace anyway: > >>>>>> com.sun.org.apache.xerces.internal.impl.dv.DVFactoryException: > >> Schema > >>>>>> factory class > >>>>>> > com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl > >>>> does > >>>>>> not > >>>>>> extend from SchemaDVFactory. > >>>>>> at > >>>>>> com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory. > >>>>>> getInstance(SchemaDVFactory.java:75) > >>>>>> at > >>>>>> com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory. > >>>>>> getInstance(SchemaDVFactory.java:57) > >>>>>> at > >>>>>> com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader. > >>>>>> reset(XMLSchemaLoader.java:1024) > >>>>>> at > >>>>>> com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader. > >>>>>> loadGrammar(XMLSchemaLoader.java:556) > >>>>>> at > >>>>>> com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader. > >>>>>> loadGrammar(XMLSchemaLoader.java:535) > >>>>>> at > >>>>>> com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchema > >>>>>> Factory.newSchema(XMLSchemaFactory.java:254) > >>>>>> at > javax.xml.validation.SchemaFactory.newSchema(SchemaFactory. > >>>>>> java:638) > >>>>>> at > javax.xml.validation.SchemaFactory.newSchema(SchemaFactory. > >>>>>> java:654) > >>>>>> at > >>>>>> com.seeburger.api.test.helpers.BuilderTestHelper.getCRSchema > >>>>>> Validator(BuilderTestHelper.java:57) > >>>>>> at > >>>>>> com.seeburger.api.test.helpers.BuilderTestHelper.validateAnd > >>>>>> Compare(BuilderTestHelper.java:73) > >>>>>> at > >>>>>> com.seeburger.api.test.KSMBuilderTest.testDeletePGP(KSMBuild > >>>>>> erTest.java:196) > >>>>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native > Method) > >>>>>> at > >>>>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce > >>>>>> ssorImpl.java:62) > >>>>>> at > >>>>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe > >>>>>> thodAccessorImpl.java:43) > >>>>>> at java.lang.reflect.Method.invoke(Method.java:498) > >>>>>> at > >> org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68) > >>>>>> at > >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R > >>>>>> > >> unnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod > >>>>>> (PowerMockJUnit44RunnerDelegateImpl.java:310) > >>>>>> at > org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie. > >>>>>> java:89) > >>>>>> at > >>>>>> org.junit.internal.runners.MethodRoadie.runBeforesThenTestTh > >>>>>> enAfters(MethodRoadie.java:97) > >>>>>> at > >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R > >>>>>> > unnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(P > >>>>>> owerMockJUnit44RunnerDelegateImpl.java:294) > >>>>>> at > >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit47R > >>>>>> > unnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestIn > >>>>>> Super(PowerMockJUnit47RunnerDelegateImpl.java:127) > >>>>>> at > >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit47R > >>>>>> > unnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(P > >>>>>> owerMockJUnit47RunnerDelegateImpl.java:82) > >>>>>> at > >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R > >>>>>> > >> unnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThe > >>>>>> nTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282) > >>>>>> at > org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie > >>>>>> .java:87) > >>>>>> at > >>>> org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50) > >>>>>> at > >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R > >>>>>> unnerDelegateImpl.invokeTestMethod(PowerMockJUni > >>>>>> t44RunnerDelegateImpl.java:207) > >>>>>> at > >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R > >>>>>> > >> > unnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.ja > >>>> va:146) > >>>>>> at > >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R > >>>>>> > >> > unnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120) > >>>>>> at > >>>>>> org.junit.internal.runners.ClassRoadie.runUnprotected(ClassR > >>>>>> oadie.java:34) > >>>>>> at > >>>>>> > >> org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) > >>>>>> at > >>>>>> org.powermock.modules.junit4.internal.impl.PowerMockJUnit44R > >>>>>> > >> > unnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122) > >>>>>> at > >>>>>> org.powermock.modules.junit4.common.internal.impl.JUnit4Test > >>>>>> SuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106) > >>>>>> at > >>>>>> org.powermock.modules.junit4.common.internal.impl.AbstractCo > >>>>>> > >> > mmonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) > >>>>>> at > >>>>>> > >> > org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner. > >>>> java:59) > >>>>>> at > >>>>>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference. > >>>>>> run(JUnit4TestReference.java:86) > >>>>>> at > >>>>>> org.eclipse.jdt.internal.junit.runner.TestExecution.run( > >>>>>> TestExecution.java:38) > >>>>>> at > >>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTe > >>>>>> sts(RemoteTestRunner.java:539) > >>>>>> at > >>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTe > >>>>>> sts(RemoteTestRunner.java:761) > >>>>>> at > >>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run( > >>>>>> RemoteTestRunner.java:461) > >>>>>> at > >>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main( > >>>>>> RemoteTestRunner.java:207) > >>>>>> > >>>>>> on the classpath jaxb-impl-2.2.5.jar but the specific packages are > only > >>>>>> loaded from rt.jar and redefined. I asume the later is done by > >>>> Powermock. > >>>>>> Line 611: [Loaded > >>>>>> com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory from > >>>>>> C:\Program > >>>>>> Files\Java\jdk1.8.0_161\jre\lib\rt.jar] > >>>>>> Line 616: [Loaded > >>>>>> > com.sun.org.apache.xerces.internal.impl.dv.xs.BaseSchemaDVFactory > >>>> from > >>>>>> C:\Program Files\Java\jdk1.8.0_161\jre\lib\rt.jar] > >>>>>> Line 617: [Loaded > >>>>>> > com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl > >>>> from > >>>>>> C:\Program Files\Java\jdk1.8.0_161\jre\lib\rt.jar] > >>>>>> Line 618: [Loaded > >>>>>> com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory from > >>>>>> __JVM_DefineClass__] > >>>>>> Line 619: [Loaded > >>>>>> > com.sun.org.apache.xerces.internal.impl.dv.xs.BaseSchemaDVFactory > >>>> from > >>>>>> __JVM_DefineClass__] > >>>>>> Line 620: [Loaded > >>>>>> > com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl > >>>> from > >>>>>> __JVM_DefineClass__] > >>>>>> > >>>>>> Is that something you are concerned? > >>>>>> > >>>>>> Gruss > >>>>>> Bernd > >>>>>> From peter.levart at gmail.com Fri Mar 2 09:07:53 2018 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 2 Mar 2018 10:07:53 +0100 Subject: RFR JDK-8187653: Lock in CoderResult.Cache becomes performance bottleneck In-Reply-To: References: <5A90BF44.3030005@oracle.com> <1467288f-e4a6-6160-a566-ef1045d8fd84@oracle.com> <5A98B259.3060600@oracle.com> Message-ID: Hi Sherman, On 03/02/18 03:20, David Holmes wrote: > Also this: > > 195???????? private Map> cache = null; > > should now be volatile. Either that, or you should load the 'cache' field only once per method call into a local variable unless you want reorderings of reads and writes observed from concurrent threads to result in NPE-s. If you do replace it with a volatile, you should also load the field into local variable just once (although not strictly necessary for correctness). Also: ?193???? private abstract static class Cache { ?197 *protected* abstract CoderResult create(int len); the abstract method is protected, but the implementations: ?217???????? = new Cache() { ?218 *public* CoderResult create(int len) { ?219???????????????????? return new CoderResult(CR_MALFORMED, len); ?220???????????????? }}; ...are public. Since you are dealing with private nested class, all create() methods could be package-private. Less words to write and read... Regards, Peter From Alan.Bateman at oracle.com Fri Mar 2 09:13:40 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 2 Mar 2018 09:13:40 +0000 Subject: RFR JDK-8197533 move javax.transaction.xa into its own module In-Reply-To: <98DD56F9-A3F0-4D1D-BCCA-C72220225074@oracle.com> References: <98DD56F9-A3F0-4D1D-BCCA-C72220225074@oracle.com> Message-ID: On 28/02/2018 19:54, Lance Andersen wrote: > : >> >> Is there any XA text from the original JTA spec that should be added >> to the module description as part of this? Another way to ask this is >> whether the JTA 1.3 drops any text dealing with the XA part. > Still waiting to see what changes are made to the PDF spec, that is > still needing to be completed. So I think for now, we go with what we > have and can circle back if needed. > Thanks. I checked the latest webrev (moving the package description to package-info.java and the langtools dot test) and it all looks good to me. -Alan From adam.farley at uk.ibm.com Fri Mar 2 11:37:53 2018 From: adam.farley at uk.ibm.com (Adam Farley8) Date: Fri, 2 Mar 2018 11:37:53 +0000 Subject: RFR: JDK-8190187: C++ code calling JNI_CreateJavaVM can be killed by Java In-Reply-To: References: Message-ID: Hi Alan Thanks for getting back to me on this. :) I've changed the hg_diff as described below, see the attached. > On 27/02/2018 15:04, Adam Farley8 wrote: > > Resending. Bump. :) > > On 14/02/2018 14:13, Adam Farley8 wrote: >>> Hi All, >>> >>> -- Short version -- >>> >>> Could a committer please take the fix for JDK-8190187 (full code included >>> in the bug) and: >>> >>> 1) Complete the CSR process for the new JNI Return code. >>> 2) Commit the changes that contain (a) the new return code, and (b) the >>> non-Hotspot code that handles the new code. >> The patches attached to the JIRA issue are missing the changes to the >> JVM TI spec (jvmti.xml). > >> I'm not seeing the JNI return codes in that file. Are you after one of those >> dated updates near the bottom? >> e.g. >> ``` >> >> Added JNI_SILENT_EXIT return code for early exits without errors. >> java.c's ParseArguments function now sets pret value to 2 for a NULL pwhat. >> This allows us to clearly identify when no class was set, but no other error has occurred. >> This is undone in java.c's ContinueInNewThread method, so the surface behaviour does not change. >> >> ``` > The "Agent Start-Up" section is the section to look at. The important part is: > > "The return value from Agent_OnLoad or Agent_OnLoad_ is used to indicate an error. Any value other than zero indicates an error and causes termination of the VM." > > If there is special return value to mean "VM terminates without error" then this part of the spec will need to be adjusted. Ah, that makes sense. I altered that bit and regenerated the hg_diff. > An additional point is that you can start several agents from the command line, does the VM terminate after it has started all agents or does it terminate when the first agent returns asks the VM to terminate quietly? If I'm reading the code correctly, the loop that initialises the different agents (which I believe to be the loop containing "// Invoke the Agent_OnLoad function") is not interrupted by the return of a silent exit code, however it only takes one agent returning this code to cause the VM to be destroyed once startup is complete. > > > > > >>> There is also text to be written for the JNI spec if this proposal goes >>> ahead. > >> I assume you mean the "RETURNS" section of the JNI_CreateJavaVM >> bit on the invocation.html web page. Something like this? > >> ``` >> RETURNS: >> Returns JNI_OK on success; returns a suitable JNI error code (a negative number) on failure. >> >> The sole exception is a silent exit, which returns JNI error code JNI_SILENT_EXIT. >> This indicates that the VM cannot be used, but that this is the intended behaviour for the >> arguments used. E.g. -Xlog:help (which prints help output and then destroys the VM) >> ``` > Yes, this is the place that will need changes. > Ok. The most official-looking place for this documentation is on the Oracle website. I'm not sure how to go about making this change happen though. Is the change to this documentation something I can push through one of the mailing lists? Or is it perhaps part of the CSR process? > > > > >>> >>> I don't agree that the launcher should be looking for >>> "-agentlib:jdwp=help" in the command line as it's just one of many ways >>> that the debugger agent might be started (e.g. -Xrunjdwp:, >>> _JAVA_TOOLS_OPTIONS, ...). > >> We can avoid that by finding a way around this line in ContinueInNewThread (java.c): > >> ``` >> return (ret != 0) ? ret : rslt; >> ``` > >> I have devised a means to do this, as outlined in the jvmti.xml change above. I put the >> changes into a recent clone of jdk/jdk, and attached the hg diff, along with an improved >> test. > > The launcher should only need to look at the return value from JNI CreateJavaVM. I don't think it should do any special handling for the JDWP or other agents (there are just too many ways to inject command lines and the launcher cannot be expected to handle all of them). > >-Alan > I agree. The change I made in response to your earlier comment is not jdwp-specific. Rather, it sets "ret" to "2" if the user has not specified an executable class in the command line. I did this because a ret value of "1" indicates an error, but we don't want to override a return code of JNI_SILENT_EXIT with ret's value if the only error was "no class was specified". So I set ret to "2" if no class is specified, and altered the aforementioned bit in ContinueInNewThread (java.c) to pick up on a ret value of 2. If the ret value is 2, and rslt is JNI_SILENT_EXIT, then we know that no error has occurred (other than "no class was specified"), and that JNI_SILENT_EXIT should be returned, as opposed to the current functionality, where it is the non-0 ret value which is returned (erroneously, in the event of a silent exit). I think my changeset explains this more concisely than I have. :) Let me know if this has just made you more confused. :) - Adam 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 -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: hg_diff.txt URL: From james.laskey at oracle.com Fri Mar 2 14:43:00 2018 From: james.laskey at oracle.com (Jim Laskey) Date: Fri, 2 Mar 2018 10:43:00 -0400 Subject: RFR: JDK-8198955 - String#repeat loop optimization Message-ID: <8D25B693-7199-4F67-B08A-AC3B0A5F686D@oracle.com> Verified to work on edge cases. JBS: https://bugs.openjdk.java.net/browse/JDK-8198955 Webrev: http://cr.openjdk.java.net/~jlaskey/8198955/webrev/index.html From Roger.Riggs at Oracle.com Fri Mar 2 15:00:20 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 2 Mar 2018 10:00:20 -0500 Subject: RFR: Here are some URLClassPath patches In-Reply-To: References: <912a66bb-45d3-0248-7f8e-b43da9b33ff9@oracle.com> <684a8186-6d29-1e52-34cd-3ceb13b2ff4f@oracle.com> <90892fc9-31f0-1da8-46f9-56c91865cb99@oracle.com> Message-ID: Hi Martin, I created the subtask for the release note[1], please review and update the summary and description. When it is done, close it as 'delivered'. Thanks, Roger [1] https://bugs.openjdk.java.net/browse/JDK-8198956 On 3/1/2018 10:32 PM, Martin Buchholz wrote: > On Wed, Feb 28, 2018 at 3:58 PM, Martin Buchholz > wrote: > >> >> 8198810: URLClassLoader does not specify behavior when URL array contains >> null >> http://cr.openjdk.java.net/~martin/webrevs/jdk/URLClassLoader-NPE/ >> https://bugs.openjdk.java.net/browse/JDK-8198810 >> > Pushed. Can someone at Oracle help with the release note? From Roger.Riggs at Oracle.com Fri Mar 2 15:07:34 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 2 Mar 2018 10:07:34 -0500 Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method In-Reply-To: References: Message-ID: Hi Naoto, String.java: 3129: Please add a message to the throw IAE.? "Not a valid Unicode code point". Roger On 3/1/2018 9:47 PM, naoto.sato at oracle.com wrote: > Hi, > > Please review the fix to the following issue: > > https://bugs.openjdk.java.net/browse/JDK-4993841 > > The proposed changeset is located at: > > http://cr.openjdk.java.net/~naoto/4993841/webrev.03/ > > This stems from the recent discussion regarding String.repeat().[1] > The corresponding CSR has already been approved. > > Naoto > > -- > [1] > http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051568.html From Roger.Riggs at Oracle.com Fri Mar 2 15:27:37 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 2 Mar 2018 10:27:37 -0500 Subject: RFR: JDK-8198955 - String#repeat loop optimization In-Reply-To: <8D25B693-7199-4F67-B08A-AC3B0A5F686D@oracle.com> References: <8D25B693-7199-4F67-B08A-AC3B0A5F686D@oracle.com> Message-ID: <8c680c15-eac6-1d4f-9303-c079ae35cf59@Oracle.com> +1 On 3/2/2018 9:43 AM, Jim Laskey wrote: > Verified to work on edge cases. > > JBS: https://bugs.openjdk.java.net/browse/JDK-8198955 > Webrev: http://cr.openjdk.java.net/~jlaskey/8198955/webrev/index.html From Roger.Riggs at Oracle.com Fri Mar 2 15:49:11 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 2 Mar 2018 10:49:11 -0500 Subject: RFR 8198697: Simplify platform encoding initialization tweak In-Reply-To: <0ea3699b-e4ab-ceca-e0d7-d41c2ed675f4@Oracle.com> References: <0ea3699b-e4ab-ceca-e0d7-d41c2ed675f4@Oracle.com> Message-ID: <365a6a3e-1f9f-0ad7-ed82-3fbe0b94aa98@Oracle.com> Please review... On 2/28/2018 9:45 AM, Roger Riggs wrote: > Hi, > > In an effort to untangle some of the issues with property > initialization I was looking > at the platform encoding initialization and found a simplification. > > Currently, the initialization occurs as a side effect of the first > call to JNU_NewStringPlatform and > involves a upcall to get sun.jnu.encoding from the system properties.? > The value is cached for later use. > > The native System.initProperties determines the platform specific > encoding via java_props_md.c and does an upcall to set the > sun.jnu.encoding system property, taking care to do it before the > first string that needs platform encoding. > > The change directly initializes the platform encoding fast path before > it is needed to encode platform strings. > And moves the setting sun.jnu.encoding system property after the > command line arguments are inserted > keeping it from being overridden by -D on the command line that can > only confuse confusion > with code that later reads the property. > > Please review and comment. > > webrev: > ?? http://cr.openjdk.java.net/~rriggs/webrev-simplify-jnu-8198697/ > > Issue: > ?? https://bugs.openjdk.java.net/browse/JDK-8198697 > > Thanks, Roger > > > > From david.lloyd at redhat.com Fri Mar 2 16:07:43 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Fri, 2 Mar 2018 10:07:43 -0600 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater Message-ID: The third... and hopefully final... version of this patch is attached. It is the same as V2, however it also uses Reference.reachabilityFence() defensively on buffers. This may be necessary because there are code paths which may allow such buffers to be GCed after their address is acquired but before the native code successfully is able to read it. The online version of this patch is visible at [1]. [1] https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v8 -- - DML -------------- next part -------------- commit 09313d25a1362039806a0c1b2d443874eb101843 Author: David M. Lloyd Date: Fri Feb 16 11:00:10 2018 -0600 [JDK-6341887] Update Inflater/Deflater to handle ByteBuffer diff --git a/make/mapfiles/libzip/mapfile-vers b/make/mapfiles/libzip/mapfile-vers index d711d8e17f4..11ccc2d6ecb 100644 --- a/make/mapfiles/libzip/mapfile-vers +++ b/make/mapfiles/libzip/mapfile-vers @@ -33,20 +33,28 @@ SUNWprivate_1.1 { Java_java_util_zip_CRC32_update; Java_java_util_zip_CRC32_updateBytes0; Java_java_util_zip_CRC32_updateByteBuffer0; - Java_java_util_zip_Deflater_deflateBytes; + Java_java_util_zip_Deflater_deflateBytesBytes; + Java_java_util_zip_Deflater_deflateBytesBuffer; + Java_java_util_zip_Deflater_deflateBufferBytes; + Java_java_util_zip_Deflater_deflateBufferBuffer; Java_java_util_zip_Deflater_end; Java_java_util_zip_Deflater_getAdler; Java_java_util_zip_Deflater_init; Java_java_util_zip_Deflater_initIDs; Java_java_util_zip_Deflater_reset; Java_java_util_zip_Deflater_setDictionary; + Java_java_util_zip_Deflater_setDictionaryBuffer; Java_java_util_zip_Inflater_end; Java_java_util_zip_Inflater_getAdler; - Java_java_util_zip_Inflater_inflateBytes; + Java_java_util_zip_Inflater_inflateBytesBytes; + Java_java_util_zip_Inflater_inflateBytesBuffer; + Java_java_util_zip_Inflater_inflateBufferBytes; + Java_java_util_zip_Inflater_inflateBufferBuffer; Java_java_util_zip_Inflater_init; Java_java_util_zip_Inflater_initIDs; Java_java_util_zip_Inflater_reset; Java_java_util_zip_Inflater_setDictionary; + Java_java_util_zip_Inflater_setDictionaryBuffer; ZIP_Close; ZIP_CRC32; ZIP_FreeEntry; diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java b/src/java.base/share/classes/java/util/zip/Deflater.java index c75dd4a33f0..524125787a8 100644 --- a/src/java.base/share/classes/java/util/zip/Deflater.java +++ b/src/java.base/share/classes/java/util/zip/Deflater.java @@ -26,7 +26,13 @@ package java.util.zip; import java.lang.ref.Cleaner.Cleanable; +import java.lang.ref.Reference; +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; +import java.util.Objects; + import jdk.internal.ref.CleanerFactory; +import sun.nio.ch.DirectBuffer; /** * This class provides support for general purpose compression using the @@ -92,8 +98,9 @@ import jdk.internal.ref.CleanerFactory; public class Deflater { private final DeflaterZStreamRef zsRef; - private byte[] buf = new byte[0]; - private int off, len; + private ByteBuffer input = ZipUtils.defaultBuf; + private byte[] inputArray; + private int inputPos, inputLim; private int level, strategy; private boolean setParams; private boolean finish, finished; @@ -170,9 +177,14 @@ public class Deflater { */ public static final int FULL_FLUSH = 3; + /** + * Flush mode to use at the end of output. Can only be provided by the + * user by way of {@link #finish()}. + */ + private static final int FINISH = 4; + static { ZipUtils.loadLibrary(); - initIDs(); } /** @@ -216,16 +228,14 @@ public class Deflater { * @see Deflater#needsInput */ public void setInput(byte[] b, int off, int len) { - if (b== null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { - this.buf = b; - this.off = off; - this.len = len; + this.input = null; + this.inputArray = b; + this.inputPos = off; + this.inputLim = off + len; } } @@ -239,6 +249,31 @@ public class Deflater { setInput(b, 0, b.length); } + /** + * Sets input data for compression. This should be called whenever + * needsInput() returns true indicating that more input data is required. + *

+ * The given buffer's position will be updated as deflate operations are + * performed. The input buffer may be modified (refilled) between deflate + * operations; doing so is equivalent to creating a new buffer and setting + * it with this method. + *

+ * Modifying the input buffer's contents, position, or limit concurrently with + * a deflate operation will result in undefined behavior, which may include + * incorrect operation results or operation failure. + * + * @param byteBuffer the input data bytes + * @see Deflater#needsInput + * @since 11 + */ + public void setInput(ByteBuffer byteBuffer) { + Objects.requireNonNull(byteBuffer); + synchronized (zsRef) { + this.input = byteBuffer; + this.inputArray = null; + } + } + /** * Sets preset dictionary for compression. A preset dictionary is used * when the history buffer can be predetermined. When the data is later @@ -252,9 +287,6 @@ public class Deflater { * @see Inflater#getAdler */ public void setDictionary(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } @@ -278,6 +310,41 @@ public class Deflater { setDictionary(b, 0, b.length); } + /** + * Sets preset dictionary for compression. A preset dictionary is used + * when the history buffer can be predetermined. When the data is later + * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called + * in order to get the Adler-32 value of the dictionary required for + * decompression. + *

+ * The bytes in given byte buffer will be fully consumed by this method. On + * return, its position will equal its limit. + * + * @param byteBuffer the dictionary data bytes + * @see Inflater#inflate + * @see Inflater#getAdler + */ + public void setDictionary(ByteBuffer byteBuffer) { + synchronized (zsRef) { + final int position = byteBuffer.position(); + final int remaining = Math.max(byteBuffer.limit() - position, 0); + ensureOpen(); + if (byteBuffer.isDirect()) { + final long address = ((DirectBuffer) byteBuffer).address(); + try { + setDictionaryBuffer(zsRef.address(), address + position, remaining); + } finally { + Reference.reachabilityFence(byteBuffer); + } + } else { + final byte[] array = ZipUtils.getBufferArray(byteBuffer); + final int offset = ZipUtils.getBufferOffset(byteBuffer); + setDictionary(zsRef.address(), array, offset + position, remaining); + } + byteBuffer.position(position + remaining); + } + } + /** * Sets the compression strategy to the specified value. * @@ -331,14 +398,17 @@ public class Deflater { } /** - * Returns true if the input data buffer is empty and setInput() - * should be called in order to provide more input. + * Returns true if no data remains in the input buffer. This can + * be used to determine if one of the {@code setInput()} methods should be + * called in order to provide more input. + * * @return true if the input data buffer is empty and setInput() * should be called in order to provide more input */ public boolean needsInput() { synchronized (zsRef) { - return len <= 0; + final ByteBuffer input = this.input; + return input == null ? inputLim == inputPos : ! input.hasRemaining(); } } @@ -404,6 +474,26 @@ public class Deflater { return deflate(b, 0, b.length, NO_FLUSH); } + /** + * Compresses the input data and fills specified buffer with compressed + * data. Returns actual number of bytes of compressed data. A return value + * of 0 indicates that {@link #needsInput() needsInput} should be called + * in order to determine if more input data is required. + * + *

This method uses {@link #NO_FLUSH} as its compression flush mode. + * An invocation of this method of the form {@code deflater.deflate(b)} + * yields the same result as the invocation of + * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. + * + * @param output the buffer for the compressed data + * @return the actual number of bytes of compressed data written to the + * output buffer + * @since 11 + */ + public int deflate(ByteBuffer output) { + return deflate(output, NO_FLUSH); + } + /** * Compresses the input data and fills the specified buffer with compressed * data. Returns actual number of bytes of data compressed. @@ -441,6 +531,10 @@ public class Deflater { * repeatedly output to the output buffer every time this method is * invoked. * + *

If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation. + * * @param b the buffer for the compressed data * @param off the start offset of the data * @param len the maximum number of bytes of compressed data @@ -452,24 +546,247 @@ public class Deflater { * @since 1.7 */ public int deflate(byte[] b, int off, int len, int flush) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } + if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) { + throw new IllegalArgumentException(); + } synchronized (zsRef) { ensureOpen(); - if (flush == NO_FLUSH || flush == SYNC_FLUSH || - flush == FULL_FLUSH) { - int thisLen = this.len; - int n = deflateBytes(zsRef.address(), b, off, len, flush); - bytesWritten += n; - bytesRead += (thisLen - this.len); - return n; + + final ByteBuffer input = this.input; + if (finish) { + // disregard given flush mode in this case + flush = FINISH; + } + final int params; + if (setParams) { + // bit 0: true to set params + // bit 1-2: strategy (0, 1, or 2) + // bit 3-31: level (0..9 or -1) + params = 1 | strategy << 1 | level << 3; + } else { + params = 0; + } + final int inputPos; + final long result; + if (input == null) { + inputPos = this.inputPos; + result = deflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + b, off, len, + flush, params); + } else { + inputPos = input.position(); + final int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + try { + final long inputAddress = ((DirectBuffer) input).address(); + result = deflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + b, off, len, + flush, params); + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + b, off, len, + flush, params); + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if (params != 0 && (result >>> 63 & 1) == 0) { + setParams = false; } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + bytesWritten += written; + bytesRead += read; + return written; + } + } + + /** + * Compresses the input data and fills the specified buffer with compressed + * data. Returns actual number of bytes of data compressed. + * + *

Compression flush mode is one of the following three modes: + * + *

    + *
  • {@link #NO_FLUSH}: allows the deflater to decide how much data + * to accumulate, before producing output, in order to achieve the best + * compression (should be used in normal use scenario). A return value + * of 0 in this flush mode indicates that {@link #needsInput()} should + * be called in order to determine if more input data is required. + * + *
  • {@link #SYNC_FLUSH}: all pending output in the deflater is flushed, + * to the specified output buffer, so that an inflater that works on + * compressed data can get all input data available so far (In particular + * the {@link #needsInput()} returns {@code true} after this invocation + * if enough output space is provided). Flushing with {@link #SYNC_FLUSH} + * may degrade compression for some compression algorithms and so it + * should be used only when necessary. + * + *
  • {@link #FULL_FLUSH}: all pending output is flushed out as with + * {@link #SYNC_FLUSH}. The compression state is reset so that the inflater + * that works on the compressed output data can restart from this point + * if previous compressed data has been damaged or if random access is + * desired. Using {@link #FULL_FLUSH} too often can seriously degrade + * compression. + *
+ * + *

In the case of {@link #FULL_FLUSH} or {@link #SYNC_FLUSH}, if + * the return value is {@code len}, the space available in output + * buffer {@code output}, this method should be invoked again with the same + * {@code flush} parameter and more output space. Make sure that + * {@code len} is greater than 6 to avoid flush marker (5 bytes) being + * repeatedly output to the output buffer every time this method is + * invoked. + * + *

On success, the position of the given {@code output} byte buffer will be + * advanced by as many bytes as were produced by the operation, which is equal + * to the number returned by this method. + * + *

If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation. + * + * @param output the buffer for the compressed data + * @param flush the compression flush mode + * @return the actual number of bytes of compressed data written to + * the output buffer + * + * @throws IllegalArgumentException if the flush mode is invalid + * @since 11 + */ + public int deflate(ByteBuffer output, int flush) { + if (output.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) { throw new IllegalArgumentException(); } + synchronized (zsRef) { + ensureOpen(); + + final ByteBuffer input = this.input; + if (finish) { + // disregard given flush mode in this case + flush = FINISH; + } + final int params; + if (setParams) { + // bit 0: true to set params + // bit 1-2: strategy (0, 1, or 2) + // bit 3-31: level (0..9 or -1) + params = 1 | strategy << 1 | level << 3; + } else { + params = 0; + } + final int outputPos = output.position(); + final int outputRem = Math.max(output.limit() - outputPos, 0); + final int inputPos; + final long result; + if (input == null) { + inputPos = this.inputPos; + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = deflateBytesBuffer(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputAddress + outputPos, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } else { + inputPos = input.position(); + final int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + final long inputAddress = ((DirectBuffer) input).address(); + try { + if (output.isDirect()) { + final long outputAddress = outputPos + ((DirectBuffer) output).address(); + try { + result = deflateBufferBuffer(zsRef.address(), + inputAddress + inputPos, inputRem, + outputAddress, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = deflateBytesBuffer(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputAddress + outputPos, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if (params != 0 && (result >>> 63 & 1) == 0) { + setParams = false; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + output.position(outputPos + written); + bytesWritten += written; + bytesRead += read; + return written; + } } /** @@ -545,7 +862,8 @@ public class Deflater { reset(zsRef.address()); finish = false; finished = false; - off = len = 0; + input = ZipUtils.defaultBuf; + inputArray = null; bytesRead = bytesWritten = 0; } } @@ -560,7 +878,7 @@ public class Deflater { public void end() { synchronized (zsRef) { zsRef.clean(); - buf = null; + input = ZipUtils.defaultBuf; } } @@ -585,11 +903,26 @@ public class Deflater { throw new NullPointerException("Deflater has been closed"); } - private static native void initIDs(); private static native long init(int level, int strategy, boolean nowrap); - private static native void setDictionary(long addr, byte[] b, int off, int len); - private native int deflateBytes(long addr, byte[] b, int off, int len, - int flush); + private static native void setDictionary(long addr, byte[] b, int off, + int len); + private static native void setDictionaryBuffer(long addr, long bufAddress, int len); + private native long deflateBytesBytes(long addr, + byte[] inputArray, int inputOff, int inputLen, + byte[] outputArray, int outputOff, int outputLen, + int flush, int params); + private native long deflateBytesBuffer(long addr, + byte[] inputArray, int inputOff, int inputLen, + long outputAddress, int outputLen, + int flush, int params); + private native long deflateBufferBytes(long addr, + long inputAddress, int inputLen, + byte[] outputArray, int outputOff, int outputLen, + int flush, int params); + private native long deflateBufferBuffer(long addr, + long inputAddress, int inputLen, + long outputAddress, int outputLen, + int flush, int params); private static native int getAdler(long addr); private static native void reset(long addr); private static native void end(long addr); diff --git a/src/java.base/share/classes/java/util/zip/Inflater.java b/src/java.base/share/classes/java/util/zip/Inflater.java index 9c6d8aa3d83..db53f574de2 100644 --- a/src/java.base/share/classes/java/util/zip/Inflater.java +++ b/src/java.base/share/classes/java/util/zip/Inflater.java @@ -26,7 +26,13 @@ package java.util.zip; import java.lang.ref.Cleaner.Cleanable; +import java.lang.ref.Reference; +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; +import java.util.Objects; + import jdk.internal.ref.CleanerFactory; +import sun.nio.ch.DirectBuffer; /** * This class provides support for general purpose decompression using the @@ -92,14 +98,19 @@ import jdk.internal.ref.CleanerFactory; public class Inflater { private final InflaterZStreamRef zsRef; - private byte[] buf = defaultBuf; - private int off, len; + private ByteBuffer input = ZipUtils.defaultBuf; + private byte[] inputArray; + private int inputPos, inputLim; private boolean finished; private boolean needDict; private long bytesRead; private long bytesWritten; - private static final byte[] defaultBuf = new byte[0]; + /** + * This field is used as an "out" parameter from JNI when a + * {@link DataFormatException} is thrown during the inflate operation. + */ + private int inputConsumed; static { ZipUtils.loadLibrary(); @@ -138,16 +149,14 @@ public class Inflater { * @see Inflater#needsInput */ public void setInput(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { - this.buf = b; - this.off = off; - this.len = len; + this.input = null; + this.inputArray = b; + this.inputPos = off; + this.inputLim = off + len; } } @@ -162,6 +171,32 @@ public class Inflater { setInput(b, 0, b.length); } + /** + * Sets input data for decompression. Should be called whenever + * needsInput() returns true indicating that more input data is + * required. + *

+ * The given buffer's position will be updated as inflate operations are + * performed. The input buffer may be modified (refilled) between inflate + * operations; doing so is equivalent to creating a new buffer and setting + * it with this method. + *

+ * Modifying the input buffer's contents, position, or limit concurrently with + * an inflate operation will result in undefined behavior, which may include + * incorrect operation results or operation failure. + * + * @param byteBuffer the input data bytes + * @see Inflater#needsInput + * @since 11 + */ + public void setInput(ByteBuffer byteBuffer) { + Objects.requireNonNull(byteBuffer); + synchronized (zsRef) { + this.input = byteBuffer; + this.inputArray = null; + } + } + /** * Sets the preset dictionary to the given array of bytes. Should be * called when inflate() returns 0 and needsDictionary() returns true @@ -174,9 +209,6 @@ public class Inflater { * @see Inflater#getAdler */ public void setDictionary(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } @@ -200,6 +232,42 @@ public class Inflater { setDictionary(b, 0, b.length); } + /** + * Sets the preset dictionary to the given array of bytes. Should be + * called when inflate() returns 0 and needsDictionary() returns true + * indicating that a preset dictionary is required. The method getAdler() + * can be used to get the Adler-32 value of the dictionary needed. + *

+ * The bytes in given byte buffer will be fully consumed by this method. On + * return, its position will equal its limit. + * + * @param byteBuffer the dictionary data bytes + * @see Inflater#needsDictionary + * @see Inflater#getAdler + * @since 11 + */ + public void setDictionary(ByteBuffer byteBuffer) { + synchronized (zsRef) { + final int position = byteBuffer.position(); + final int remaining = Math.max(byteBuffer.limit() - position, 0); + ensureOpen(); + if (byteBuffer.isDirect()) { + final long address = ((DirectBuffer) byteBuffer).address(); + try { + setDictionaryBuffer(zsRef.address(), address + position, remaining); + } finally { + Reference.reachabilityFence(byteBuffer); + } + } else { + final byte[] array = ZipUtils.getBufferArray(byteBuffer); + final int offset = ZipUtils.getBufferOffset(byteBuffer); + setDictionary(zsRef.address(), array, offset + position, remaining); + } + byteBuffer.position(position + remaining); + needDict = false; + } + } + /** * Returns the total number of bytes remaining in the input buffer. * This can be used to find out what bytes still remain in the input @@ -208,19 +276,22 @@ public class Inflater { */ public int getRemaining() { synchronized (zsRef) { - return len; + final ByteBuffer input = this.input; + return input == null ? inputLim - inputPos : input.remaining(); } } /** * Returns true if no data remains in the input buffer. This can - * be used to determine if #setInput should be called in order - * to provide more input. + * be used to determine if one of the {@code setInput()} methods should be + * called in order to provide more input. + * * @return true if no data remains in the input buffer */ public boolean needsInput() { synchronized (zsRef) { - return len <= 0; + final ByteBuffer input = this.input; + return input == null ? inputLim == inputPos : ! input.hasRemaining(); } } @@ -254,30 +325,87 @@ public class Inflater { * determine if more input data or a preset dictionary is required. * In the latter case, getAdler() can be used to get the Adler-32 * value of the dictionary required. + *

+ * If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation, even in the event that an exception is thrown. + * * @param b the buffer for the uncompressed data * @param off the start offset of the data * @param len the maximum number of uncompressed bytes * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid + * @throws DataFormatException if the compressed data format is invalid * @see Inflater#needsInput * @see Inflater#needsDictionary */ public int inflate(byte[] b, int off, int len) throws DataFormatException { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { ensureOpen(); - int thisLen = this.len; - int n = inflateBytes(zsRef.address(), b, off, len); - bytesWritten += n; - bytesRead += (thisLen - this.len); - return n; + final ByteBuffer input = this.input; + final long result; + final int inputPos; + if (input == null) { + inputPos = this.inputPos; + try { + result = inflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + b, off, len); + } catch (DataFormatException e) { + int read = inputConsumed; + this.inputPos = inputPos + read; + bytesRead += read; + inputConsumed = 0; + throw e; + } + } else { + inputPos = input.position(); + try { + final int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + try { + final long inputAddress = ((DirectBuffer) input).address(); + result = inflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + b, off, len); + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + b, off, len); + } + } catch (DataFormatException e) { + int read = inputConsumed; + input.position(inputPos + read); + bytesRead += read; + inputConsumed = 0; + throw e; + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if ((result >>> 63 & 1) != 0) { + needDict = true; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + bytesWritten += written; + bytesRead += read; + return written; } } @@ -288,9 +416,14 @@ public class Inflater { * determine if more input data or a preset dictionary is required. * In the latter case, getAdler() can be used to get the Adler-32 * value of the dictionary required. + *

+ * If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation, even in the event that an exception is thrown. + * * @param b the buffer for the uncompressed data * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid + * @throws DataFormatException if the compressed data format is invalid * @see Inflater#needsInput * @see Inflater#needsDictionary */ @@ -298,6 +431,142 @@ public class Inflater { return inflate(b, 0, b.length); } + /** + * Uncompresses bytes into specified buffer. Returns actual number + * of bytes uncompressed. A return value of 0 indicates that + * needsInput() or needsDictionary() should be called in order to + * determine if more input data or a preset dictionary is required. + * In the latter case, getAdler() can be used to get the Adler-32 + * value of the dictionary required. + *

+ * On success, the position of the given {@code output} byte buffer will be + * advanced by as many bytes as were produced by the operation, which is equal + * to the number returned by this method. + *

+ * If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation, even in the event that an exception is thrown. + * + * @param output the buffer for the uncompressed data + * @return the actual number of uncompressed bytes + * @throws DataFormatException if the compressed data format is invalid + * @throws ReadOnlyBufferException if the given output buffer is read-only + * @see Inflater#needsInput + * @see Inflater#needsDictionary + * @since 11 + */ + public int inflate(ByteBuffer output) throws DataFormatException { + if (output.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + synchronized (zsRef) { + ensureOpen(); + final ByteBuffer input = this.input; + final long result; + final int inputPos; + final int outputPos = output.position(); + final int outputRem = Math.max(output.limit() - outputPos, 0); + if (input == null) { + inputPos = this.inputPos; + try { + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBytesBuffer(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputArray, outputOffset + outputPos, outputRem); + } + } catch (DataFormatException e) { + int read = inputConsumed; + this.inputPos = inputPos + read; + bytesRead += read; + inputConsumed = 0; + throw e; + } + } else { + inputPos = input.position(); + final int inputRem = Math.max(input.limit() - inputPos, 0); + try { + if (input.isDirect()) { + final long inputAddress = ((DirectBuffer) input).address(); + try { + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBufferBuffer(zsRef.address(), + inputAddress + inputPos, inputRem, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem); + } + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBytesBuffer(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem); + } + } + } catch (DataFormatException e) { + int read = inputConsumed; + input.position(inputPos + read); + bytesRead += read; + inputConsumed = 0; + throw e; + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if ((result >>> 63 & 1) != 0) { + needDict = true; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + // Note: this method call also serves to keep the byteBuffer ref alive + output.position(outputPos + written); + bytesWritten += written; + bytesRead += read; + return written; + } + } + /** * Returns the ADLER-32 value of the uncompressed data. * @return the ADLER-32 value of the uncompressed data @@ -368,10 +637,10 @@ public class Inflater { synchronized (zsRef) { ensureOpen(); reset(zsRef.address()); - buf = defaultBuf; + input = ZipUtils.defaultBuf; + inputArray = null; finished = false; needDict = false; - off = len = 0; bytesRead = bytesWritten = 0; } } @@ -386,7 +655,8 @@ public class Inflater { public void end() { synchronized (zsRef) { zsRef.clean(); - buf = null; + input = ZipUtils.defaultBuf; + inputArray = null; } } @@ -416,18 +686,23 @@ public class Inflater { throw new NullPointerException("Inflater has been closed"); } - boolean ended() { - synchronized (zsRef) { - return zsRef.address() == 0; - } - } - private static native void initIDs(); private static native long init(boolean nowrap); private static native void setDictionary(long addr, byte[] b, int off, int len); - private native int inflateBytes(long addr, byte[] b, int off, int len) - throws DataFormatException; + private static native void setDictionaryBuffer(long addr, long bufAddress, int len); + private native long inflateBytesBytes(long addr, + byte[] inputArray, int inputOff, int inputLen, + byte[] outputArray, int outputOff, int outputLen) throws DataFormatException; + private native long inflateBytesBuffer(long addr, + byte[] inputArray, int inputOff, int inputLen, + long outputAddress, int outputLen) throws DataFormatException; + private native long inflateBufferBytes(long addr, + long inputAddress, int inputLen, + byte[] outputArray, int outputOff, int outputLen) throws DataFormatException; + private native long inflateBufferBuffer(long addr, + long inputAddress, int inputLen, + long outputAddress, int outputLen) throws DataFormatException; private static native int getAdler(long addr); private static native void reset(long addr); private static native void end(long addr); diff --git a/src/java.base/share/classes/java/util/zip/ZipUtils.java b/src/java.base/share/classes/java/util/zip/ZipUtils.java index 45c5d8dbb67..07e64e4fa92 100644 --- a/src/java.base/share/classes/java/util/zip/ZipUtils.java +++ b/src/java.base/share/classes/java/util/zip/ZipUtils.java @@ -25,6 +25,8 @@ package java.util.zip; +import java.nio.Buffer; +import java.nio.ByteBuffer; import java.nio.file.attribute.FileTime; import java.security.AccessController; import java.security.PrivilegedAction; @@ -37,6 +39,9 @@ import java.util.concurrent.TimeUnit; import static java.util.zip.ZipConstants.ENDHDR; +import jdk.internal.misc.Unsafe; +import sun.nio.ch.DirectBuffer; + class ZipUtils { // used to adjust values between Windows and java epoch @@ -45,6 +50,8 @@ class ZipUtils { // used to indicate the corresponding windows time is not available public static final long WINDOWS_TIME_NOT_AVAILABLE = Long.MIN_VALUE; + static final ByteBuffer defaultBuf = ByteBuffer.allocateDirect(0); + /** * Converts Windows time (in microseconds, UTC/GMT) time to FileTime. */ @@ -281,4 +288,17 @@ class ZipUtils { AccessController.doPrivileged(pa); } } + + private static final Unsafe unsafe = Unsafe.getUnsafe(); + + private static final long byteBufferArrayOffset = unsafe.objectFieldOffset(ByteBuffer.class, "hb"); + private static final long byteBufferOffsetOffset = unsafe.objectFieldOffset(ByteBuffer.class, "offset"); + + static byte[] getBufferArray(ByteBuffer byteBuffer) { + return (byte[]) unsafe.getObject(byteBuffer, byteBufferArrayOffset); + } + + static int getBufferOffset(ByteBuffer byteBuffer) { + return unsafe.getInt(byteBuffer, byteBufferOffsetOffset); + } } diff --git a/src/java.base/share/native/libzip/Deflater.c b/src/java.base/share/native/libzip/Deflater.c index b666a16145a..b56df5ecc1b 100644 --- a/src/java.base/share/native/libzip/Deflater.c +++ b/src/java.base/share/native/libzip/Deflater.c @@ -38,34 +38,6 @@ #define DEF_MEM_LEVEL 8 -static jfieldID levelID; -static jfieldID strategyID; -static jfieldID setParamsID; -static jfieldID finishID; -static jfieldID finishedID; -static jfieldID bufID, offID, lenID; - -JNIEXPORT void JNICALL -Java_java_util_zip_Deflater_initIDs(JNIEnv *env, jclass cls) -{ - levelID = (*env)->GetFieldID(env, cls, "level", "I"); - CHECK_NULL(levelID); - strategyID = (*env)->GetFieldID(env, cls, "strategy", "I"); - CHECK_NULL(strategyID); - setParamsID = (*env)->GetFieldID(env, cls, "setParams", "Z"); - CHECK_NULL(setParamsID); - finishID = (*env)->GetFieldID(env, cls, "finish", "Z"); - CHECK_NULL(finishID); - finishedID = (*env)->GetFieldID(env, cls, "finished", "Z"); - CHECK_NULL(finishedID); - bufID = (*env)->GetFieldID(env, cls, "buf", "[B"); - CHECK_NULL(bufID); - offID = (*env)->GetFieldID(env, cls, "off", "I"); - CHECK_NULL(offID); - lenID = (*env)->GetFieldID(env, cls, "len", "I"); - CHECK_NULL(lenID); -} - JNIEXPORT jlong JNICALL Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level, jint strategy, jboolean nowrap) @@ -104,17 +76,9 @@ Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level, } } -JNIEXPORT void JNICALL -Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, - jarray b, jint off, jint len) +static void doSetDictionary(JNIEnv *env, jlong addr, jbyte *buf, jint len) { - Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - int res; - if (buf == 0) {/* out of memory */ - return; - } - res = deflateSetDictionary((z_stream *)jlong_to_ptr(addr), buf + off, len); - (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); + int res = deflateSetDictionary(jlong_to_ptr(addr), (Bytef *) buf, len); switch (res) { case Z_OK: break; @@ -127,94 +91,169 @@ Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, } } -JNIEXPORT jint JNICALL -Java_java_util_zip_Deflater_deflateBytes(JNIEnv *env, jobject this, jlong addr, - jarray b, jint off, jint len, jint flush) +JNIEXPORT void JNICALL +Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, + jbyteArray b, jint off, jint len) +{ + jbyte *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); + if (buf == NULL) /* out of memory */ + return; + doSetDictionary(env, addr, buf + off, len); + (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); +} + +JNIEXPORT void JNICALL +Java_java_util_zip_Deflater_setDictionaryBuffer(JNIEnv *env, jclass cls, jlong addr, + jlong bufferAddr, jint len) +{ + jbyte *buf = jlong_to_ptr(bufferAddr); + doSetDictionary(env, addr, buf, len); +} + +static jlong doDeflate(JNIEnv *env, jobject this, jlong addr, + jbyte *input, jint inputLen, + jbyte *output, jint outputLen, + jint flush, jint params) { z_stream *strm = jlong_to_ptr(addr); + jint inputUsed = 0, outputUsed = 0; - jarray this_buf = (*env)->GetObjectField(env, this, bufID); - jint this_off = (*env)->GetIntField(env, this, offID); - jint this_len = (*env)->GetIntField(env, this, lenID); - jbyte *in_buf; - jbyte *out_buf; - int res; - if ((*env)->GetBooleanField(env, this, setParamsID)) { - int level = (*env)->GetIntField(env, this, levelID); - int strategy = (*env)->GetIntField(env, this, strategyID); - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - // Throw OOME only when length is not zero - if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } + strm->next_in = (Bytef *) input; + strm->next_out = (Bytef *) output; + strm->avail_in = inputLen; + strm->avail_out = outputLen; + + int finished = 0; + int setParams = params & 1; - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - res = deflateParams(strm, level, strategy); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + if (setParams) { + int strategy = (params >> 1) & 3; + int level = params >> 3; + int res = deflateParams(strm, level, strategy); switch (res) { case Z_OK: - (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE); + setParams = 0; + /* fall through */ case Z_BUF_ERROR: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return (jint) (len - strm->avail_out); + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; default: JNU_ThrowInternalError(env, strm->msg); return 0; } } else { - jboolean finish = (*env)->GetBooleanField(env, this, finishID); - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - if (this_len != 0) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0) - JNU_ThrowOutOfMemoryError(env, 0); - - return 0; - } - - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - res = deflate(strm, finish ? Z_FINISH : flush); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + int res = deflate(strm, flush); switch (res) { case Z_STREAM_END: - (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); + finished = 1; /* fall through */ case Z_OK: case Z_BUF_ERROR: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return len - strm->avail_out; + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; default: JNU_ThrowInternalError(env, strm->msg); return 0; } } + return ((jlong)inputUsed) | (((jlong)outputUsed) << 31) | (((jlong)finished) << 62) | (((jlong)setParams) << 63); +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBytesBytes(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen, + jint flush, jint params) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doDeflate(env, this, addr, + input + inputOff, inputLen, + output + outputOff, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0); + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBytesBuffer(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jlong outputBuffer, jint outputLen, + jint flush, jint params) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = jlong_to_ptr(outputBuffer); + + jlong retVal = doDeflate(env, this, addr, + input + inputOff, inputLen, + output, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBufferBytes(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen, + jint flush, jint params) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doDeflate(env, this, addr, + input, inputLen, + output + outputOff, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBufferBuffer(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jlong outputBuffer, jint outputLen, + jint flush, jint params) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = jlong_to_ptr(outputBuffer); + + return doDeflate(env, this, addr, + input, inputLen, + output, outputLen, + flush, params); } JNIEXPORT jint JNICALL diff --git a/src/java.base/share/native/libzip/Inflater.c b/src/java.base/share/native/libzip/Inflater.c index 2e21d084b39..4999b5467a0 100644 --- a/src/java.base/share/native/libzip/Inflater.c +++ b/src/java.base/share/native/libzip/Inflater.c @@ -42,23 +42,13 @@ #define ThrowDataFormatException(env, msg) \ JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg) -static jfieldID needDictID; -static jfieldID finishedID; -static jfieldID bufID, offID, lenID; +static jfieldID inputConsumedID; JNIEXPORT void JNICALL Java_java_util_zip_Inflater_initIDs(JNIEnv *env, jclass cls) { - needDictID = (*env)->GetFieldID(env, cls, "needDict", "Z"); - CHECK_NULL(needDictID); - finishedID = (*env)->GetFieldID(env, cls, "finished", "Z"); - CHECK_NULL(finishedID); - bufID = (*env)->GetFieldID(env, cls, "buf", "[B"); - CHECK_NULL(bufID); - offID = (*env)->GetFieldID(env, cls, "off", "I"); - CHECK_NULL(offID); - lenID = (*env)->GetFieldID(env, cls, "len", "I"); - CHECK_NULL(lenID); + inputConsumedID = (*env)->GetFieldID(env, cls, "inputConsumed", "I"); + CHECK_NULL(inputConsumedID); } JNIEXPORT jlong JNICALL @@ -94,16 +84,9 @@ Java_java_util_zip_Inflater_init(JNIEnv *env, jclass cls, jboolean nowrap) } } -JNIEXPORT void JNICALL -Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, - jarray b, jint off, jint len) +static void doSetDictionary(JNIEnv *env, jlong addr, jbyte *buf, jint len) { - Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - int res; - if (buf == 0) /* out of memory */ - return; - res = inflateSetDictionary(jlong_to_ptr(addr), buf + off, len); - (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); + int res = inflateSetDictionary(jlong_to_ptr(addr), (Bytef *) buf, len); switch (res) { case Z_OK: break; @@ -117,68 +100,155 @@ Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, } } -JNIEXPORT jint JNICALL -Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr, - jarray b, jint off, jint len) +JNIEXPORT void JNICALL +Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, + jbyteArray b, jint off, jint len) +{ + jbyte *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); + if (buf == NULL) /* out of memory */ + return; + doSetDictionary(env, addr, buf + off, len); + (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); +} + +JNIEXPORT void JNICALL +Java_java_util_zip_Inflater_setDictionaryBuffer(JNIEnv *env, jclass cls, jlong addr, + jlong bufferAddr, jint len) +{ + jbyte *buf = jlong_to_ptr(bufferAddr); + doSetDictionary(env, addr, buf, len); +} + +static jlong doInflate(JNIEnv *env, jobject this, jlong addr, + jbyte *input, jint inputLen, + jbyte *output, jint outputLen) { z_stream *strm = jlong_to_ptr(addr); - jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID); - jint this_off = (*env)->GetIntField(env, this, offID); - jint this_len = (*env)->GetIntField(env, this, lenID); + jint inputUsed = 0, outputUsed = 0; - jbyte *in_buf; - jbyte *out_buf; - int ret; + strm->next_in = (Bytef *) input; + strm->next_out = (Bytef *) output; + strm->avail_in = inputLen; + strm->avail_out = outputLen; - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - ret = inflate(strm, Z_PARTIAL_FLUSH); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + int ret = inflate(strm, Z_PARTIAL_FLUSH); + int finished = 0; + int needDict = 0; switch (ret) { case Z_STREAM_END: - (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); + finished = 1; /* fall through */ case Z_OK: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return (jint) (len - strm->avail_out); + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; case Z_NEED_DICT: - (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE); + needDict = 1; /* Might have consumed some input here! */ - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return 0; + inputUsed = inputLen - strm->avail_in; + break; case Z_BUF_ERROR: - return 0; + break; case Z_DATA_ERROR: + inputUsed = inputLen - strm->avail_in; + (*env)->SetIntField(env, this, inputConsumedID, inputUsed); ThrowDataFormatException(env, strm->msg); - return 0; + break; case Z_MEM_ERROR: JNU_ThrowOutOfMemoryError(env, 0); - return 0; + break; default: JNU_ThrowInternalError(env, strm->msg); - return 0; + break; + } + return ((jlong)inputUsed) | (((jlong)outputUsed) << 31) | (((jlong)finished) << 62) | (((jlong)needDict) << 63); +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBytesBytes(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doInflate(env, this, addr, + input + inputOff, inputLen, + output + outputOff, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0); + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBytesBuffer(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jlong outputBuffer, jint outputLen) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = jlong_to_ptr(outputBuffer); + + jlong retVal = doInflate(env, this, addr, + input + inputOff, inputLen, + output, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBufferBytes(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; } + + jlong retVal = doInflate(env, this, addr, + input, inputLen, + output + outputOff, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBufferBuffer(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jlong outputBuffer, jint outputLen) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = jlong_to_ptr(outputBuffer); + + return doInflate(env, this, addr, + input, inputLen, + output, outputLen); } JNIEXPORT jint JNICALL diff --git a/test/jdk/java/util/zip/FlaterTest.java b/test/jdk/java/util/zip/FlaterTest.java index 7245440d033..b5aff0319b3 100644 --- a/test/jdk/java/util/zip/FlaterTest.java +++ b/test/jdk/java/util/zip/FlaterTest.java @@ -29,7 +29,6 @@ * @key randomness */ -import java.io.*; import java.nio.*; import java.util.*; import java.util.zip.*; @@ -41,35 +40,37 @@ import java.util.zip.*; */ public class FlaterTest extends Thread { private static final int DATA_LEN = 1024 * 128; - private static byte[] data; + + private static ByteBuffer dataDirect; + private static ByteBuffer dataHeap; // If true, print extra info. private static final boolean debug = false; // Set of Flater threads running. - private static Set flaters = - Collections.synchronizedSet(new HashSet()); + private static Set flaters = + Collections.synchronizedSet(new HashSet<>()); /** Fill in {@code data} with random values. */ static void createData() { - ByteBuffer bb = ByteBuffer.allocate(8); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - for (int i = 0; i < DATA_LEN; i++) { - bb.putDouble(0, Math.random()); - baos.write(bb.array(), 0, 8); + ByteBuffer bb = ByteBuffer.allocateDirect(DATA_LEN * 8); + for (int i = 0; i < DATA_LEN * 8; i += 8) { + bb.putDouble(i, Math.random()); } - data = baos.toByteArray(); - if (debug) System.out.println("data length is " + data.length); + dataDirect = bb; + final ByteBuffer hb = ByteBuffer.allocate(bb.capacity()); + hb.duplicate().put(bb.duplicate()); + dataHeap = hb; + if (debug) System.out.println("data length is " + bb.capacity()); } /** @return the length of the deflated {@code data}. */ - private static int getDeflatedLength() throws Throwable { - int rc = 0; + private static int getDeflatedLength() { Deflater deflater = new Deflater(); - deflater.setInput(data); + deflater.setInput(dataDirect.duplicate()); deflater.finish(); - byte[] out = new byte[data.length]; - rc = deflater.deflate(out); + byte[] out = new byte[dataDirect.capacity()]; + int rc = deflater.deflate(out); deflater.end(); if (debug) System.out.println("deflatedLength is " + rc); return rc; @@ -78,70 +79,98 @@ public class FlaterTest extends Thread { /** Compares given bytes with those in {@code data}. * @throws Exception if given bytes don't match {@code data}. */ - private static void validate(byte[] buf, int offset, int len) throws Exception { + private static void validate(ByteBuffer buf, int offset, int len) throws Exception { for (int i = 0; i < len; i++ ) { - if (buf[i] != data[offset+i]) { + if (buf.get(i) != dataDirect.get(offset+i)) { throw new Exception("mismatch at " + (offset + i)); } } } - public static void realMain(String[] args) throws Throwable { - createData(); + public static void realMain(String[] args) { int numThreads = args.length > 0 ? Integer.parseInt(args[0]) : 5; - new FlaterTest().go(numThreads); + createData(); + for (int srcMode = 0; srcMode <= 2; srcMode ++) { + for (int dstMode = 0; dstMode <= 2; dstMode ++) { + new FlaterTest().go(numThreads, srcMode, dstMode); + } + } } - private synchronized void go(int numThreads) throws Throwable { + private synchronized void go(int numThreads, int srcMode, int dstMode) { int deflatedLength = getDeflatedLength(); long time = System.currentTimeMillis(); for (int i = 0; i < numThreads; i++) { - Flater f = new Flater(deflatedLength); + Flater f = new Flater(deflatedLength, srcMode, dstMode); flaters.add(f); f.start(); } - while (flaters.size() != 0) { - try { - Thread.currentThread().sleep(10); - } catch (InterruptedException ex) { - unexpected(ex); + synchronized (flaters) { + while (flaters.size() != 0) { + try { + flaters.wait(); + } catch (InterruptedException ex) { + unexpected(ex); + } } } time = System.currentTimeMillis() - time; System.out.println("Time needed for " + numThreads - + " threads to deflate/inflate: " + time + " ms."); + + " threads to deflate/inflate: " + time + " ms (srcMode="+srcMode+",dstMode="+dstMode+")"); } /** Deflates and inflates data. */ static class Flater extends Thread { private final int deflatedLength; + private final int srcMode, dstMode; - private Flater(int length) { + private Flater(int length, int srcMode, int dstMode) { this.deflatedLength = length; + this.srcMode = srcMode; + this.dstMode = dstMode; } /** Deflates and inflates {@code data}. */ public void run() { if (debug) System.out.println(getName() + " starting run()"); try { - byte[] deflated = DeflateData(deflatedLength); + ByteBuffer deflated = DeflateData(deflatedLength); InflateData(deflated); } catch (Throwable t) { t.printStackTrace(); fail(getName() + " failed"); } finally { - flaters.remove(this); + synchronized (flaters) { + flaters.remove(this); + if (flaters.isEmpty()) { + flaters.notifyAll(); + } + } } } /** Returns a copy of {@code data} in deflated form. */ - private byte[] DeflateData(int length) throws Throwable { + private ByteBuffer DeflateData(int length) { Deflater deflater = new Deflater(); - deflater.setInput(data); + if (srcMode == 0) { + deflater.setInput(dataHeap.array()); + } else if (srcMode == 1) { + deflater.setInput(dataHeap.duplicate()); + } else { + assert srcMode == 2; + deflater.setInput(dataDirect.duplicate()); + } deflater.finish(); - byte[] out = new byte[length]; - deflater.deflate(out); + ByteBuffer out = dstMode == 2 ? ByteBuffer.allocateDirect(length) : ByteBuffer.allocate(length); + int deflated; + if (dstMode == 0) { + deflated = deflater.deflate(out.array(), 0, length); + out.position(deflated); + } else { + deflater.deflate(out); + } + out.flip(); return out; } @@ -149,14 +178,30 @@ public class FlaterTest extends Thread { * inflation. * @throws Exception if inflated bytes don't match {@code data}. */ - private void InflateData(byte[] bytes) throws Throwable { + private void InflateData(ByteBuffer bytes) throws Throwable { Inflater inflater = new Inflater(); - inflater.setInput(bytes, 0, bytes.length); + if (dstMode == 0) { + inflater.setInput(bytes.array(), 0, bytes.remaining()); + } else { + inflater.setInput(bytes); + } + if (inflater.getRemaining() == 0) { + throw new Exception("Nothing to inflate (bytes=" + bytes + ")"); + } int len = 1024 * 8; int offset = 0; + ByteBuffer buf = srcMode == 2 ? ByteBuffer.allocateDirect(len) : ByteBuffer.allocate(len); while (inflater.getRemaining() > 0) { - byte[] buf = new byte[len]; - int inflated = inflater.inflate(buf, 0, len); + buf.clear(); + int inflated; + if (srcMode == 0) { + inflated = inflater.inflate(buf.array(), 0, buf.remaining()); + } else { + inflated = inflater.inflate(buf); + } + if (inflated == 0) { + throw new Exception("Nothing inflated (dst=" + buf + ",offset=" + offset + ",rem=" + inflater.getRemaining() + ",srcMode="+srcMode+",dstMode="+dstMode+")"); + } validate(buf, offset, inflated); offset += inflated; } From paul.sandoz at oracle.com Fri Mar 2 16:36:20 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 2 Mar 2018 08:36:20 -0800 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: Message-ID: <2FD5706A-E4B5-40A0-AADC-074C02ED2172@oracle.com> > On Mar 2, 2018, at 8:07 AM, David Lloyd wrote: > > The third... and hopefully final... version of this patch is attached. > It is the same as V2, however it also uses > Reference.reachabilityFence() defensively on buffers. This may be > necessary because there are code paths which may allow such buffers to > be GCed after their address is acquired but before the native code > successfully is able to read it. > > The online version of this patch is visible at [1]. > I have not been tracking this patch closely, but the use of Reference.reachabilityFence looks good to me. Paul. > [1] https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v8 > > -- > - DML > From claes.redestad at oracle.com Fri Mar 2 16:48:55 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 2 Mar 2018 17:48:55 +0100 Subject: RFR 8198697: Simplify platform encoding initialization tweak In-Reply-To: <0ea3699b-e4ab-ceca-e0d7-d41c2ed675f4@Oracle.com> References: <0ea3699b-e4ab-ceca-e0d7-d41c2ed675f4@Oracle.com> Message-ID: Hi, looks good to me, although part of me can't help wonder if we'd profit ever so little from rearranging if statements so that we test for UTF8 first and move the should-be-asserts tests for NO_ENCODING_YET down. /Claes On 2018-02-28 15:45, Roger Riggs wrote: > Hi, > > In an effort to untangle some of the issues with property > initialization I was looking > at the platform encoding initialization and found a simplification. > > Currently, the initialization occurs as a side effect of the first > call to JNU_NewStringPlatform and > involves a upcall to get sun.jnu.encoding from the system properties.? > The value is cached for later use. > > The native System.initProperties determines the platform specific > encoding via java_props_md.c and does an upcall to set the > sun.jnu.encoding system property, taking care to do it before the > first string that needs platform encoding. > > The change directly initializes the platform encoding fast path before > it is needed to encode platform strings. > And moves the setting sun.jnu.encoding system property after the > command line arguments are inserted > keeping it from being overridden by -D on the command line that can > only confuse confusion > with code that later reads the property. > > Please review and comment. > > webrev: > ?? http://cr.openjdk.java.net/~rriggs/webrev-simplify-jnu-8198697/ > > Issue: > ?? https://bugs.openjdk.java.net/browse/JDK-8198697 > > Thanks, Roger > > > > From claes.redestad at oracle.com Fri Mar 2 16:50:39 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 2 Mar 2018 17:50:39 +0100 Subject: RFR: JDK-8198955 - String#repeat loop optimization In-Reply-To: <8D25B693-7199-4F67-B08A-AC3B0A5F686D@oracle.com> References: <8D25B693-7199-4F67-B08A-AC3B0A5F686D@oracle.com> Message-ID: <65bee133-ecf0-f5cc-7f0d-a2edad0e84e4@oracle.com> +1 On 2018-03-02 15:43, Jim Laskey wrote: > Verified to work on edge cases. > > JBS: https://bugs.openjdk.java.net/browse/JDK-8198955 > Webrev: http://cr.openjdk.java.net/~jlaskey/8198955/webrev/index.html From paul.sandoz at oracle.com Fri Mar 2 17:01:41 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 2 Mar 2018 09:01:41 -0800 Subject: [PATCH] Reduce Chance Of Mistakenly Early Backing Memory Cleanup In-Reply-To: References: <7215566D-A8BA-4D51-8262-E70E7FA55982@oracle.com> Message-ID: <135224D1-153F-4544-A06D-A7D799E65F27@oracle.com> Here?s an update Ben and I tweaked: http://cr.openjdk.java.net/~psandoz/jdk/buffer-reachability-fence/webrev/index.html I think this looks good but would still like to double check with Vladimir that the @ForceInline is not problematic. Paul. > On Feb 26, 2018, at 6:50 PM, Paul Sandoz wrote: > > Hi Ben, > > Here is the webrev online: > > http://cr.openjdk.java.net/~psandoz/jdk/buffer-reachability-fence/webrev/index.html > From xueming.shen at oracle.com Fri Mar 2 17:03:01 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 02 Mar 2018 09:03:01 -0800 Subject: RFR 8198697: Simplify platform encoding initialization tweak In-Reply-To: <365a6a3e-1f9f-0ad7-ed82-3fbe0b94aa98@Oracle.com> References: <0ea3699b-e4ab-ceca-e0d7-d41c2ed675f4@Oracle.com> <365a6a3e-1f9f-0ad7-ed82-3fbe0b94aa98@Oracle.com> Message-ID: <5A9983C5.6080702@oracle.com> +1 On 03/02/2018 07:49 AM, Roger Riggs wrote: > Please review... > > On 2/28/2018 9:45 AM, Roger Riggs wrote: >> Hi, >> >> In an effort to untangle some of the issues with property initialization I was looking >> at the platform encoding initialization and found a simplification. >> >> Currently, the initialization occurs as a side effect of the first call to JNU_NewStringPlatform and >> involves a upcall to get sun.jnu.encoding from the system properties. The value is cached for later use. >> >> The native System.initProperties determines the platform specific encoding via java_props_md.c and does an upcall to set the sun.jnu.encoding system property, taking care to do it before the first string that needs platform encoding. >> >> The change directly initializes the platform encoding fast path before it is needed to encode platform strings. >> And moves the setting sun.jnu.encoding system property after the command line arguments are inserted >> keeping it from being overridden by -D on the command line that can only confuse confusion >> with code that later reads the property. >> >> Please review and comment. >> >> webrev: >> http://cr.openjdk.java.net/~rriggs/webrev-simplify-jnu-8198697/ >> >> Issue: >> https://bugs.openjdk.java.net/browse/JDK-8198697 >> >> Thanks, Roger >> >> >> >> > From vladimir.x.ivanov at oracle.com Fri Mar 2 17:11:25 2018 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Fri, 2 Mar 2018 20:11:25 +0300 Subject: [PATCH] Reduce Chance Of Mistakenly Early Backing Memory Cleanup In-Reply-To: <135224D1-153F-4544-A06D-A7D799E65F27@oracle.com> References: <7215566D-A8BA-4D51-8262-E70E7FA55982@oracle.com> <135224D1-153F-4544-A06D-A7D799E65F27@oracle.com> Message-ID: <785979c9-c2a5-29dd-aada-b7926191e132@oracle.com> On 3/2/18 8:01 PM, Paul Sandoz wrote: > Here?s an update Ben and I tweaked: > > http://cr.openjdk.java.net/~psandoz/jdk/buffer-reachability-fence/webrev/index.html > > I think this looks good but would still like to double check with Vladimir that the @ForceInline is not problematic. I confirm that my previous analysis [1] still applies when method is marked w/ @ForceInline. Best regards, Vladimir Ivanov [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051312.html >> On Feb 26, 2018, at 6:50 PM, Paul Sandoz wrote: >> >> Hi Ben, >> >> Here is the webrev online: >> >> http://cr.openjdk.java.net/~psandoz/jdk/buffer-reachability-fence/webrev/index.html >> > > From paul.sandoz at oracle.com Fri Mar 2 17:15:40 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 2 Mar 2018 09:15:40 -0800 Subject: [PATCH] Reduce Chance Of Mistakenly Early Backing Memory Cleanup In-Reply-To: <785979c9-c2a5-29dd-aada-b7926191e132@oracle.com> References: <7215566D-A8BA-4D51-8262-E70E7FA55982@oracle.com> <135224D1-153F-4544-A06D-A7D799E65F27@oracle.com> <785979c9-c2a5-29dd-aada-b7926191e132@oracle.com> Message-ID: Thanks! Paul. > On Mar 2, 2018, at 9:11 AM, Vladimir Ivanov wrote: > > > > On 3/2/18 8:01 PM, Paul Sandoz wrote: >> Here?s an update Ben and I tweaked: >> http://cr.openjdk.java.net/~psandoz/jdk/buffer-reachability-fence/webrev/index.html >> I think this looks good but would still like to double check with Vladimir that the @ForceInline is not problematic. > > I confirm that my previous analysis [1] still applies when method is marked w/ @ForceInline. > > Best regards, > Vladimir Ivanov > > [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051312.html > >>> On Feb 26, 2018, at 6:50 PM, Paul Sandoz wrote: >>> >>> Hi Ben, >>> >>> Here is the webrev online: >>> >>> http://cr.openjdk.java.net/~psandoz/jdk/buffer-reachability-fence/webrev/index.html >>> From martinrb at google.com Fri Mar 2 17:29:52 2018 From: martinrb at google.com (Martin Buchholz) Date: Fri, 2 Mar 2018 09:29:52 -0800 Subject: RFR: Here are some URLClassPath patches In-Reply-To: References: <912a66bb-45d3-0248-7f8e-b43da9b33ff9@oracle.com> <684a8186-6d29-1e52-34cd-3ceb13b2ff4f@oracle.com> <90892fc9-31f0-1da8-46f9-56c91865cb99@oracle.com> Message-ID: Thanks! Delivered without further changes. That should be the end of this batch of classloader changes. On Fri, Mar 2, 2018 at 7:00 AM, Roger Riggs wrote: > Hi Martin, > > I created the subtask for the release note[1], please review and update > the summary and description. > When it is done, close it as 'delivered'. > > Thanks, Roger > > [1] https://bugs.openjdk.java.net/browse/JDK-8198956 > > > > On 3/1/2018 10:32 PM, Martin Buchholz wrote: > >> On Wed, Feb 28, 2018 at 3:58 PM, Martin Buchholz >> wrote: >> >> >>> 8198810: URLClassLoader does not specify behavior when URL array contains >>> null >>> http://cr.openjdk.java.net/~martin/webrevs/jdk/URLClassLoader-NPE/ >>> https://bugs.openjdk.java.net/browse/JDK-8198810 >>> >>> Pushed. Can someone at Oracle help with the release note? >> > > From xueming.shen at oracle.com Fri Mar 2 18:49:19 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 02 Mar 2018 10:49:19 -0800 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: Message-ID: <5A999CAF.3030905@oracle.com> Hi David, (1) Deflater.deflate(Bytebuffer) the api doc regarding "no_flush" appears to be the copy/paste of the byte[] version without being updated to the corresponding ByteBuffer? (2) Inflater.inflate() a "inputConsumed" field is added to handle the "bytes-read" if a DFE is being thrown. While the API doc specifies that "if the setInput(bytebuffer) method was call ...." it appears the inputPos/bytesRead are being updated for the "setInput(byte[]) case as well. This might be a desirable change, but is an "incompatible" behavior change as well. I doubt if there is any existing app depending on this existing behavior though, it's really hard, if not impossible, to try to recover from this kind of error There might also bring in a little inconsistency, as we are updating the "input" in this case, but why not the "output" buffer? It's true there is no way to do that with the inflate(byte[] ...), it's kinda doable for the inflate(ByteBuffer) and in fact there might be bytes that have been written into the output ByteBuffer in this case. (3) there are usages like Math.max(buf.limit() - outputPos, 0); just wonder if there is any reason not using existing api method. Math.max(buf.remaining(), 0); sherman On 03/02/2018 08:07 AM, David Lloyd wrote: > The third... and hopefully final... version of this patch is attached. > It is the same as V2, however it also uses > Reference.reachabilityFence() defensively on buffers. This may be > necessary because there are code paths which may allow such buffers to > be GCed after their address is acquired but before the native code > successfully is able to read it. > > The online version of this patch is visible at [1]. > > [1] https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v8 > From Roger.Riggs at Oracle.com Fri Mar 2 19:21:30 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 2 Mar 2018 14:21:30 -0500 Subject: RFR 8198697: Simplify platform encoding initialization tweak In-Reply-To: <5A9983C5.6080702@oracle.com> References: <0ea3699b-e4ab-ceca-e0d7-d41c2ed675f4@Oracle.com> <365a6a3e-1f9f-0ad7-ed82-3fbe0b94aa98@Oracle.com> <5A9983C5.6080702@oracle.com> Message-ID: Hi Claes, Sherman, Thanks for the reviews: I reordered as the suggested the checks for encoding type to put utf-8, most common first in JNU_NewStringPlatform() and JNU_GetStringPlatformChars(). Webrev updated in place: ? http://cr.openjdk.java.net/~rriggs/webrev-simplify-jnu-8198697/ Thanks, Roger On 3/2/2018 12:03 PM, Xueming Shen wrote: > +1 > > On 03/02/2018 07:49 AM, Roger Riggs wrote: >> Please review... >> >> On 2/28/2018 9:45 AM, Roger Riggs wrote: >>> Hi, >>> >>> In an effort to untangle some of the issues with property >>> initialization I was looking >>> at the platform encoding initialization and found a simplification. >>> >>> Currently, the initialization occurs as a side effect of the first >>> call to JNU_NewStringPlatform and >>> involves a upcall to get sun.jnu.encoding from the system >>> properties.? The value is cached for later use. >>> >>> The native System.initProperties determines the platform specific >>> encoding via java_props_md.c and does an upcall to set the >>> sun.jnu.encoding system property, taking care to do it before the >>> first string that needs platform encoding. >>> >>> The change directly initializes the platform encoding fast path >>> before it is needed to encode platform strings. >>> And moves the setting sun.jnu.encoding system property after the >>> command line arguments are inserted >>> keeping it from being overridden by -D on the command line that can >>> only confuse confusion >>> with code that later reads the property. >>> >>> Please review and comment. >>> >>> webrev: >>> http://cr.openjdk.java.net/~rriggs/webrev-simplify-jnu-8198697/ >>> >>> Issue: >>> ?? https://bugs.openjdk.java.net/browse/JDK-8198697 >>> >>> Thanks, Roger >>> >>> >>> >>> >> > From xueming.shen at oracle.com Fri Mar 2 20:02:16 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 02 Mar 2018 12:02:16 -0800 Subject: RFR JDK-8187653: Lock in CoderResult.Cache becomes performance bottleneck In-Reply-To: References: <5A90BF44.3030005@oracle.com> <1467288f-e4a6-6160-a566-ef1045d8fd84@oracle.com> <5A98B259.3060600@oracle.com> Message-ID: <5A99ADC8.2060206@oracle.com> To follow Claes's suggestion to make the CoderResult.Cache.cache field final and allocate early. issue: https://bugs.openjdk.java.net/browse/JDK-8198966 webrev: http://cr.openjdk.java.net/~sherman/8198966/webrev/ Thanks, -Sherman From ivan.gerasimov at oracle.com Fri Mar 2 20:34:13 2018 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Fri, 2 Mar 2018 12:34:13 -0800 Subject: RFR: JDK-8198955 - String#repeat loop optimization In-Reply-To: <8D25B693-7199-4F67-B08A-AC3B0A5F686D@oracle.com> References: <8D25B693-7199-4F67-B08A-AC3B0A5F686D@oracle.com> Message-ID: This looks good, thank you! On 3/2/18 6:43 AM, Jim Laskey wrote: > Verified to work on edge cases. > > JBS: https://bugs.openjdk.java.net/browse/JDK-8198955 > Webrev: http://cr.openjdk.java.net/~jlaskey/8198955/webrev/index.html -- With kind regards, Ivan Gerasimov From david.lloyd at redhat.com Fri Mar 2 20:34:02 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Fri, 2 Mar 2018 14:34:02 -0600 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: <5A999CAF.3030905@oracle.com> References: <5A999CAF.3030905@oracle.com> Message-ID: On Fri, Mar 2, 2018 at 12:49 PM, Xueming Shen wrote: > Hi David, > > (1) Deflater.deflate(Bytebuffer) > the api doc regarding "no_flush" appears to be the copy/paste of the > byte[] version > without being updated to the corresponding ByteBuffer? You're right, I missed that one. I've incorporated this fix locally: --- 8< --- cut here --- 8< --- diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java b/src/java.base/share/classes/java/util/zip/Deflater.java index 524125787a8..9cf735a9477 100644 --- a/src/java.base/share/classes/java/util/zip/Deflater.java +++ b/src/java.base/share/classes/java/util/zip/Deflater.java @@ -483,7 +483,7 @@ public class Deflater { *

This method uses {@link #NO_FLUSH} as its compression flush mode. * An invocation of this method of the form {@code deflater.deflate(b)} * yields the same result as the invocation of - * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. + * {@code deflater.deflate(output, Deflater.NO_FLUSH)}. * * @param output the buffer for the compressed data * @return the actual number of bytes of compressed data written to the --- 8< --- cut here --- 8< --- I'll post an amended patch once we work out the other points below (and any other feedback that comes in the meantime). > (2) Inflater.inflate() > a "inputConsumed" field is added to handle the "bytes-read" if a DFE is > being thrown. > > While the API doc specifies that "if the setInput(bytebuffer) method > was call ...." > it appears the inputPos/bytesRead are being updated for the > "setInput(byte[]) case > as well. This might be a desirable change, but is an "incompatible" > behavior change > as well. I doubt if there is any existing app depending on this > existing behavior though, > it's really hard, if not impossible, to try to recover from this kind > of error I agree; this was implemented based on Alan's points but I could go either way with it. I had a thought that I could update the position only in the buffer input case, not the array input case, but this would still have the effect of changing the behavior of Inflater.getRemaining() when the input is a buffer, which is still technically an incompatibility. So the three options are: * Always update the input position on exception * Only update the input position on exception when the input is a ByteBuffer * Never update the input position on exception AFAICT there are no inherent technical issues with any of these approaches beyond the obscure compatibility change. Since the behavior was previously unspecified, I think that decreases the compatibility risk even further, so I'm inclined to think that #1 is the best overall choice. > There might also bring in a little inconsistency, as we are updating > the "input" in this > case, but why not the "output" buffer? It's true there is no way to do > that with the > inflate(byte[] ...), it's kinda doable for the inflate(ByteBuffer) and > in fact there might > be bytes that have been written into the output ByteBuffer in this > case. Since there is no way to get the output bytes consumed in the array case, this is not an incompatible change, so I am happy to include it in my next revision. However I think it only makes sense to do this if it is consistent with input; i.e. if option #3 above is chosen then it would be inconsistent to update the output position on exception and we should not do it. > (3) there are usages like > Math.max(buf.limit() - outputPos, 0); > just wonder if there is any reason not using existing api method. > Math.max(buf.remaining(), 0); This is because the buffer's position can change between the call to buf.position() and buf.remaining(), which can have the ultimate effect of allowing invalid memory accesses. By acquiring the position and limit each one time, I can guarantee some consistent view of these properties. This is consistent with (for example) sun.nio.ch.IOUtil. Also just as a general principle, buf.remaining() reads both the limit and position, and since I already have the position, it makes sense to just read the limit which is the only other piece of data that must be read in order to correctly calculate these values. Thanks for the feedback. -- - DML From david.lloyd at redhat.com Fri Mar 2 20:36:19 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Fri, 2 Mar 2018 14:36:19 -0600 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: <5A999CAF.3030905@oracle.com> Message-ID: On Fri, Mar 2, 2018 at 2:34 PM, David Lloyd wrote: > On Fri, Mar 2, 2018 at 12:49 PM, Xueming Shen wrote: >> Hi David, >> >> (1) Deflater.deflate(Bytebuffer) >> the api doc regarding "no_flush" appears to be the copy/paste of the >> byte[] version >> without being updated to the corresponding ByteBuffer? > > You're right, I missed that one. I've incorporated this fix locally: Oops, this should have been: --- 8< --- cut here --- 8< --- diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java b/src/java.base/share/classes/java/util/zip/Deflater.java index 524125787a8..40f0d9736e2 100644 --- a/src/java.base/share/classes/java/util/zip/Deflater.java +++ b/src/java.base/share/classes/java/util/zip/Deflater.java @@ -481,9 +481,9 @@ public class Deflater { * in order to determine if more input data is required. * *

This method uses {@link #NO_FLUSH} as its compression flush mode. - * An invocation of this method of the form {@code deflater.deflate(b)} + * An invocation of this method of the form {@code deflater.deflate(output)} * yields the same result as the invocation of - * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. + * {@code deflater.deflate(output, Deflater.NO_FLUSH)}. * * @param output the buffer for the compressed data * @return the actual number of bytes of compressed data written to the --- 8< --- cut here --- 8< --- -- - DML From claes.redestad at oracle.com Fri Mar 2 22:52:59 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 2 Mar 2018 23:52:59 +0100 Subject: RFR JDK-8187653: Lock in CoderResult.Cache becomes performance bottleneck In-Reply-To: <5A99ADC8.2060206@oracle.com> References: <5A90BF44.3030005@oracle.com> <1467288f-e4a6-6160-a566-ef1045d8fd84@oracle.com> <5A98B259.3060600@oracle.com> <5A99ADC8.2060206@oracle.com> Message-ID: <031a5636-40e4-76f7-f96d-7025f2222686@oracle.com> One less (benign) race - and possibly more efficient, too :-) If we really worry about the startup costs here, we could make it so that the three Cache classes themselves aren't loaded until someone actually has a need for them: http://cr.openjdk.java.net/~redestad/scratch/coderresult_cache.00/ /Claes On 2018-03-02 21:02, Xueming Shen wrote: > > To follow Claes's suggestion to make the CoderResult.Cache.cache field > final and allocate early. > > issue: https://bugs.openjdk.java.net/browse/JDK-8198966 > webrev: http://cr.openjdk.java.net/~sherman/8198966/webrev/ > > Thanks, > -Sherman From Roger.Riggs at Oracle.com Fri Mar 2 22:56:47 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 2 Mar 2018 17:56:47 -0500 Subject: RFR 8198970: jnu_util.c compilation error on Solaris Message-ID: <6d9caae8-9eac-73f0-b6c1-faa648d1a9d4@Oracle.com> Please review a correction to the jni_util.c native code that does not compile on Solaris. Declarations must precede assignments. Issue: 8198970 jnu_util.c compilation error on Solaris diff --git a/src/java.base/share/native/libjava/jni_util.c b/src/java.base/share/native/libjava/jni_util.c --- a/src/java.base/share/native/libjava/jni_util.c +++ b/src/java.base/share/native/libjava/jni_util.c @@ -803,10 +803,10 @@ InitializeEncoding(JNIEnv *env, const ch ???????????? (strcmp(encname, "ISO-8859-1") == 0)) { ???????????? fastEncoding = FAST_8859_1; ???????? } else if (strcmp(encname, "UTF-8") == 0) { -??????????? fastEncoding = FAST_UTF_8; ???????????? jstring enc = (*env)->NewStringUTF(env, encname); ???????????? if (enc == NULL) ???????????????? return; +??????????? fastEncoding = FAST_UTF_8; ???????????? jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); ???????????? (*env)->DeleteLocalRef(env, enc); ???????? } else if (strcmp(encname, "ISO646-US") == 0) { @@ -818,10 +818,10 @@ InitializeEncoding(JNIEnv *env, const ch ???????????? strcmp(encname, "utf-16le") == 0) { ???????????? fastEncoding = FAST_CP1252; ???????? } else { -??????????? fastEncoding = NO_FAST_ENCODING; ???????????? jstring enc = (*env)->NewStringUTF(env, encname); ???????????? if (enc == NULL) ???????????????? return; +??????????? fastEncoding = NO_FAST_ENCODING; ???????????? jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); ???????????? (*env)->DeleteLocalRef(env, enc); ???????? } Thanks, Roger From claes.redestad at oracle.com Fri Mar 2 22:59:05 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 2 Mar 2018 23:59:05 +0100 Subject: RFR 8198697: Simplify platform encoding initialization tweak In-Reply-To: References: <0ea3699b-e4ab-ceca-e0d7-d41c2ed675f4@Oracle.com> <365a6a3e-1f9f-0ad7-ed82-3fbe0b94aa98@Oracle.com> <5A9983C5.6080702@oracle.com> Message-ID: On 2018-03-02 20:21, Roger Riggs wrote: > I reordered as the suggested the checks for encoding type to put > utf-8, most common first > in JNU_NewStringPlatform() and JNU_GetStringPlatformChars(). > > Webrev updated in place: > http://cr.openjdk.java.net/~rriggs/webrev-simplify-jnu-8198697/ Thanks, looks good to me! /Claes From mandy.chung at oracle.com Fri Mar 2 23:02:51 2018 From: mandy.chung at oracle.com (mandy chung) Date: Fri, 2 Mar 2018 15:02:51 -0800 Subject: RFR 8198970: jnu_util.c compilation error on Solaris In-Reply-To: <6d9caae8-9eac-73f0-b6c1-faa648d1a9d4@Oracle.com> References: <6d9caae8-9eac-73f0-b6c1-faa648d1a9d4@Oracle.com> Message-ID: +1 Mandy On 3/2/18 2:56 PM, Roger Riggs wrote: > Please review a correction to the jni_util.c native code that does not > compile on Solaris. > Declarations must precede assignments. > > Issue: 8198970 jnu_util.c compilation error on Solaris > > > diff --git a/src/java.base/share/native/libjava/jni_util.c > b/src/java.base/share/native/libjava/jni_util.c > --- a/src/java.base/share/native/libjava/jni_util.c > +++ b/src/java.base/share/native/libjava/jni_util.c > @@ -803,10 +803,10 @@ InitializeEncoding(JNIEnv *env, const ch > ???????????? (strcmp(encname, "ISO-8859-1") == 0)) { > ???????????? fastEncoding = FAST_8859_1; > ???????? } else if (strcmp(encname, "UTF-8") == 0) { > -??????????? fastEncoding = FAST_UTF_8; > ???????????? jstring enc = (*env)->NewStringUTF(env, encname); > ???????????? if (enc == NULL) > ???????????????? return; > +??????????? fastEncoding = FAST_UTF_8; > ???????????? jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); > ???????????? (*env)->DeleteLocalRef(env, enc); > ???????? } else if (strcmp(encname, "ISO646-US") == 0) { > @@ -818,10 +818,10 @@ InitializeEncoding(JNIEnv *env, const ch > ???????????? strcmp(encname, "utf-16le") == 0) { > ???????????? fastEncoding = FAST_CP1252; > ???????? } else { > -??????????? fastEncoding = NO_FAST_ENCODING; > ???????????? jstring enc = (*env)->NewStringUTF(env, encname); > ???????????? if (enc == NULL) > ???????????????? return; > +??????????? fastEncoding = NO_FAST_ENCODING; > ???????????? jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); > ???????????? (*env)->DeleteLocalRef(env, enc); > ???????? } > > > Thanks, Roger > > From claes.redestad at oracle.com Fri Mar 2 23:02:19 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Sat, 3 Mar 2018 00:02:19 +0100 Subject: RFR 8198970: jnu_util.c compilation error on Solaris In-Reply-To: <6d9caae8-9eac-73f0-b6c1-faa648d1a9d4@Oracle.com> References: <6d9caae8-9eac-73f0-b6c1-faa648d1a9d4@Oracle.com> Message-ID: Looks ok to me. /Claes On 2018-03-02 23:56, Roger Riggs wrote: > Please review a correction to the jni_util.c native code that does not > compile on Solaris. > Declarations must precede assignments. > > Issue: 8198970 jnu_util.c compilation error on Solaris > > > diff --git a/src/java.base/share/native/libjava/jni_util.c > b/src/java.base/share/native/libjava/jni_util.c > --- a/src/java.base/share/native/libjava/jni_util.c > +++ b/src/java.base/share/native/libjava/jni_util.c > @@ -803,10 +803,10 @@ InitializeEncoding(JNIEnv *env, const ch > ???????????? (strcmp(encname, "ISO-8859-1") == 0)) { > ???????????? fastEncoding = FAST_8859_1; > ???????? } else if (strcmp(encname, "UTF-8") == 0) { > -??????????? fastEncoding = FAST_UTF_8; > ???????????? jstring enc = (*env)->NewStringUTF(env, encname); > ???????????? if (enc == NULL) > ???????????????? return; > +??????????? fastEncoding = FAST_UTF_8; > ???????????? jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); > ???????????? (*env)->DeleteLocalRef(env, enc); > ???????? } else if (strcmp(encname, "ISO646-US") == 0) { > @@ -818,10 +818,10 @@ InitializeEncoding(JNIEnv *env, const ch > ???????????? strcmp(encname, "utf-16le") == 0) { > ???????????? fastEncoding = FAST_CP1252; > ???????? } else { > -??????????? fastEncoding = NO_FAST_ENCODING; > ???????????? jstring enc = (*env)->NewStringUTF(env, encname); > ???????????? if (enc == NULL) > ???????????????? return; > +??????????? fastEncoding = NO_FAST_ENCODING; > ???????????? jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); > ???????????? (*env)->DeleteLocalRef(env, enc); > ???????? } > > > Thanks, Roger > > From Roger.Riggs at Oracle.com Fri Mar 2 23:10:54 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 2 Mar 2018 18:10:54 -0500 Subject: RFR 8198970: jnu_util.c compilation error on Solaris In-Reply-To: References: <6d9caae8-9eac-73f0-b6c1-faa648d1a9d4@Oracle.com> Message-ID: <3d555836-1061-01e1-616b-29e0ad61020d@Oracle.com> Thanks, Mandy, Claes, On 3/2/2018 6:02 PM, mandy chung wrote: > +1 > > Mandy > > On 3/2/18 2:56 PM, Roger Riggs wrote: >> Please review a correction to the jni_util.c native code that does >> not compile on Solaris. >> Declarations must precede assignments. >> >> Issue: 8198970 jnu_util.c compilation error on Solaris >> >> >> diff --git a/src/java.base/share/native/libjava/jni_util.c >> b/src/java.base/share/native/libjava/jni_util.c >> --- a/src/java.base/share/native/libjava/jni_util.c >> +++ b/src/java.base/share/native/libjava/jni_util.c >> @@ -803,10 +803,10 @@ InitializeEncoding(JNIEnv *env, const ch >> ???????????? (strcmp(encname, "ISO-8859-1") == 0)) { >> ???????????? fastEncoding = FAST_8859_1; >> ???????? } else if (strcmp(encname, "UTF-8") == 0) { >> -??????????? fastEncoding = FAST_UTF_8; >> ???????????? jstring enc = (*env)->NewStringUTF(env, encname); >> ???????????? if (enc == NULL) >> ???????????????? return; >> +??????????? fastEncoding = FAST_UTF_8; >> ???????????? jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); >> ???????????? (*env)->DeleteLocalRef(env, enc); >> ???????? } else if (strcmp(encname, "ISO646-US") == 0) { >> @@ -818,10 +818,10 @@ InitializeEncoding(JNIEnv *env, const ch >> ???????????? strcmp(encname, "utf-16le") == 0) { >> ???????????? fastEncoding = FAST_CP1252; >> ???????? } else { >> -??????????? fastEncoding = NO_FAST_ENCODING; >> ???????????? jstring enc = (*env)->NewStringUTF(env, encname); >> ???????????? if (enc == NULL) >> ???????????????? return; >> +??????????? fastEncoding = NO_FAST_ENCODING; >> ???????????? jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); >> ???????????? (*env)->DeleteLocalRef(env, enc); >> ???????? } >> >> >> Thanks, Roger >> >> > From naoto.sato at oracle.com Fri Mar 2 23:37:02 2018 From: naoto.sato at oracle.com (naoto.sato at oracle.com) Date: Fri, 2 Mar 2018 15:37:02 -0800 Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method In-Reply-To: References: Message-ID: <0747b8ff-ff27-8406-f05f-042ae070ce0f@oracle.com> Thanks for comments, Martin, Roger. Updated the fix as follows: http://cr.openjdk.java.net/~naoto/4993841/webrev.04/ Naoto On 3/1/18 6:47 PM, naoto.sato at oracle.com wrote: > Hi, > > Please review the fix to the following issue: > > https://bugs.openjdk.java.net/browse/JDK-4993841 > > The proposed changeset is located at: > > http://cr.openjdk.java.net/~naoto/4993841/webrev.03/ > > This stems from the recent discussion regarding String.repeat().[1] The > corresponding CSR has already been approved. > > Naoto > > -- > [1] > http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051568.html > From poweruserm at live.com.au Sat Mar 3 00:24:32 2018 From: poweruserm at live.com.au (A Z) Date: Sat, 3 Mar 2018 00:24:32 +0000 Subject: Floating Point and Arithmetic Changes for Java SE Lnguage Message-ID: I have found that double and float types in java are heirs to arithmetic underflow and overflow at any use. I have found that presently, floating point is an arithmetic approximation. My problem is that the java language needs to be changed here, so that one may have arithmetic accuracy with floats and doubles. There is also a trigonometric shortfall when it comes to BigDecimal. I have attempted to, and have more carefully described these problems, via the java bugs database: JDK-8190947 JDK-8197995 JDK-8190991 JDK-8190946 -These types, as things are, must be computationally discarded, used only in terms of push and pull, and be programmed around using BigDecimal, which will be a waste of memory, program execution speed, and a total confusion due to the lack of any operator usage options on BigDecimals. -It is the case that set, get methods, constructors and mutability methods are all based around float and double, not BigDecimal, which is part of the previous problem. -It is the case that setting up BigDecimals can be and is a circumstantial waste of memory with very many tasks, combined with the fact that the fact that having to use BigDecimal method calls is nowhere near as efficient or legible to developers or mathematics and enginner programmers (and useful with their time) as +, -, *, /, %, +=,-+,*=,/=,%=, ++, -- .This is a syntax argument largely, but also an instruction argument since BigDecimals have to be set up or used with an extra, thereby second, call. -It is the case that every other major language includes both floating point and accuracy mode options with these two types and or Objects, either as a source code instruction or as a compiler switch option. These languages at least provide both options for floating point and mathematical accuracy mode. -It is so that the present arithmetic underflow and underflow are total disadvantages, that need only be changed in place, for preconditions and postconditions. This is in regard to programs that have been compiled and built already. -It is also the case that the state of Java floating point for the last 10 years or so is not really any argument, given that things can be changed in place remaining reverse compatible, along with how clear and necessary the problem is. -My Oracle Support technical reviews seem not to recognise these real problems whatsoever, or only interpret matters in terms of the Java Language Specification on these issues, which of itself possesses inadequecies in these places. Can someone please reply to me on these things? Can Oracle update the Java SE language? From forax at univ-mlv.fr Sat Mar 3 00:42:19 2018 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 3 Mar 2018 01:42:19 +0100 (CET) Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method In-Reply-To: References: Message-ID: <206013518.1922002.1520037739819.JavaMail.zimbra@u-pem.fr> Just to be sure, it now means that a code like this will work String s = "hello".chars() .mapToObj(Character::toString) .collect(Collectors.joining()); R?mi ----- Mail original ----- > De: "naoto sato" > ?: "Stuart Marks" , "Xueming Shen" , "core-libs-dev" > > Envoy?: Vendredi 2 Mars 2018 03:47:51 > Objet: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method > Hi, > > Please review the fix to the following issue: > > https://bugs.openjdk.java.net/browse/JDK-4993841 > > The proposed changeset is located at: > > http://cr.openjdk.java.net/~naoto/4993841/webrev.03/ > > This stems from the recent discussion regarding String.repeat().[1] The > corresponding CSR has already been approved. > > Naoto > > -- > [1] > http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051568.html From naoto.sato at oracle.com Sat Mar 3 00:50:25 2018 From: naoto.sato at oracle.com (Naoto Sato) Date: Fri, 2 Mar 2018 16:50:25 -0800 Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method In-Reply-To: <206013518.1922002.1520037739819.JavaMail.zimbra@u-pem.fr> References: <206013518.1922002.1520037739819.JavaMail.zimbra@u-pem.fr> Message-ID: Yes. With a private build: jshell> "hello".chars().mapToObj(Character::toString).collect(Collectors.joining()) $1 ==> "hello" Naoto On 03/02/2018 04:42 PM, Remi Forax wrote: > Just to be sure, it now means that a code like this will work > > String s = "hello".chars() > .mapToObj(Character::toString) > .collect(Collectors.joining()); > > R?mi > > ----- Mail original ----- >> De: "naoto sato" >> ?: "Stuart Marks" , "Xueming Shen" , "core-libs-dev" >> >> Envoy?: Vendredi 2 Mars 2018 03:47:51 >> Objet: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method > >> Hi, >> >> Please review the fix to the following issue: >> >> https://bugs.openjdk.java.net/browse/JDK-4993841 >> >> The proposed changeset is located at: >> >> http://cr.openjdk.java.net/~naoto/4993841/webrev.03/ >> >> This stems from the recent discussion regarding String.repeat().[1] The >> corresponding CSR has already been approved. >> >> Naoto >> >> -- >> [1] >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051568.html From xueming.shen at oracle.com Sat Mar 3 00:54:56 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 02 Mar 2018 16:54:56 -0800 Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method In-Reply-To: <0747b8ff-ff27-8406-f05f-042ae070ce0f@oracle.com> References: <0747b8ff-ff27-8406-f05f-042ae070ce0f@oracle.com> Message-ID: <5A99F260.1070607@oracle.com> +1 On 3/2/18, 3:37 PM, naoto.sato at oracle.com wrote: > Thanks for comments, Martin, Roger. Updated the fix as follows: > > http://cr.openjdk.java.net/~naoto/4993841/webrev.04/ > > Naoto > > On 3/1/18 6:47 PM, naoto.sato at oracle.com wrote: >> Hi, >> >> Please review the fix to the following issue: >> >> https://bugs.openjdk.java.net/browse/JDK-4993841 >> >> The proposed changeset is located at: >> >> http://cr.openjdk.java.net/~naoto/4993841/webrev.03/ >> >> This stems from the recent discussion regarding String.repeat().[1] >> The corresponding CSR has already been approved. >> >> Naoto >> >> -- >> [1] >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051568.html >> From jbluettduncan at gmail.com Sat Mar 3 01:19:50 2018 From: jbluettduncan at gmail.com (Jonathan Bluett-Duncan) Date: Sat, 3 Mar 2018 01:19:50 +0000 Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method In-Reply-To: <206013518.1922002.1520037739819.JavaMail.zimbra@u-pem.fr> References: <206013518.1922002.1520037739819.JavaMail.zimbra@u-pem.fr> Message-ID: Hi R?mi, I'm sure I've misunderstood something, but AFAIK the code example you gave is already valid code and was valid as far back as Java 8 (I don't have an IDE at hand to confirm this). Did you perhaps mean to ask instead that the code snippet below would work with the resolution of https://bugs.openjdk.java.net/browse/JDK-4993841 (difference being that it uses .codePoints() instead of .chars())? Or have I completely lost the plot? String s = "hello".codePoints() .mapToObj(Character::toString) .collect(Collectors.joining()); Cheers, Jonathan On 3 March 2018 at 00:42, Remi Forax wrote: > Just to be sure, it now means that a code like this will work > > String s = "hello".chars() > .mapToObj(Character::toString) > .collect(Collectors.joining()); > > R?mi > > ----- Mail original ----- > > De: "naoto sato" > > ?: "Stuart Marks" , "Xueming Shen" < > xueming.shen at gmail.com>, "core-libs-dev" > > > > Envoy?: Vendredi 2 Mars 2018 03:47:51 > > Objet: [11] RFR: 4993841: (str) java.lang.Character should have a > toString(int) method > > > Hi, > > > > Please review the fix to the following issue: > > > > https://bugs.openjdk.java.net/browse/JDK-4993841 > > > > The proposed changeset is located at: > > > > http://cr.openjdk.java.net/~naoto/4993841/webrev.03/ > > > > This stems from the recent discussion regarding String.repeat().[1] The > > corresponding CSR has already been approved. > > > > Naoto > > > > -- > > [1] > > http://mail.openjdk.java.net/pipermail/core-libs-dev/2018- > February/051568.html > From stuart.marks at oracle.com Sat Mar 3 01:30:01 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Fri, 2 Mar 2018 17:30:01 -0800 Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method In-Reply-To: <206013518.1922002.1520037739819.JavaMail.zimbra@u-pem.fr> References: <206013518.1922002.1520037739819.JavaMail.zimbra@u-pem.fr> Message-ID: <32f7f3fa-1b8f-f92b-e4ae-ce091c950825@oracle.com> On 3/2/18 4:42 PM, Remi Forax wrote: > Just to be sure, it now means that a code like this will work > > String s = "hello".chars() > .mapToObj(Character::toString) > .collect(Collectors.joining()); Yes, this will work, as Naoto mentioned, but I don't recommend it -- this will split up surrogate pairs. Simplying joining them back together will work in this case, but if any intermediate processing is done, it could be lossy. I think the more important case is something like this: String s = "hello\ud83d\ude1d".codePoints() .mapToObj(Character::toString) .collect(joining()); Previously, you had to do something like String s = "hello\ud83d\ude1d".codePoints() .mapToObj(cp -> new String(Character.toChars(cp))) .collect(joining()); which is a mouthful and which also creates an extra array. s'marks > > R?mi > > ----- Mail original ----- >> De: "naoto sato" >> ?: "Stuart Marks" , "Xueming Shen" , "core-libs-dev" >> >> Envoy?: Vendredi 2 Mars 2018 03:47:51 >> Objet: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method > >> Hi, >> >> Please review the fix to the following issue: >> >> https://bugs.openjdk.java.net/browse/JDK-4993841 >> >> The proposed changeset is located at: >> >> http://cr.openjdk.java.net/~naoto/4993841/webrev.03/ >> >> This stems from the recent discussion regarding String.repeat().[1] The >> corresponding CSR has already been approved. >> >> Naoto >> >> -- >> [1] >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051568.html From stuart.marks at oracle.com Sat Mar 3 01:50:40 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Fri, 2 Mar 2018 17:50:40 -0800 Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method In-Reply-To: <0747b8ff-ff27-8406-f05f-042ae070ce0f@oracle.com> References: <0747b8ff-ff27-8406-f05f-042ae070ce0f@oracle.com> Message-ID: <7c774842-df5a-d0c7-8421-c9ec8f8328cb@oracle.com> Looks good. I note that other codepoint-consuming methods, such as Character.UnicodeBlock.of(cp) Character.UnicodeScript.of(cp) Character.toChars(cp, char[], int) Character.toChars(cp) Character.getName(cp) all throw IAE with no message. It would be nice to add messages to them. It would be even nicer to print out the offending value, possibly even in hex. Indeed, there are several other places in Character.java where exceptions are thrown that lack diagnostic information. Maybe as part of a separate cleanup pass? s'marks On 3/2/18 3:37 PM, naoto.sato at oracle.com wrote: > Thanks for comments, Martin, Roger. Updated the fix as follows: > > http://cr.openjdk.java.net/~naoto/4993841/webrev.04/ > > Naoto > > On 3/1/18 6:47 PM, naoto.sato at oracle.com wrote: >> Hi, >> >> Please review the fix to the following issue: >> >> https://bugs.openjdk.java.net/browse/JDK-4993841 >> >> The proposed changeset is located at: >> >> http://cr.openjdk.java.net/~naoto/4993841/webrev.03/ >> >> This stems from the recent discussion regarding String.repeat().[1] The >> corresponding CSR has already been approved. >> >> Naoto >> >> -- >> [1] >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051568.html From martinrb at google.com Sat Mar 3 01:52:40 2018 From: martinrb at google.com (Martin Buchholz) Date: Fri, 2 Mar 2018 17:52:40 -0800 Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method In-Reply-To: <0747b8ff-ff27-8406-f05f-042ae070ce0f@oracle.com> References: <0747b8ff-ff27-8406-f05f-042ae070ce0f@oracle.com> Message-ID: Thanks - looks good. On Fri, Mar 2, 2018 at 3:37 PM, wrote: > Thanks for comments, Martin, Roger. Updated the fix as follows: > > http://cr.openjdk.java.net/~naoto/4993841/webrev.04/ > > Naoto > > > On 3/1/18 6:47 PM, naoto.sato at oracle.com wrote: > >> Hi, >> >> Please review the fix to the following issue: >> >> https://bugs.openjdk.java.net/browse/JDK-4993841 >> >> The proposed changeset is located at: >> >> http://cr.openjdk.java.net/~naoto/4993841/webrev.03/ >> >> This stems from the recent discussion regarding String.repeat().[1] The >> corresponding CSR has already been approved. >> >> Naoto >> >> -- >> [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-Fe >> bruary/051568.html >> > From stuart.marks at oracle.com Sat Mar 3 02:13:13 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Fri, 2 Mar 2018 18:13:13 -0800 Subject: RFR: JDK-8197594: String#repeat In-Reply-To: References: <55005B6D-CCD8-4B20-BD62-57DAAFCE8E56@oracle.com> Message-ID: On 2/28/18 6:34 PM, James Laskey wrote: > Thanks Stuart. RE apinote, I was trying to follow the pattern of other older > method comments (Roman-style.) Comments/Javadoc in most of these older > classes are a mix of styles. Question: if you update/clean-up a method in an > older class, should you bring the comment/Javadoc up-to-date as well? This is always a tough one. It's like when you're refactoring code... sometimes you just want to clean up the next thing, and the next, and the next, until you're off in the weeds. On the one hand, there's the prevailing rule of remaining consistent with other stuff in the same file. On the other hand, if there are problems with other stuff in the file, it often doesn't make sense to propagate the same error to the new stuff you're adding, merely in order to remain consistent. Sometimes it's reasonable just to include the other cleanups along with the current changeset, if they're small enough and prove not to be too much of a distraction. At other times, the cleanups will tend to overwhelm the main goal of this changeset. In those cases, I'd suggest proceeding the "right way" for the stuff being added, even if it means a hopefully temporary inconsistency with the rest of the file. Then do the cleanup and consistency changes in a separate pass. This requires a separate bug report, but that's not a big deal. Often, if it's just javadoc stuff, it won't require regression tests. If the doc changes are merely editorial (not specification) it doesn't even require a CSR. So pure cleanup changes can proceed relatively quickly. s'marks From david.holmes at oracle.com Sat Mar 3 03:36:52 2018 From: david.holmes at oracle.com (David Holmes) Date: Sat, 3 Mar 2018 13:36:52 +1000 Subject: RFR 8198970: jnu_util.c compilation error on Solaris In-Reply-To: <6d9caae8-9eac-73f0-b6c1-faa648d1a9d4@Oracle.com> References: <6d9caae8-9eac-73f0-b6c1-faa648d1a9d4@Oracle.com> Message-ID: <15ad24c1-d390-8257-68e1-cba4708c2a1c@oracle.com> On 3/03/2018 8:56 AM, Roger Riggs wrote: > Please review a correction to the jni_util.c native code that does not > compile on Solaris. > Declarations must precede assignments. Wow! I didn't think Solaris Studio compiler was subject to such anachronisms! We must be compiling in a really old mode. I'm pretty darn certain we're not limited this way when compiling hotspot .. David > Issue: 8198970 jnu_util.c compilation error on Solaris > > > diff --git a/src/java.base/share/native/libjava/jni_util.c > b/src/java.base/share/native/libjava/jni_util.c > --- a/src/java.base/share/native/libjava/jni_util.c > +++ b/src/java.base/share/native/libjava/jni_util.c > @@ -803,10 +803,10 @@ InitializeEncoding(JNIEnv *env, const ch > ???????????? (strcmp(encname, "ISO-8859-1") == 0)) { > ???????????? fastEncoding = FAST_8859_1; > ???????? } else if (strcmp(encname, "UTF-8") == 0) { > -??????????? fastEncoding = FAST_UTF_8; > ???????????? jstring enc = (*env)->NewStringUTF(env, encname); > ???????????? if (enc == NULL) > ???????????????? return; > +??????????? fastEncoding = FAST_UTF_8; > ???????????? jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); > ???????????? (*env)->DeleteLocalRef(env, enc); > ???????? } else if (strcmp(encname, "ISO646-US") == 0) { > @@ -818,10 +818,10 @@ InitializeEncoding(JNIEnv *env, const ch > ???????????? strcmp(encname, "utf-16le") == 0) { > ???????????? fastEncoding = FAST_CP1252; > ???????? } else { > -??????????? fastEncoding = NO_FAST_ENCODING; > ???????????? jstring enc = (*env)->NewStringUTF(env, encname); > ???????????? if (enc == NULL) > ???????????????? return; > +??????????? fastEncoding = NO_FAST_ENCODING; > ???????????? jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); > ???????????? (*env)->DeleteLocalRef(env, enc); > ???????? } > > > Thanks, Roger > > From ecki at zusammenkunft.net Sat Mar 3 07:13:12 2018 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Sat, 3 Mar 2018 08:13:12 +0100 Subject: Floating Point and Arithmetic Changes for Java SE Lnguage In-Reply-To: References: Message-ID: <5a9a4b08.4bab500a.97905.feab@mx.google.com> Hello Anon, It is impossible to Change the Java behavior for already existing Features like the simple Floating Point types. I would not expect much in this area. There was a JSR to add a new mode, but it seems to be abandoned: https://jcp.org/en/jsr/detail?id=84 I think there was some discussion on Underflow/Overflow handlers, cant remeber where I have seen it. It seems to be not on the current JEP list: http://openjdk.java.net/jeps/0 BTW: please reconsider your communication strategy (especially on Mailing lists). Marking mails as urgent should only be done if you are sure they are urgent to all (thousand) receivers, not only to you. Gruss Bernd -- http://bernd.eckenfels.net Von: A Z Gesendet: Samstag, 3. M?rz 2018 04:25 An: core-libs-dev at openjdk.java.net Betreff: Floating Point and Arithmetic Changes for Java SE Lnguage Wichtigkeit: Hoch I have found that double and float types in java are heirs to arithmetic underflow and overflow at any use. I have found that presently, floating point is an arithmetic approximation. My problem is that the java language needs to be changed here, so that one may have arithmetic accuracy with floats and doubles. There is also a trigonometric shortfall when it comes to BigDecimal. I have attempted to, and have more carefully described these problems, via the java bugs database: JDK-8190947 JDK-8197995 JDK-8190991 JDK-8190946 -These types, as things are, must be computationally discarded, used only in terms of push and pull, and be programmed around using BigDecimal, which will be a waste of memory, program execution speed, and a total confusion due to the lack of any operator usage options on BigDecimals. -It is the case that set, get methods, constructors and mutability methods are all based around float and double, not BigDecimal, which is part of the previous problem. -It is the case that setting up BigDecimals can be and is a circumstantial waste of memory with very many tasks, combined with the fact that the fact that having to use BigDecimal method calls is nowhere near as efficient or legible to developers or mathematics and enginner programmers (and useful with their time) as +, -, *, /, %, +=,-+,*=,/=,%=, ++, -- .This is a syntax argument largely, but also an instruction argument since BigDecimals have to be set up or used with an extra, thereby second, call. -It is the case that every other major language includes both floating point and accuracy mode options with these two types and or Objects, either as a source code instruction or as a compiler switch option. These languages at least provide both options for floating point and mathematical accuracy mode. -It is so that the present arithmetic underflow and underflow are total disadvantages, that need only be changed in place, for preconditions and postconditions. This is in regard to programs that have been compiled and built already. -It is also the case that the state of Java floating point for the last 10 years or so is not really any argument, given that things can be changed in place remaining reverse compatible, along with how clear and necessary the problem is. -My Oracle Support technical reviews seem not to recognise these real problems whatsoever, or only interpret matters in terms of the Java Language Specification on these issues, which of itself possesses inadequecies in these places. Can someone please reply to me on these things? Can Oracle update the Java SE language? From naoto.sato at oracle.com Sat Mar 3 17:30:37 2018 From: naoto.sato at oracle.com (naoto.sato at oracle.com) Date: Sat, 3 Mar 2018 09:30:37 -0800 Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method In-Reply-To: <7c774842-df5a-d0c7-8421-c9ec8f8328cb@oracle.com> References: <0747b8ff-ff27-8406-f05f-042ae070ce0f@oracle.com> <7c774842-df5a-d0c7-8421-c9ec8f8328cb@oracle.com> Message-ID: <17e84e26-20c5-f5ae-2a31-32ff5dba6159@oracle.com> Hi Stuart, Filed an issue for the cleanup: https://bugs.openjdk.java.net/browse/JDK-8198989 Naoto On 3/2/18 5:50 PM, Stuart Marks wrote: > Looks good. > > I note that other codepoint-consuming methods, such as > > ??? Character.UnicodeBlock.of(cp) > ??? Character.UnicodeScript.of(cp) > ??? Character.toChars(cp, char[], int) > ??? Character.toChars(cp) > ??? Character.getName(cp) > > all throw IAE with no message. It would be nice to add messages to them. > It would be even nicer to print out the offending value, possibly even > in hex. Indeed, there are several other places in Character.java where > exceptions are thrown that lack diagnostic information. Maybe as part of > a separate cleanup pass? > > s'marks > > On 3/2/18 3:37 PM, naoto.sato at oracle.com wrote: >> Thanks for comments, Martin, Roger. Updated the fix as follows: >> >> http://cr.openjdk.java.net/~naoto/4993841/webrev.04/ >> >> Naoto >> >> On 3/1/18 6:47 PM, naoto.sato at oracle.com wrote: >>> Hi, >>> >>> Please review the fix to the following issue: >>> >>> https://bugs.openjdk.java.net/browse/JDK-4993841 >>> >>> The proposed changeset is located at: >>> >>> http://cr.openjdk.java.net/~naoto/4993841/webrev.03/ >>> >>> This stems from the recent discussion regarding String.repeat().[1] >>> The corresponding CSR has already been approved. >>> >>> Naoto >>> >>> -- >>> [1] >>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051568.html >>> From poweruserm at live.com.au Sun Mar 4 05:24:02 2018 From: poweruserm at live.com.au (A Z) Date: Sun, 4 Mar 2018 05:24:02 +0000 Subject: core-libs-dev Digest, Vol 131, Issue 19 In-Reply-To: References: Message-ID: To who it may concern, 'There was a JSR to add a new mode' then I suppose I would be asking for that change on float and double, that being the case, as well as an extra mathematics class for BigDecimal. Despite all the time since 1.1, these are necessary changes, since having to use BigDecimal for all accurate arithmetic begins to waste memory, instructions, and the presently unavoidable translation betwee get/set (float or double) and compute (BigDecimal) and convert to (float or double). These are in fact not opinions, but very great needs that the Software community has needed from java for a very long time now, despite statement in the Java Language Specification. ________________________________ From: core-libs-dev on behalf of core-libs-dev-request at openjdk.java.net Sent: Saturday, 3 March 2018 11:00 PM To: core-libs-dev at openjdk.java.net Subject: core-libs-dev Digest, Vol 131, Issue 19 Send core-libs-dev mailing list submissions to core-libs-dev at openjdk.java.net To subscribe or unsubscribe via the World Wide Web, visit http://mail.openjdk.java.net/mailman/listinfo/core-libs-dev core-libs-dev Info Page - java.net mail.openjdk.java.net core-libs-dev -- Technical discussion about the development of the core libraries About core-libs-dev or, via email, send a message with subject or body 'help' to core-libs-dev-request at openjdk.java.net You can reach the person managing the list at core-libs-dev-owner at openjdk.java.net When replying, please edit your Subject line so it is more specific than "Re: Contents of core-libs-dev digest..." Today's Topics: 1. Re: Floating Point and Arithmetic Changes for Java SE Lnguage (Bernd Eckenfels) ---------------------------------------------------------------------- Message: 1 Date: Sat, 3 Mar 2018 08:13:12 +0100 From: Bernd Eckenfels To: "core-libs-dev at openjdk.java.net" Subject: Re: Floating Point and Arithmetic Changes for Java SE Lnguage Message-ID: <5a9a4b08.4bab500a.97905.feab at mx.google.com> Content-Type: text/plain; charset="utf-8" Hello Anon, It is impossible to Change the Java behavior for already existing Features like the simple Floating Point types. I would not expect much in this area. There was a JSR to add a new mode, but it seems to be abandoned: https://jcp.org/en/jsr/detail?id=84 The Java Community Process(SM) Program - JSRs: Java ... jcp.org This JSR has been Withdrawn Reason: Due to the general absence of interest in the community, the Specification lead withdrew the JSR. Original Java Specification ... I think there was some discussion on Underflow/Overflow handlers, cant remeber where I have seen it. It seems to be not on the current JEP list: http://openjdk.java.net/jeps/0 JEP 0: JEP Index openjdk.java.net This JEP is the index of all JDK Enhancement Proposals, known as JEPs. See JEP 1 for an overview of the JEP Process. BTW: please reconsider your communication strategy (especially on Mailing lists). Marking mails as urgent should only be done if you are sure they are urgent to all (thousand) receivers, not only to you. Gruss Bernd -- http://bernd.eckenfels.net Bernd Eckenfels - Home bernd.eckenfels.net Bernd Eckenfels Kurzprofil. Seit 2004 lebe ich in Karlsruhe und seit 1998 mit Mela Eckenfels verheiratet. Ich arbeite bei einem mittelst?ndischen Software ... Von: A Z Gesendet: Samstag, 3. M?rz 2018 04:25 An: core-libs-dev at openjdk.java.net Betreff: Floating Point and Arithmetic Changes for Java SE Lnguage Wichtigkeit: Hoch I have found that double and float types in java are heirs to arithmetic underflow and overflow at any use. I have found that presently, floating point is an arithmetic approximation. My problem is that the java language needs to be changed here, so that one may have arithmetic accuracy with floats and doubles. There is also a trigonometric shortfall when it comes to BigDecimal. I have attempted to, and have more carefully described these problems, via the java bugs database: JDK-8190947 JDK-8197995 JDK-8190991 JDK-8190946 -These types, as things are, must be computationally discarded, used only in terms of push and pull, and be programmed around using BigDecimal, which will be a waste of memory, program execution speed, and a total confusion due to the lack of any operator usage options on BigDecimals. -It is the case that set, get methods, constructors and mutability methods are all based around float and double, not BigDecimal, which is part of the previous problem. -It is the case that setting up BigDecimals can be and is a circumstantial waste of memory with very many tasks, combined with the fact that the fact that having to use BigDecimal method calls is nowhere near as efficient or legible to developers or mathematics and enginner programmers (and useful with their time) as +, -, *, /, %, +=,-+,*=,/=,%=, ++, -- .This is a syntax argument largely, but also an instruction argument since BigDecimals have to be set up or used with an extra, thereby second, call. -It is the case that every other major language includes both floating point and accuracy mode options with these two types and or Objects, either as a source code instruction or as a compiler switch option. These languages at least provide both options for floating point and mathematical accuracy mode. -It is so that the present arithmetic underflow and underflow are total disadvantages, that need only be changed in place, for preconditions and postconditions. This is in regard to programs that have been compiled and built already. -It is also the case that the state of Java floating point for the last 10 years or so is not really any argument, given that things can be changed in place remaining reverse compatible, along with how clear and necessary the problem is. -My Oracle Support technical reviews seem not to recognise these real problems whatsoever, or only interpret matters in terms of the Java Language Specification on these issues, which of itself possesses inadequecies in these places. Can someone please reply to me on these things? Can Oracle update the Java SE language? End of core-libs-dev Digest, Vol 131, Issue 19 ********************************************** From jbluettduncan at gmail.com Sun Mar 4 12:01:46 2018 From: jbluettduncan at gmail.com (Jonathan Bluett-Duncan) Date: Sun, 4 Mar 2018 12:01:46 +0000 Subject: core-libs-dev Digest, Vol 131, Issue 19 In-Reply-To: References: Message-ID: Okay. Do you have any citations that we can refer to to confirm for ourselves that this is indeed a recognised need? Cheers, Jonathan On 4 March 2018 at 05:24, A Z wrote: > To who it may concern, > > > 'There was a JSR to add a new mode' > > > then I suppose I would be asking for that change on float and double, that > being the case, > > > as well as an extra mathematics class for BigDecimal. > > > Despite all the time since 1.1, these are necessary changes, > > > since having to use BigDecimal for all accurate arithmetic begins > > > to waste memory, instructions, and the presently unavoidable > > > translation betwee get/set (float or double) and compute (BigDecimal) > > > and convert to (float or double). > > > These are in fact not opinions, but very great needs that the Software > > > community has needed from java for a very long time now, > > > despite statement in the Java Language Specification. > > . . . From xu.y.yin at oracle.com Mon Mar 5 01:26:25 2018 From: xu.y.yin at oracle.com (Chris Yin) Date: Mon, 5 Mar 2018 09:26:25 +0800 Subject: RFR 8198931: remove java.xml.bind module dependency for com/sun/jndi tests Message-ID: Please review the minor changes to remove java.xml.bind module dependency for com/sun/jndi tests, thanks bug: https://bugs.openjdk.java.net/browse/JDK-8198931 webrev: http://cr.openjdk.java.net/~xiaofeya/8198931/webrev.00/ Regards, Chris From Lance.Andersen at oracle.com Mon Mar 5 01:38:38 2018 From: Lance.Andersen at oracle.com (Lance Andersen) Date: Sun, 4 Mar 2018 20:38:38 -0500 Subject: RFR 8198931: remove java.xml.bind module dependency for com/sun/jndi tests In-Reply-To: References: Message-ID: <0D4A470F-56EF-4F5F-8EFF-C65068BCD6ED@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 Mar 4, 2018, at 8:26 PM, Chris Yin wrote: > > Please review the minor changes to remove java.xml.bind module dependency for com/sun/jndi tests, thanks > > bug: https://bugs.openjdk.java.net/browse/JDK-8198931 > webrev: http://cr.openjdk.java.net/~xiaofeya/8198931/webrev.00/ > > Regards, > Chris From xu.y.yin at oracle.com Mon Mar 5 02:44:18 2018 From: xu.y.yin at oracle.com (Chris Yin) Date: Mon, 5 Mar 2018 10:44:18 +0800 Subject: RFR 8198931: remove java.xml.bind module dependency for com/sun/jndi tests In-Reply-To: <0D4A470F-56EF-4F5F-8EFF-C65068BCD6ED@oracle.com> References: <0D4A470F-56EF-4F5F-8EFF-C65068BCD6ED@oracle.com> Message-ID: Thank you, Lance Regards, Chris > On 5 Mar 2018, at 9:38 AM, Lance Andersen wrote: > > +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 Mar 4, 2018, at 8:26 PM, Chris Yin > wrote: > >> Please review the minor changes to remove java.xml.bind module dependency for com/sun/jndi tests, thanks >> >> bug: https://bugs.openjdk.java.net/browse/JDK-8198931 > >> webrev: http://cr.openjdk.java.net/~xiaofeya/8198931/webrev.00/ > >> >> Regards, >> Chris From david.holmes at oracle.com Mon Mar 5 06:33:20 2018 From: david.holmes at oracle.com (David Holmes) Date: Mon, 5 Mar 2018 16:33:20 +1000 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: References: Message-ID: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> Hi Ian, Do you run with -Xcheck:jni in production mode because you load unknown native code libraries? It's mainly intended as a diagnostic option to turn on if you encounter a possible JNI problem. I'll leave the debate on your actual patch proposal to others more familiar with the library code. Thanks, David On 5/03/2018 5:24 AM, Ian Rogers wrote: > Hi, > > we've been encountering poor performance with -Xcheck:jni, for the > following example the performance is 140x to 510x slower with the flag > enabled: > >>>>> > import java.io.ByteArrayOutputStream; > import java.io.IOException; > import java.util.Random; > import java.util.zip.DeflaterOutputStream; > > public final class CheckJniTest { > static void deflateBytesPerformance() throws IOException { > byte[] inflated = new byte[1 << 23]; > new Random(71917367).nextBytes(inflated); > ByteArrayOutputStream deflated = new ByteArrayOutputStream(); > try (DeflaterOutputStream dout = new DeflaterOutputStream(deflated)) { > dout.write(inflated, 0, inflated.length); > } > if (8391174 != deflated.size()) { > throw new AssertionError(); > } > } > > public static void main(String args[]) throws IOException { > int n = 5; > if (args.length > 0) { > n = Integer.parseInt(args[0]); > } > for (int i = 0; i < n; i++) { > long startTime = System.currentTimeMillis(); > deflateBytesPerformance(); > long endTime = System.currentTimeMillis(); > System.out.println("Round " + i + " took " + (endTime - startTime) + > "ms"); > } > } > } > <<<< > > The issue is in the libzip Deflater.c JNI code: > http://hg.openjdk.java.net/jdk/jdk/file/c5eb27eed365/src/java.base/share/native/libzip/Deflater.c#l131 > > The test has an 8MB array to deflate/compress. The DeflaterOutputStream has > an buffer of size 512 bytes: > http://hg.openjdk.java.net/jdk/jdk/file/c5eb27eed365/src/java.base/share/classes/java/util/zip/DeflaterOutputStream.java#l128 > > To compress the array, 16,384 native calls are made that use the 8MB input > array and the 512 byte output array. These arrays are accessed using > GetPrimitiveArrayCritical that with -Xcheck:jni copies the array: > http://hg.openjdk.java.net/jdk/jdk/file/c5eb27eed365/src/hotspot/share/prims/jniCheck.cpp#l1862 > The copying of the arrays leads to 128GB of copying which dominates > execution time. > > One approach to fix the problem is to rewrite libzip in Java. GNU Classpath > has such an implementation: > http://cvs.savannah.gnu.org/viewvc/classpath/classpath/java/util/zip/Deflater.java?view=markup#l417 > > A different approach is to use Get/SetByteArrayRegion (using > Get/SetByteArrayElements would be no different than the current approach > accept potentially causing more copies). I've included a patch and > performance data for this approach below where regions of the arrays are > copied onto a 512 byte buffer on the stack. The non -Xcheck:jni performance > is roughly equivalent before and after the patch, the -Xcheck:jni > performance is now similar to the non -Xcheck:jni performance. > > The choice to go from a using GetPrimitiveArrayCritical to > GetByteArrayRegion is a controversial one, as engineers have many different > expectations about what critical means and does. GetPrimitiveArrayCritical > may have similar overhead to GetByteArrayElements if primitive arrays > (possibly of a certain size) are known to be non-moving. There may be a > cost to pin critical arrays or regions they exist within. There may be a > global or region lock that is in play that can cause interactions with the > garbage collector - such interactions may cause tail latency issues in > production environments. GetByteArrayRegion loses compared to > GetPrimitiveArrayCritical as it must always copy a region of the array for > access. Given these issues it is hard to develop a benchmark of > GetPrimitiveArrayCritical > vs GetByteArrayRegion that can take into account the GC interactions. Most > benchmarks will see that avoiding a copy can be good for performance. > > For more background, Aleksey has a good post on GetPrimitiveArrayCritical > here: > https://shipilev.net/jvm-anatomy-park/9-jni-critical-gclocker/ > > A different solution to the performance problem presented here is to change > the check JNI implementation to do less copying of arrays. This would be > motivated if GetPrimitiveArrayCritical were expected to be used more widely > than GetByteArrayRegion in performance sensitive, commonly used code. Given > the range of problems possible with GetPrimitiveArrayCritical I'd > personally prefer GetByteArrayRegion to be more commonly used, as I'm yet > to see a performance problem that made GetPrimitiveArrayCritical so > compelling. For example, ObjectOutputStream has burnt me previously: > http://hg.openjdk.java.net/jdk/jdk/file/c5eb27eed365/src/java.base/share/native/libjava/ObjectOutputStream.c#l69 > and these trivial copy operations, should really be a call to fix the > JIT/AOT compilers. > > Next steps: it'd be great to get this turned in to a bug although its not > clear to me whether this is a JDK issue (as it uses > GetPrimitiveArrayCritical) or a HotSpot performance issue related to > -Xcheck:jni (hence the cross post). We're happy to contribute the attached > patch but there should be greater consistency in libzip, were it applied, > as there are uses of GetPrimitiveArrayCritical in the > inflation/uncompressing code and elsewhere. > > Thanks, > Ian Rogers - Google > > Current non -Xcheck:jni performance: > Round 0 took 382ms > Round 1 took 340ms > Round 2 took 303ms > Round 3 took 256ms > Round 4 took 258ms > Round 5 took 255ms > Round 6 took 260ms > Round 7 took 257ms > Round 8 took 253ms > Round 9 took 246ms > Round 10 took 246ms > Round 11 took 247ms > Round 12 took 245ms > Round 13 took 245ms > Round 14 took 246ms > Round 15 took 244ms > Round 16 took 268ms > Round 17 took 248ms > Round 18 took 247ms > Round 19 took 247ms > > Current -Xcheck:jni performance: > Round 0 took 99223ms > Round 1 took 56829ms > Round 2 took 55620ms > Round 3 took 55558ms > Round 4 took 55893ms > Round 5 took 55779ms > Round 6 took 56039ms > Round 7 took 54443ms > Round 8 took 126490ms > Round 9 took 124516ms > Round 10 took 125497ms > Round 11 took 125022ms > Round 12 took 126630ms > Round 13 took 122399ms > Round 14 took 125623ms > Round 15 took 125574ms > Round 16 took 123621ms > Round 17 took 125374ms > Round 18 took 124973ms > Round 19 took 125248ms > > Patched non -Xcheck:jni performance: > Round 0 took 363ms > Round 1 took 382ms > Round 2 took 354ms > Round 3 took 274ms > Round 4 took 265ms > Round 5 took 264ms > Round 6 took 266ms > Round 7 took 255ms > Round 8 took 259ms > Round 9 took 245ms > Round 10 took 245ms > Round 11 took 245ms > Round 12 took 245ms > Round 13 took 244ms > Round 14 took 244ms > Round 15 took 245ms > Round 16 took 358ms > Round 17 took 318ms > Round 18 took 311ms > Round 19 took 251ms > > Patched -Xcheck:jni performance: > Round 0 took 385ms > Round 1 took 373ms > Round 2 took 366ms > Round 3 took 297ms > Round 4 took 301ms > Round 5 took 303ms > Round 6 took 304ms > Round 7 took 308ms > Round 8 took 298ms > Round 9 took 287ms > Round 10 took 290ms > Round 11 took 396ms > Round 12 took 368ms > Round 13 took 328ms > Round 14 took 283ms > Round 15 took 282ms > Round 16 took 296ms > Round 17 took 283ms > Round 18 took 283ms > Round 19 took 281ms > From kim.barrett at oracle.com Mon Mar 5 06:34:01 2018 From: kim.barrett at oracle.com (Kim Barrett) Date: Mon, 5 Mar 2018 01:34:01 -0500 Subject: RFR 8198970: jnu_util.c compilation error on Solaris In-Reply-To: <15ad24c1-d390-8257-68e1-cba4708c2a1c@oracle.com> References: <6d9caae8-9eac-73f0-b6c1-faa648d1a9d4@Oracle.com> <15ad24c1-d390-8257-68e1-cba4708c2a1c@oracle.com> Message-ID: <0500D041-B02F-41A2-9E15-9C0B3F0F0DAD@oracle.com> > On Mar 2, 2018, at 10:36 PM, David Holmes wrote: > > On 3/03/2018 8:56 AM, Roger Riggs wrote: >> Please review a correction to the jni_util.c native code that does not compile on Solaris. >> Declarations must precede assignments. > > Wow! I didn't think Solaris Studio compiler was subject to such anachronisms! We must be compiling in a really old mode. I'm pretty darn certain we're not limited this way when compiling hotspot .. This is C, not C++, and is apparently being compiled in C89 mode. (Mixing declarations and statements in compound statements was added in C99.) > David > >> Issue: 8198970 jnu_util.c compilation error on Solaris >> diff --git a/src/java.base/share/native/libjava/jni_util.c b/src/java.base/share/native/libjava/jni_util.c >> --- a/src/java.base/share/native/libjava/jni_util.c >> +++ b/src/java.base/share/native/libjava/jni_util.c >> @@ -803,10 +803,10 @@ InitializeEncoding(JNIEnv *env, const ch >> (strcmp(encname, "ISO-8859-1") == 0)) { >> fastEncoding = FAST_8859_1; >> } else if (strcmp(encname, "UTF-8") == 0) { >> - fastEncoding = FAST_UTF_8; >> jstring enc = (*env)->NewStringUTF(env, encname); >> if (enc == NULL) >> return; >> + fastEncoding = FAST_UTF_8; >> jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); >> (*env)->DeleteLocalRef(env, enc); >> } else if (strcmp(encname, "ISO646-US") == 0) { >> @@ -818,10 +818,10 @@ InitializeEncoding(JNIEnv *env, const ch >> strcmp(encname, "utf-16le") == 0) { >> fastEncoding = FAST_CP1252; >> } else { >> - fastEncoding = NO_FAST_ENCODING; >> jstring enc = (*env)->NewStringUTF(env, encname); >> if (enc == NULL) >> return; >> + fastEncoding = NO_FAST_ENCODING; >> jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc); >> (*env)->DeleteLocalRef(env, enc); >> } >> Thanks, Roger From poweruserm at live.com.au Mon Mar 5 06:47:10 2018 From: poweruserm at live.com.au (A Z) Date: Mon, 5 Mar 2018 06:47:10 +0000 Subject: Fw: core-libs-dev Digest, Vol 131, Issue 19 In-Reply-To: References: , Message-ID: To who it may concern, 'There was a JSR to add a new mode' Citation about problems with Java floating point: https://people.eecs.berkeley.edu/~wkahan/JAVAhurt.pdf I suppose I would be asking for that change on float and double, that being the case, as well as an extra mathematics class for BigDecimal. People absolutely need decimal accuracy, and not floating point approximations, within their ranges. Double a = 0.1D; Double b = 0.1D; Double output = a*b; out.println(output == 0.01D); //false, should be true. //and, Float a = 0.1F; Float b = 0.1F; Float output = a*b; out.println(output == 0.01F); //false, should be true. Despite all the time since 1.1, these are necessary changes, since having to use BigDecimal for all accurate arithmetic begins to waste memory, instructions, and the presently unavoidable translation betwee get/set (float or double) and compute (BigDecimal) and convert to (float or double). The other thing is that whenever asking for a .distance() method in Java2D, Java3D, AWT, Swing, JavaFX, JavaFX2, if I even temporarily want to proceed with decimal distances, these methods are all possibly able to return underflow or underflow results. These are in fact not opinions, but very great needs that the Software community has needed from java for a very long time now, despite statements in the Java Language Specification, which in fact do not entirely, unilaterally implement the IEEE 754 standard. And can people please check out, sitting on the Oracle Java Bugs Database: JDK-8190947 JDK-8197995 JDK-8190991 JDK-8190946 From Alan.Bateman at oracle.com Mon Mar 5 08:42:12 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 5 Mar 2018 08:42:12 +0000 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> Message-ID: <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> On 05/03/2018 06:33, David Holmes wrote: > > > Hi Ian, > > Do you run with -Xcheck:jni in production mode because you load > unknown native code libraries? It's mainly intended as a diagnostic > option to turn on if you encounter a possible JNI problem. It does unusual to be running with -Xcheck:jni in a performance critical environment. I would expect to see-Xcheck:jni when developing or maintaining a library that uses JNI and drop the option the code has been fulling tested. Lots of good work was done in JDK 9 to replace the ZipFile implementation with a Java implementation and it would be good to get some results with a re-write of Inflater and Deflater. It would need lots of testing, including startup. We would need have a dependency on libz of course as it is needed by the VM to deflate entries in the jimage container (when they are compressed) or access JAR files on the boot class path. -Alan From irogers at google.com Mon Mar 5 16:34:46 2018 From: irogers at google.com (Ian Rogers) Date: Mon, 05 Mar 2018 16:34:46 +0000 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> Message-ID: Firstly, we're not running -Xcheck:jni in production code :-) During development and testing it doesn't seem an unreasonable flag to enable, but a 140x regression is too much to get developers to swallow. There are 2 performance considerations: 1) the performance of -Xcheck:jni, which probably shouldn't be orders of magnitude worse than without the flag. 2) the problems associated with JNI criticals, for which GetByteArrayRegion is a panacea but by introducing a copying overhead. Moving this code to pure Java would be awesome! Could we start a bug/process? Thanks, Ian On Mon, Mar 5, 2018 at 12:42 AM Alan Bateman wrote: > > > On 05/03/2018 06:33, David Holmes wrote: > > > > > > Hi Ian, > > > > Do you run with -Xcheck:jni in production mode because you load > > unknown native code libraries? It's mainly intended as a diagnostic > > option to turn on if you encounter a possible JNI problem. > It does unusual to be running with -Xcheck:jni in a performance critical > environment. I would expect to see-Xcheck:jni when developing or > maintaining a library that uses JNI and drop the option the code has > been fulling tested. > > Lots of good work was done in JDK 9 to replace the ZipFile > implementation with a Java implementation and it would be good to get > some results with a re-write of Inflater and Deflater. It would need > lots of testing, including startup. We would need have a dependency on > libz of course as it is needed by the VM to deflate entries in the > jimage container (when they are compressed) or access JAR files on the > boot class path. > > -Alan > From xueming.shen at oracle.com Mon Mar 5 18:28:48 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Mon, 05 Mar 2018 10:28:48 -0800 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> Message-ID: <5A9D8C60.3050505@oracle.com> On 03/05/2018 08:34 AM, Ian Rogers wrote: > Firstly, we're not running -Xcheck:jni in production code :-) During > development and testing it doesn't seem an unreasonable flag to enable, but > a 140x regression is too much to get developers to swallow. > > There are 2 performance considerations: > 1) the performance of -Xcheck:jni, which probably shouldn't be orders of > magnitude worse than without the flag. > 2) the problems associated with JNI criticals, for which GetByteArrayRegion > is a panacea but by introducing a copying overhead. > > The reason the GetByteArrayCritical was/is being used here is exactly to avoid the copy overhead, which was an issue escalated in the past. Though the "copy overhead" appears to be much bigger for the GBAC when -Xcheck:jni is used here. Another issue with the DeflaterOutputStream is the default buf size is relative too small, for historical reason. So with a DeflaterOutStream(deflated, new Deflater(), 8192 *64), is which a bigger buf/8192*64, the performance is close to the run with the -Xcheck:jni for the byte[1 << 23] input. Understood the test case is to show the issue for the GetPrimitiveArrayCritical+check:jni use scenario. -Sherman From brian.burkhalter at oracle.com Mon Mar 5 18:29:57 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Mon, 5 Mar 2018 10:29:57 -0800 Subject: RFR 8198899: Compilation errors in java.prefs with VS 2017https://bugs.openjdk.java.net/browse/JDK-8198899 http://javaweb.us.oracle.com/~bburkhal/jdk/review/8198899/webrev.00 This code currently represents a 64-bit Windows HKEY as an int at the Java level. The proposed change is to represent the HKEY as a long. All open/test/jdk/:jdk_core, closed/test/jdk/:jdk_core passed in Mach 5 on Windows-x64. Thanks, Brian Message-ID: <68DD13EA-0EB6-4A9E-BBFC-EB85E4A47E63@oracle.com> https://bugs.openjdk.java.net/browse/JDK-8198899 http://cr.openjdk.java.net/~bpb/8198899/webrev.00/ This code currently represents a 64-bit Windows HKEY as an int at the Java level. The proposed change is to represent the HKEY as a long. All existing regression tests passed on Windows-x64. Thanks, Brian From paul.sandoz at oracle.com Mon Mar 5 18:39:14 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 5 Mar 2018 10:39:14 -0800 Subject: RFR 8198899: Compilation errors in java.prefs with VS 2017https://bugs.openjdk.java.net/browse/JDK-8198899 http://javaweb.us.oracle.com/~bburkhal/jdk/review/8198899/webrev.00 This code currently represents a 64-bit Windows HKEY as an int at the Java level. The proposed change is to represent the HKEY as a long. All open/test/jdk/:jdk_core, closed/test/jdk/:jdk_core passed in Mach 5 on Windows-x64. Thanks, Brian In-Reply-To: <68DD13EA-0EB6-4A9E-BBFC-EB85E4A47E63@oracle.com> References: <68DD13EA-0EB6-4A9E-BBFC-EB85E4A47E63@oracle.com> Message-ID: Looks like a fairly routine translation. Did you consider keeping this contained within the JNI code if that is at all possible? I don?t know whether that would just push the compiler error around e.g. converting from jint to jlong then to HKEY? 747 int maxValueNameLength = (int)result[MAX_VALUE_NAME_LENGTH]; 748 int valuesNumber = (int)result[VALUES_NUMBER]; Might wanna comment that the lossy conversion is safe? Paul. > On Mar 5, 2018, at 10:29 AM, Brian Burkhalter wrote: > > https://bugs.openjdk.java.net/browse/JDK-8198899 > http://cr.openjdk.java.net/~bpb/8198899/webrev.00/ > > This code currently represents a 64-bit Windows HKEY as an int at the Java level. The proposed change is to represent the HKEY as a long. All existing regression tests passed on Windows-x64. > > Thanks, > > Brian From xueming.shen at oracle.com Mon Mar 5 18:40:51 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Mon, 05 Mar 2018 10:40:51 -0800 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: <5A9D8C60.3050505@oracle.com> References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> Message-ID: <5A9D8F33.5060500@oracle.com> On 03/05/2018 10:28 AM, Xueming Shen wrote: > On 03/05/2018 08:34 AM, Ian Rogers wrote: >> Firstly, we're not running -Xcheck:jni in production code :-) During >> development and testing it doesn't seem an unreasonable flag to enable, but >> a 140x regression is too much to get developers to swallow. >> >> There are 2 performance considerations: >> 1) the performance of -Xcheck:jni, which probably shouldn't be orders of >> magnitude worse than without the flag. >> 2) the problems associated with JNI criticals, for which GetByteArrayRegion >> is a panacea but by introducing a copying overhead. >> >> > > The reason the GetByteArrayCritical was/is being used here is exactly to avoid the copy > overhead, which was an issue escalated in the past. Though the "copy overhead" appears > to be much bigger for the GBAC when -Xcheck:jni is used here. > > Another issue with the DeflaterOutputStream is the default buf size is relative too small, > for historical reason. So with a DeflaterOutStream(deflated, new Deflater(), 8192 *64), > is which a bigger buf/8192*64, the performance is close to the run with the -Xcheck:jni > type: in which a bigger buf/8192*64 is used, .... run without the -Xcheck:jni is specified. -Sherman From brian.burkhalter at oracle.com Mon Mar 5 18:50:30 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Mon, 5 Mar 2018 10:50:30 -0800 Subject: RFR 8198899: Compilation errors in java.prefs with VS 2017https://bugs.openjdk.java.net/browse/JDK-8198899 http://javaweb.us.oracle.com/~bburkhal/jdk/review/8198899/webrev.00 This code currently represents a 64-bit Windows HKEY as an int at the Java level. The proposed change is to represent the HKEY as a long. All open/test/jdk/:jdk_core, closed/test/jdk/:jdk_core passed in Mach 5 on Windows-x64. Thanks, Brian In-Reply-To: References: <68DD13EA-0EB6-4A9E-BBFC-EB85E4A47E63@oracle.com> Message-ID: <7FE4A837-09B8-4EC2-BC92-C18E7415AFD0@oracle.com> On Mar 5, 2018, at 10:39 AM, Paul Sandoz wrote: > Did you consider keeping this contained within the JNI code if that is at all possible? No. I think that a Java variable to contain the HKEY might be inevitable. This is similar to the FileDescriptor holding the Windows HANDLE as a long. > I don?t know whether that would just push the compiler error around e.g. converting from jint to jlong then to HKEY? If probably would. With the current version there is no passage via a 32-bit representation. Thanks, Brian From Roger.Riggs at Oracle.com Mon Mar 5 18:54:30 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Mon, 5 Mar 2018 13:54:30 -0500 Subject: RFR 8198899: Compilation errors in java.prefs with VS 2017 In-Reply-To: <7FE4A837-09B8-4EC2-BC92-C18E7415AFD0@oracle.com> References: <68DD13EA-0EB6-4A9E-BBFC-EB85E4A47E63@oracle.com> <7FE4A837-09B8-4EC2-BC92-C18E7415AFD0@oracle.com> Message-ID: <8fd54632-cae5-fb79-906e-42222d05a881@Oracle.com> Hi, (Trimmed the subject line). Looks fine. Some re-formatting to put spaces before "=" and after "," would be useful but its good to review only the real changes. Thanks, Roger On 3/5/2018 1:50 PM, Brian Burkhalter wrote: > On Mar 5, 2018, at 10:39 AM, Paul Sandoz wrote: > >> Did you consider keeping this contained within the JNI code if that is at all possible? > No. I think that a Java variable to contain the HKEY might be inevitable. This is similar to the FileDescriptor holding the Windows HANDLE as a long. > >> I don?t know whether that would just push the compiler error around e.g. converting from jint to jlong then to HKEY? > If probably would. With the current version there is no passage via a 32-bit representation. > > Thanks, > > Brian From irogers at google.com Mon Mar 5 19:15:09 2018 From: irogers at google.com (Ian Rogers) Date: Mon, 05 Mar 2018 19:15:09 +0000 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: <5A9D8F33.5060500@oracle.com> References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> <5A9D8F33.5060500@oracle.com> Message-ID: Thanks! Changing the DeflaterOutputStream buffer size to be something other than the default reduces the number of JNI native calls and is a possible work around here, as this is an implementation detail could it be made in the JDK? Unfortunately larger input sizes will also regress the issue as the number of calls is "input size / buffer size". The JNI critical may give direct access to the array but depending on the GC, may require a lock and so lock contention may be a significant issue with the code and contribute to tail latencies. In my original post I mention this is difficult to measure and I think good practice is to avoid JNI critical regions. Thanks, Ian On Mon, Mar 5, 2018 at 10:41 AM Xueming Shen wrote: > On 03/05/2018 10:28 AM, Xueming Shen wrote: > > On 03/05/2018 08:34 AM, Ian Rogers wrote: > >> Firstly, we're not running -Xcheck:jni in production code :-) During > >> development and testing it doesn't seem an unreasonable flag to enable, > but > >> a 140x regression is too much to get developers to swallow. > >> > >> There are 2 performance considerations: > >> 1) the performance of -Xcheck:jni, which probably shouldn't be orders of > >> magnitude worse than without the flag. > >> 2) the problems associated with JNI criticals, for which > GetByteArrayRegion > >> is a panacea but by introducing a copying overhead. > >> > >> > > > > The reason the GetByteArrayCritical was/is being used here is exactly to > avoid the copy > > overhead, which was an issue escalated in the past. Though the "copy > overhead" appears > > to be much bigger for the GBAC when -Xcheck:jni is used here. > > > > Another issue with the DeflaterOutputStream is the default buf size is > relative too small, > > for historical reason. So with a DeflaterOutStream(deflated, new > Deflater(), 8192 *64), > > is which a bigger buf/8192*64, the performance is close to the run with > the -Xcheck:jni > > > > type: > > in which a bigger buf/8192*64 is used, .... run without the -Xcheck:jni is > specified. > > -Sherman > > From huizhe.wang at oracle.com Mon Mar 5 19:25:14 2018 From: huizhe.wang at oracle.com (Joe Wang) Date: Mon, 5 Mar 2018 11:25:14 -0800 Subject: RFR (JDK11) 8183554: Add constructors with Charset parameter for FileReader and FileWriter Message-ID: <95db0276-5ca9-5e4e-7830-cdfd7f772bc4@oracle.com> Hi, Adding constructors with a Charset parameter for FileReader and FileWriter. Please review. JBS: https://bugs.openjdk.java.net/browse/JDK-8183554 webrev: http://cr.openjdk.java.net/~joehw/jdk11/8183554/webrev/ Thanks, Joe From brian.burkhalter at oracle.com Mon Mar 5 20:24:13 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Mon, 5 Mar 2018 12:24:13 -0800 Subject: RFR 8198899: Compilation errors in java.prefs with VS 2017 In-Reply-To: <8fd54632-cae5-fb79-906e-42222d05a881@Oracle.com> References: <68DD13EA-0EB6-4A9E-BBFC-EB85E4A47E63@oracle.com> <7FE4A837-09B8-4EC2-BC92-C18E7415AFD0@oracle.com> <8fd54632-cae5-fb79-906e-42222d05a881@Oracle.com> Message-ID: <8FC004CF-8C58-4DEE-BD1B-9D0BC13B5D51@oracle.com> Hi Roger, I?ll look into doing this before pushing the change. I assume there would be no need for further review for that. Thanks, Brian On Mar 5, 2018, at 10:54 AM, Roger Riggs wrote: > Some re-formatting to put spaces before "=" and after "," would be useful but > its good to review only the real changes. From paul.sandoz at oracle.com Mon Mar 5 20:30:17 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 5 Mar 2018 12:30:17 -0800 Subject: RFR 8198899: Compilation errors in java.prefs with VS 2017https://bugs.openjdk.java.net/browse/JDK-8198899 http://javaweb.us.oracle.com/~bburkhal/jdk/review/8198899/webrev.00 This code currently represents a 64-bit Windows HKEY as an int at the Java level. The proposed change is to represent the HKEY as a long. All open/test/jdk/:jdk_core, closed/test/jdk/:jdk_core passed in Mach 5 on Windows-x64. Thanks, Brian In-Reply-To: <7FE4A837-09B8-4EC2-BC92-C18E7415AFD0@oracle.com> References: <68DD13EA-0EB6-4A9E-BBFC-EB85E4A47E63@oracle.com> <7FE4A837-09B8-4EC2-BC92-C18E7415AFD0@oracle.com> Message-ID: > On Mar 5, 2018, at 10:50 AM, Brian Burkhalter wrote: > > On Mar 5, 2018, at 10:39 AM, Paul Sandoz > wrote: > >> Did you consider keeping this contained within the JNI code if that is at all possible? > > No. I think that a Java variable to contain the HKEY might be inevitable. This is similar to the FileDescriptor holding the Windows HANDLE as a long. > Ok. Paul. >> I don?t know whether that would just push the compiler error around e.g. converting from jint to jlong then to HKEY? > > If probably would. With the current version there is no passage via a 32-bit representation. > > Thanks, > > Brian From Alan.Bateman at oracle.com Mon Mar 5 20:41:55 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 5 Mar 2018 20:41:55 +0000 Subject: RFR (JDK11) 8183554: Add constructors with Charset parameter for FileReader and FileWriter In-Reply-To: <95db0276-5ca9-5e4e-7830-cdfd7f772bc4@oracle.com> References: <95db0276-5ca9-5e4e-7830-cdfd7f772bc4@oracle.com> Message-ID: <29cf309b-47fc-2eaa-5c42-2381290c5199@oracle.com> On 05/03/2018 19:25, Joe Wang wrote: > Hi, > > Adding constructors with a Charset parameter for FileReader and > FileWriter. Please review. > > JBS: https://bugs.openjdk.java.net/browse/JDK-8183554 > webrev: http://cr.openjdk.java.net/~joehw/jdk11/8183554/webrev/ The constructors that take String+Charset and File+Charset looks fine. I'm less sure about the constructors that take FileDescriptor+Charset, mostly because FileDescriptor is always problematic and I wouldn't expect most developers to every need this. Would you be open to leaving those out of the proposal? -Alan From xueming.shen at oracle.com Mon Mar 5 20:45:56 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Mon, 05 Mar 2018 12:45:56 -0800 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> <5A9D8F33.5060500@oracle.com> Message-ID: <5A9DAC84.906@oracle.com> On 3/5/18, 11:15 AM, Ian Rogers wrote: > Thanks! Changing the DeflaterOutputStream buffer size to be something > other than the default reduces the number of JNI native calls and is a > possible work around here, as this is an implementation detail could > it be made in the JDK? Unfortunately larger input sizes will also > regress the issue as the number of calls is "input size / buffer > size". The JNI critical may give direct access to the array but > depending on the GC, may require a lock and so lock contention may be > a significant issue with the code and contribute to tail latencies. In > my original post I mention this is difficult to measure and I think > good practice is to avoid JNI critical regions. We do have a history on the usage of GetPrimitiveArrayCritical/Elements() here regarding the potential "lock contention", copy overhead... and went back and forth on which jni call is the appropriate one to go. Martin might still have the memory of that :-) Some related bugids: https://bugs.openjdk.java.net/browse/JDK-6206933 https://bugs.openjdk.java.net/browse/JDK-6348045 https://bugs.openjdk.java.net/browse/JDK-5043044 https://bugs.openjdk.java.net/browse/JDK-6356456 There was once a "lock contention" bug that affects the performance of GetPrimitiveArrayCritical. But that bug was fixed since (in hotspot). With various use scenario, a "copy overhead" when using GetPrimitiveArrayElement() was concluded not acceptable, at least back then. It appears to be an easy to do/must to do (nice to have?) to increase the "default buf size" used in DeflaterOutputStream. But every time we tried to touch those default setting/configuration values that have been there for decades, some "regression" complains would come back and hurt us :-) For this particular case a potential "regression" is that the footprint increase because of the the default buffer size is increased from 512 -> xxxx might not be desirable for some use scenario. For example if hundreds of thousands of DeflaterOutputStream are being open/closed on hundreds of thousands of compressed jar or zip files the increase might be huge. And the API does provide the constructor that you can customize the buffer size. It might be desired to keep the default size asis. That said, I agreed that 512 appears to be a "too-small" default size if the majority of the use scenario for the DeflaterOutputStream is to open a jar/zip file entry. Sherman From Alan.Bateman at oracle.com Mon Mar 5 20:51:20 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 5 Mar 2018 20:51:20 +0000 Subject: RFR 8198899: Compilation errors in java.prefs with VS 2017 In-Reply-To: <68DD13EA-0EB6-4A9E-BBFC-EB85E4A47E63@oracle.com> References: <68DD13EA-0EB6-4A9E-BBFC-EB85E4A47E63@oracle.com> Message-ID: On 05/03/2018 18:29, Brian Burkhalter wrote: > https://bugs.openjdk.java.net/browse/JDK-8198899 > http://cr.openjdk.java.net/~bpb/8198899/webrev.00/ > > This code currently represents a 64-bit Windows HKEY as an int at the Java level. The proposed change is to represent the HKEY as a long. All existing regression tests passed on Windows-x64. > This looks okay to me. -Alan From xueming.shen at oracle.com Mon Mar 5 20:54:31 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Mon, 05 Mar 2018 12:54:31 -0800 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: <5A9DAC84.906@oracle.com> References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> <5A9D8F33.5060500@oracle.com> <5A9DAC84.906@oracle.com> Message-ID: <5A9DAE87.8020801@oracle.com> On 3/5/18, 12:45 PM, Xueming Shen wrote: > On 3/5/18, 11:15 AM, Ian Rogers wrote: >> Thanks! Changing the DeflaterOutputStream buffer size to be something >> other than the default reduces the number of JNI native calls and is >> a possible work around here, as this is an implementation detail >> could it be made in the JDK? Unfortunately larger input sizes will >> also regress the issue as the number of calls is "input size / buffer >> size". The JNI critical may give direct access to the array but >> depending on the GC, may require a lock and so lock contention may be >> a significant issue with the code and contribute to tail latencies. >> In my original post I mention this is difficult to measure and I >> think good practice is to avoid JNI critical regions. > > We do have a history on the usage of > GetPrimitiveArrayCritical/Elements() here regarding the > potential "lock contention", copy overhead... and went back and forth > on which jni call is the > appropriate one to go. Martin might still have the memory of that :-) > And for the record. The direct root trigger of this issue probably is the fix for JDK-6311046 that went into jdk9. https://bugs.openjdk.java.net/browse/JDK-6311046 -Sherman > > > From Roger.Riggs at Oracle.com Mon Mar 5 21:10:16 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Mon, 5 Mar 2018 16:10:16 -0500 Subject: RFR (JDK11) 8183554: Add constructors with Charset parameter for FileReader and FileWriter In-Reply-To: <95db0276-5ca9-5e4e-7830-cdfd7f772bc4@oracle.com> References: <95db0276-5ca9-5e4e-7830-cdfd7f772bc4@oracle.com> Message-ID: Hi Joe, For files by name and File these are useful additions.? The new constructors with FileDescriptors don't have a strong use case for them and re-using file descriptors is something that developers need to be more careful about.? They don't need the added convenience constructors and can build readers and writers from streams when they need it. Regards, Roger On 3/5/2018 2:25 PM, Joe Wang wrote: > Hi, > > Adding constructors with a Charset parameter for FileReader and > FileWriter. Please review. > > JBS: https://bugs.openjdk.java.net/browse/JDK-8183554 > webrev: http://cr.openjdk.java.net/~joehw/jdk11/8183554/webrev/ > > Thanks, > Joe > From Roger.Riggs at Oracle.com Mon Mar 5 21:32:47 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Mon, 5 Mar 2018 16:32:47 -0500 Subject: RFR: 8197538 Remove mention of hotjava paths in MimeTable.java Message-ID: Please review a change to a location where mailcap entries may appear. The mention of "hotjava.home" is ancient history. BTW, if you know whether? "user.mailcap" System property is used, I'd be interested if anyone is using it. I may need a CSR to make it official. diff --git a/src/java.base/share/classes/sun/net/www/MimeTable.java b/src/java.base/share/classes/sun/net/www/MimeTable.java --- a/src/java.base/share/classes/sun/net/www/MimeTable.java +++ b/src/java.base/share/classes/sun/net/www/MimeTable.java @@ -57,9 +57,6 @@ public class MimeTable implements FileNa "/etc/mailcap", "/usr/etc/mailcap", "/usr/local/etc/mailcap", - System.getProperty("hotjava.home", - "/usr/local/hotjava") - + "/lib/mailcap", }; return null; } Thanks, Roger From patrick at reini.net Mon Mar 5 21:45:00 2018 From: patrick at reini.net (Patrick Reinhart) Date: Mon, 5 Mar 2018 22:45:00 +0100 Subject: RFR 8196298 Add null Reader and Writer with latest changes Message-ID: <6AF3DEA9-5572-47B1-804E-AD7B0E46D833@reini.net> I tried to incorporate all feedback I received so far and updated the webrev accordingly: http://cr.openjdk.java.net/~reinhapa/reviews/8196298/webrev.01 -Patrick From lance.andersen at oracle.com Mon Mar 5 21:47:13 2018 From: lance.andersen at oracle.com (Lance Andersen) Date: Mon, 5 Mar 2018 16:47:13 -0500 Subject: RFR: 8197538 Remove mention of hotjava paths in MimeTable.java In-Reply-To: References: Message-ID: <6777CD82-5487-4094-868A-FEE644486D21@oracle.com> +1 > On Mar 5, 2018, at 4:32 PM, Roger Riggs wrote: > > Please review a change to a location where mailcap entries may appear. > The mention of "hotjava.home" is ancient history. > > BTW, if you know whether "user.mailcap" System property is used, I'd be interested if anyone is using it. > > I may need a CSR to make it official. > > diff --git a/src/java.base/share/classes/sun/net/www/MimeTable.java b/src/java.base/share/classes/sun/net/www/MimeTable.java > --- a/src/java.base/share/classes/sun/net/www/MimeTable.java > +++ b/src/java.base/share/classes/sun/net/www/MimeTable.java > @@ -57,9 +57,6 @@ public class MimeTable implements FileNa > "/etc/mailcap", > "/usr/etc/mailcap", > "/usr/local/etc/mailcap", > - System.getProperty("hotjava.home", > - "/usr/local/hotjava") > - + "/lib/mailcap", > }; > return null; > } > > Thanks, Roger > > 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 Mon Mar 5 21:55:32 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Mon, 5 Mar 2018 13:55:32 -0800 Subject: RFR: 8197538 Remove mention of hotjava paths in MimeTable.java In-Reply-To: References: Message-ID: <62A5F1BB-83DF-4128-A048-2743C7DF4291@oracle.com> On Mar 5, 2018, at 1:32 PM, Roger Riggs wrote: > Please review a change to a location where mailcap entries may appear. +1 > The mention of "hotjava.home" is ancient history. Quite so. Brian From huizhe.wang at oracle.com Mon Mar 5 21:58:08 2018 From: huizhe.wang at oracle.com (Joe Wang) Date: Mon, 5 Mar 2018 13:58:08 -0800 Subject: RFR (JDK11) 8183554: Add constructors with Charset parameter for FileReader and FileWriter In-Reply-To: References: <95db0276-5ca9-5e4e-7830-cdfd7f772bc4@oracle.com> Message-ID: <0ac54c0a-4e4d-d9a5-ce1f-5617218c38c3@oracle.com> Thanks Alan, Roger! Less is better. Removed the ones that take FileDescriptors, now we're only adding Constructors that take String+Charset and File+Charset. Tests are updated accordingly. Build/Test may take a while, but expected to pass since it was simply removing the FileDescriptor from the Enum. JBS: https://bugs.openjdk.java.net/browse/JDK-8183554 webrev: http://cr.openjdk.java.net/~joehw/jdk11/8183554/webrev/ Best, Joe On 3/5/2018 1:10 PM, Roger Riggs wrote: > Hi Joe, > > For files by name and File these are useful additions.? The new > constructors with > FileDescriptors don't have a strong use case for them and re-using > file descriptors > is something that developers need to be more careful about.? They > don't need the > added convenience constructors and can build readers and writers from > streams > when they need it. > > Regards, Roger > > > On 3/5/2018 2:25 PM, Joe Wang wrote: >> Hi, >> >> Adding constructors with a Charset parameter for FileReader and >> FileWriter. Please review. >> >> JBS: https://bugs.openjdk.java.net/browse/JDK-8183554 >> webrev: http://cr.openjdk.java.net/~joehw/jdk11/8183554/webrev/ >> >> Thanks, >> Joe >> > From mike.skells1 at gmail.com Tue Mar 6 00:35:49 2018 From: mike.skells1 at gmail.com (Michael Skells) Date: Tue, 06 Mar 2018 00:35:49 +0000 Subject: trivial patch to reduce allocations in nio open* methods Message-ID: Hi I have a trivial patch to reduce allocation of OpenOption sets where no args are supplied Spotted this while working on scala compiler, trying to reduce allocations I cannot build JDK due to visual studio issues Can someone progress the patch for me? Dont want to send a patch to this mailgroup! I have previously signed OCA and contributed (although it has been a while) Mike From brian.burkhalter at oracle.com Tue Mar 6 01:12:33 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Mon, 5 Mar 2018 17:12:33 -0800 Subject: trivial patch to reduce allocations in nio open* methods In-Reply-To: References: Message-ID: <158BFF8B-586B-4C1C-8DBE-5C5DD3E8D66B@oracle.com> Hello, Redirecting to nio-dev. Please reply omitting core-libs-dev. If the patch is small you can include it in e-mail to the mailing list as attachments are generally scrubbed. Thanks, Brian On Mar 5, 2018, at 4:35 PM, Michael Skells wrote: > I have a trivial patch to reduce allocation of OpenOption sets where no > args are supplied > > Spotted this while working on scala compiler, trying to reduce allocations > > I cannot build JDK due to visual studio issues > > Can someone progress the patch for me? Dont want to send a patch to this > mailgroup! > > I have previously signed OCA and contributed (although it has been a while) From poweruserm at live.com.au Tue Mar 6 04:48:47 2018 From: poweruserm at live.com.au (A Z) Date: Tue, 6 Mar 2018 04:48:47 +0000 Subject: Java Float and Double changes, BigDecimal maths class, BigDecimal operators? In-Reply-To: References: , , Message-ID: 'There was a JSR to add a new mode' Citation about problems with Java floating point: https://people.eecs.berkeley.edu/~wkahan/JAVAhurt.pdf I suppose I would be asking for that change on float and double, that being the case, as well as an extra mathematics class for BigDecimal. People absolutely need decimal accuracy, and not floating point approximations, within their ranges. Double a = 0.1D; Double b = 0.1D; Double output = a*b; out.println(output == 0.01D); //false, should be true. //and, Float a = 0.1F; Float b = 0.1F; Float output = a*b; out.println(output == 0.01F); //false, should be true. Despite all the time since 1.1, these are necessary changes, since having to use BigDecimal for all accurate arithmetic begins to waste memory, instructions, and the presently unavoidable translation betwee get/set (float or double) and compute (BigDecimal) and convert to (float or double). The other thing is that whenever asking for a .distance() method in Java2D, Java3D, AWT, Swing, JavaFX, JavaFX2, if I even temporarily want to proceed with decimal distances, these methods are all possibly able to return underflow or underflow results. These are in fact not opinions, but very great needs that the Software community has needed from java for a very long time now, despite statements in the Java Language Specification, which in fact do not entirely, unilaterally implement the IEEE 754 standard. And can people please check out, sitting on the Oracle Java Bugs Database: JDK-8190947 JDK-8197995 JDK-8190991 JDK-8190946 From daniel.fuchs at oracle.com Tue Mar 6 13:07:25 2018 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Tue, 6 Mar 2018 13:07:25 +0000 Subject: RFR: JDK-8144300 : Java does not honor http.nonProxyHosts value having wildcard * both at end and start In-Reply-To: References: Message-ID: <953e2ed8-4e1c-3f62-8fcc-9bee700ca4f2@oracle.com> Hi, Looks reasonable to me. best regards, -- daniel On 01/03/2018 14:46, Pallavi Sonal wrote: > Hi, > > Please review the following change to fix JDK-8144300. > > > > Bug : https://bugs.openjdk.java.net/browse/JDK-8144300 > > Webrev : http://cr.openjdk.java.net/~rpatil/8144300/webrev.00/ > > > > Whenever there is a wildcard(*) at either the beginning or the end of a hostname specified in the list of http.nonProxyHosts , the code works as expected and DIRECT connection is used for them. But in scenarios, where there is a wildcard both at the beginning and end of the hostname, proxy is used instead of DIRECT connection. > > > > All the tier1 and tier2 Mach 5 tests have passed. > > > > Thanks, > > Pallavi Sonal > From martin.desruisseaux at geomatys.com Tue Mar 6 13:25:32 2018 From: martin.desruisseaux at geomatys.com (Martin Desruisseaux) Date: Tue, 6 Mar 2018 14:25:32 +0100 Subject: Java Float and Double changes, BigDecimal maths class, BigDecimal operators? In-Reply-To: References: Message-ID: <6412425c-8ef9-71ab-5dc0-3b56ad5ca110@geomatys.com> Le 06/03/2018 ? 05:48, A Z a ?crit?: > Citation about problems with Java floating point: > https://people.eecs.berkeley.edu/~wkahan/JAVAhurt.pdf This paper is about complex numbers, operation overloading, handling of NaN, /etc./ I don't think that they are making an argument for decimal arithmetic. > People absolutely need decimal accuracy, and not floating point > approximations > Float and double are accurate in base 2, which is as good as base 10 for scientific and engineering applications (nature does not have a preferred base - our use of base 10 is only because human have 10 fingers). Base 10 is useful in some cases like financial applications, but those ones already have their own representation (e.g. integer count of 1/1000 of cents). When numbers are measurements, values like 0.1 are approximation anyway, no matter if using base 2 or base 10. IEEE754 float and double types have hardward acceleration in modern CPU. Consequently IEEE754 is used not only in Java, but also in other languages like C/C++. The C language may give an impression of accuracy because printf can round the last digits, but the actual accuracy is still the same than Java. ??? Martin From chris.hegarty at oracle.com Tue Mar 6 14:49:36 2018 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Tue, 6 Mar 2018 14:49:36 +0000 Subject: RFR: 8197538 Remove mention of hotjava paths in MimeTable.java In-Reply-To: References: Message-ID: <40e80a30-39cd-2f6c-74dd-260ed1f1ce92@oracle.com> On 05/03/18 21:32, Roger Riggs wrote: > Please review a change to a location where mailcap entries may appear. > The mention of "hotjava.home" is ancient history. > > BTW, if you know whether "user.mailcap" System property is used, I'd be > interested if anyone is using it. > > I may need a CSR to make it official. > > diff --git a/src/java.base/share/classes/sun/net/www/MimeTable.java > b/src/java.base/share/classes/sun/net/www/MimeTable.java > --- a/src/java.base/share/classes/sun/net/www/MimeTable.java > +++ b/src/java.base/share/classes/sun/net/www/MimeTable.java > @@ -57,9 +57,6 @@ public class MimeTable implements FileNa > "/etc/mailcap", > "/usr/etc/mailcap", > "/usr/local/etc/mailcap", > - System.getProperty("hotjava.home", > - "/usr/local/hotjava") > - + "/lib/mailcap", > }; > return null; > } I think this is fine. -Chris. From Alan.Bateman at oracle.com Tue Mar 6 16:35:12 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 6 Mar 2018 16:35:12 +0000 Subject: RFR 8196298 Add null Reader and Writer with latest changes In-Reply-To: <6AF3DEA9-5572-47B1-804E-AD7B0E46D833@reini.net> References: <6AF3DEA9-5572-47B1-804E-AD7B0E46D833@reini.net> Message-ID: <3ebd00ec-aa2d-65b9-9f68-0d693628ef2b@oracle.com> On 05/03/2018 21:45, Patrick Reinhart wrote: > I tried to incorporate all feedback I received so far and updated the webrev accordingly: > > http://cr.openjdk.java.net/~reinhapa/reviews/8196298/webrev.01 > I think this looks good now. I've added myself as a reviewer on the CSR so you should be able to finalize it. -Alan From chris.hegarty at oracle.com Tue Mar 6 18:16:57 2018 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Tue, 6 Mar 2018 18:16:57 +0000 Subject: RFR: JDK-8144300 : Java does not honor http.nonProxyHosts value having wildcard * both at end and start In-Reply-To: References: Message-ID: <9ddafa91-d7f0-401e-3821-f141880701f5@oracle.com> Pallavi, On 01/03/18 14:46, Pallavi Sonal wrote: > Hi, > > Please review the following change to fix JDK-8144300. > > > > Bug : https://bugs.openjdk.java.net/browse/JDK-8144300 > > Webrev : http://cr.openjdk.java.net/~rpatil/8144300/webrev.00/ Looks ok to me. Please add the bugId to the @bug tag in the test before pushing. Thanks, -Chris. From patrick at reini.net Tue Mar 6 19:00:50 2018 From: patrick at reini.net (Patrick Reinhart) Date: Tue, 6 Mar 2018 20:00:50 +0100 Subject: RFR 8196298 Add null Reader and Writer with latest changes In-Reply-To: <3ebd00ec-aa2d-65b9-9f68-0d693628ef2b@oracle.com> References: <6AF3DEA9-5572-47B1-804E-AD7B0E46D833@reini.net> <3ebd00ec-aa2d-65b9-9f68-0d693628ef2b@oracle.com> Message-ID: Updated the CSR API with webrev's content and finalized it.. -Patrick Am 06.03.2018 um 17:35 schrieb Alan Bateman: > On 05/03/2018 21:45, Patrick Reinhart wrote: >> I tried to incorporate all feedback I received so far and updated the >> webrev accordingly: >> >> http://cr.openjdk.java.net/~reinhapa/reviews/8196298/webrev.01 >> >> > I think this looks good now. I've added myself as a reviewer on the > CSR so you should be able to finalize it. > > -Alan From ecki at zusammenkunft.net Tue Mar 6 19:49:50 2018 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Tue, 6 Mar 2018 20:49:50 +0100 Subject: RFR 8196298 Add null Reader and Writer with latest changes In-Reply-To: <3ebd00ec-aa2d-65b9-9f68-0d693628ef2b@oracle.com> References: <6AF3DEA9-5572-47B1-804E-AD7B0E46D833@reini.net> <3ebd00ec-aa2d-65b9-9f68-0d693628ef2b@oracle.com> Message-ID: <5a9ef0dc.77b0df0a.bb39.cc95@mx.google.com> Just a nit, Should append(CharSequence,int,int) also use checkFromIndexSize? Greetings Bernd -- http://bernd.eckenfels.net Von: Alan Bateman Gesendet: Dienstag, 6. M?rz 2018 20:35 An: Patrick Reinhart; core-libs-dev Betreff: Re: RFR 8196298 Add null Reader and Writer with latest changes On 05/03/2018 21:45, Patrick Reinhart wrote: > I tried to incorporate all feedback I received so far and updated the webrev accordingly: > > http://cr.openjdk.java.net/~reinhapa/reviews/8196298/webrev.01 > I think this looks good now. I've added myself as a reviewer on the CSR so you should be able to finalize it. -Alan From ekaterina.pavlova at oracle.com Tue Mar 6 21:45:35 2018 From: ekaterina.pavlova at oracle.com (Ekaterina Pavlova) Date: Tue, 6 Mar 2018 13:45:35 -0800 Subject: RFR(XS) [closed] : 8198924: java/lang/StackWalker/LocalsAndOperands.java timeouts with Graal Message-ID: Hi all, java/lang/StackWalker/LocalsAndOperands.java runs LocalsAndOperands 3 times with following set of jvm flags: 1) -Xint -DtestUnused=true 2) -Xcomp 3) -Xcomp -XX:-TieredCompilation When running with Graal as JIT (-XX:+TieredCompilation -XX:+UseJVMCICompiler -Djvmci.Compiler=graal) 3rd scenario could take more than 10 minutes and the test could fail by timeout. Actually running LocalsAndOperands with Graal and with "-Xcomp -XX:-TieredCompilation" doesn't provide big benefit and it would be reasonable to disable this scenario in case Graal is enabled. Please review the change. JBS: https://bugs.openjdk.java.net/browse/JDK-8198924 webrev: http://cr.openjdk.java.net/~epavlova//8198924/webrev.00/index.html testing: Tested by running the test in Graal as JIT mode. thanks, -katya p.s. Igor Ignatyev volunteered to sponsor this change. From mandy.chung at oracle.com Tue Mar 6 21:59:14 2018 From: mandy.chung at oracle.com (mandy chung) Date: Tue, 6 Mar 2018 13:59:14 -0800 Subject: RFR(XS) [closed] : 8198924: java/lang/StackWalker/LocalsAndOperands.java timeouts with Graal In-Reply-To: References: Message-ID: <571e551e-f40c-dbf6-0094-4a841fda42a3@oracle.com> Running #1 and #2 when Graal is enabled is fine. For the second @test, does it need @bug and @summary to run?? If not, I suggest to take it out as it's already mentioned in the first @test. Mandy On 3/6/18 1:45 PM, Ekaterina Pavlova wrote: > Hi all, > > java/lang/StackWalker/LocalsAndOperands.java runs LocalsAndOperands 3 > times with following set of jvm flags: > ?1) -Xint -DtestUnused=true > ?2) -Xcomp > ?3) -Xcomp -XX:-TieredCompilation > > When running with Graal as JIT (-XX:+TieredCompilation > -XX:+UseJVMCICompiler -Djvmci.Compiler=graal) > 3rd scenario could take more than 10 minutes and the test could fail > by timeout. > Actually running LocalsAndOperands with Graal and with "-Xcomp > -XX:-TieredCompilation" doesn't provide > big benefit and it would be reasonable to disable this scenario in > case Graal is enabled. > > Please review the change. > > ????? JBS: https://bugs.openjdk.java.net/browse/JDK-8198924 > ?? webrev: > http://cr.openjdk.java.net/~epavlova//8198924/webrev.00/index.html > > ? testing: Tested by running the test in Graal as JIT mode. > > thanks, > -katya > > p.s. > ?Igor Ignatyev volunteered to sponsor this change. From brian.burkhalter at oracle.com Tue Mar 6 22:12:22 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Tue, 6 Mar 2018 14:12:22 -0800 Subject: RFR 8196298 Add null Reader and Writer with latest changes In-Reply-To: <5a9ef0dc.77b0df0a.bb39.cc95@mx.google.com> References: <6AF3DEA9-5572-47B1-804E-AD7B0E46D833@reini.net> <3ebd00ec-aa2d-65b9-9f68-0d693628ef2b@oracle.com> <5a9ef0dc.77b0df0a.bb39.cc95@mx.google.com> Message-ID: <5D587382-6466-4854-8C70-68CBC8C7332E@oracle.com> Yes, I think so and and also the parameter ?csq' is allowed to be null so Objects.requireNonNull(csq) should be removed at lines 100 and 107 as no NPE is specified for these methods [1, 2]. Thanks, Brian [1] https://download.java.net/java/jdk10/docs/api/java/io/Writer.html#append(java.lang.CharSequence) [2] https://download.java.net/java/jdk10/docs/api/java/io/Writer.html#append(java.lang.CharSequence,int,int) On Mar 6, 2018, at 11:49 AM, Bernd Eckenfels wrote: > Just a nit, Should append(CharSequence,int,int) also use checkFromIndexSize? From brent.christian at oracle.com Tue Mar 6 22:30:01 2018 From: brent.christian at oracle.com (Brent Christian) Date: Tue, 6 Mar 2018 14:30:01 -0800 Subject: RFR(XS) [closed] : 8198924: java/lang/StackWalker/LocalsAndOperands.java timeouts with Graal In-Reply-To: <571e551e-f40c-dbf6-0094-4a841fda42a3@oracle.com> References: <571e551e-f40c-dbf6-0094-4a841fda42a3@oracle.com> Message-ID: <4fcc3671-214a-accd-105b-9aeb83e6e62b@oracle.com> Looks good, Katya - thanks. I agree with omitting @bug and @summary from the second @test tag. Thanks, -Brent On 3/6/18 1:59 PM, mandy chung wrote: > Running #1 and #2 when Graal is enabled is fine. > > For the second @test, does it need @bug and @summary to run?? If not, I > suggest to take it out as it's already mentioned in the first @test. > > Mandy > > > On 3/6/18 1:45 PM, Ekaterina Pavlova wrote: >> Hi all, >> >> java/lang/StackWalker/LocalsAndOperands.java runs LocalsAndOperands 3 >> times with following set of jvm flags: >> ?1) -Xint -DtestUnused=true >> ?2) -Xcomp >> ?3) -Xcomp -XX:-TieredCompilation >> >> When running with Graal as JIT (-XX:+TieredCompilation >> -XX:+UseJVMCICompiler -Djvmci.Compiler=graal) >> 3rd scenario could take more than 10 minutes and the test could fail >> by timeout. >> Actually running LocalsAndOperands with Graal and with "-Xcomp >> -XX:-TieredCompilation" doesn't provide >> big benefit and it would be reasonable to disable this scenario in >> case Graal is enabled. >> >> Please review the change. >> >> ????? JBS: https://bugs.openjdk.java.net/browse/JDK-8198924 >> ?? webrev: >> http://cr.openjdk.java.net/~epavlova//8198924/webrev.00/index.html >> >> ? testing: Tested by running the test in Graal as JIT mode. >> >> thanks, >> -katya >> >> p.s. >> ?Igor Ignatyev volunteered to sponsor this change. > From poweruserm at live.com.au Tue Mar 6 23:38:38 2018 From: poweruserm at live.com.au (A Z) Date: Tue, 6 Mar 2018 23:38:38 +0000 Subject: core-libs-dev Digest, Vol 131, Issue 26 In-Reply-To: References: Message-ID: -Whenever there there is an arithmetic continuing carry operation involving Java Float or Double, there can be an underflow or overflow. This means that comparisons at the data level using >, ==,<,<=.>=, .equals(), etc. will begin to misbehave. Whatever the behind the scenes implementation, there must be at least both options; there should be a class level keyword to enfource accuracy mode floating point arithmetic. There needs to be an accurate arithmetic mode using these types, in order to best minimise memory and instructions usage in source code. Also, programmers should be free to use accuracy arithmetic with any of the decimal supporting number types, so that they can make their own decisions about choosing types to model and actuate all sorts of phenomena in their programs. There are also syntax advantages in programming this way, too. Every othermajor language allows a requisite option to turn off floating point overflow and underflow. Java needs to. Consider, then, statements in the following online paper: http://www.sonic.net/~jddarcy/Research/jgrande.pdf There also should be operator support for BigDecimal and BigInteger, as well as a StrictMath class that supports BigDecimal trigonometry, base 2, Euler's constant e, base 10 logarithms, powers, square, cube, nth root, computation of e and pi for arbitrarily specified numbers of places (all in terms of a BigDecimal or BigInteger specified number of places). From david.holmes at oracle.com Wed Mar 7 00:06:08 2018 From: david.holmes at oracle.com (David Holmes) Date: Wed, 7 Mar 2018 10:06:08 +1000 Subject: core-libs-dev Digest, Vol 131, Issue 26 In-Reply-To: References: Message-ID: <3a369f0b-e60d-29a6-7a43-871ff9fcff25@oracle.com> "A Z", Can you please post using appropriate subject lines, and formatting and follow basic email etiquette - which includes identifying yourself. You are quoting 20 year old papers. The JavaGrande effort was born in 1998 and died a few years later. David On 7/03/2018 9:38 AM, A Z wrote: > -Whenever there there is an arithmetic continuing carry operation > > involving Java Float or Double, there can be an underflow or overflow. > > This means that comparisons at the data level using > >> , ==,<,<=.>=, .equals(), etc. will begin to misbehave. > > > Whatever the behind the scenes implementation, there > > must be at least both options; there should be > > a class level keyword to enfource accuracy mode floating point > > arithmetic. > > > There needs to be an accurate arithmetic mode using these types, > > in order to best minimise memory and instructions > > usage in source code. > > > Also, programmers should be free to use accuracy arithmetic > > with any of the decimal supporting number types, > > so that they can make their own decisions about > > choosing types to model and actuate all sorts > > of phenomena in their programs. > > > There are also syntax advantages in programming this way, too. > > Every othermajor language allows a requisite option > > to turn off floating point overflow and underflow. > > Java needs to. > > > Consider, then, statements in the following online paper: > > > http://www.sonic.net/~jddarcy/Research/jgrande.pdf > > > There also should be operator support for BigDecimal and BigInteger, > > as well as a StrictMath class that supports BigDecimal trigonometry, > > base 2, Euler's constant e, base 10 logarithms, powers, > > square, cube, nth root, computation of e and pi > > for arbitrarily specified numbers of places > > (all in terms of a BigDecimal or BigInteger specified number of places). > > From stuart.marks at oracle.com Wed Mar 7 02:17:00 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Tue, 6 Mar 2018 18:17:00 -0800 Subject: [11] RFR: 4993841: (str) java.lang.Character should have a toString(int) method In-Reply-To: <17e84e26-20c5-f5ae-2a31-32ff5dba6159@oracle.com> References: <0747b8ff-ff27-8406-f05f-042ae070ce0f@oracle.com> <7c774842-df5a-d0c7-8421-c9ec8f8328cb@oracle.com> <17e84e26-20c5-f5ae-2a31-32ff5dba6159@oracle.com> Message-ID: Hi Naoto, Thanks for fixing the original issue, and for filing the cleanup followup bug. s'marks On 3/3/18 9:30 AM, naoto.sato at oracle.com wrote: > Hi Stuart, > > Filed an issue for the cleanup: > > https://bugs.openjdk.java.net/browse/JDK-8198989 > > Naoto > > On 3/2/18 5:50 PM, Stuart Marks wrote: >> Looks good. >> >> I note that other codepoint-consuming methods, such as >> >> ???? Character.UnicodeBlock.of(cp) >> ???? Character.UnicodeScript.of(cp) >> ???? Character.toChars(cp, char[], int) >> ???? Character.toChars(cp) >> ???? Character.getName(cp) >> >> all throw IAE with no message. It would be nice to add messages to them. It >> would be even nicer to print out the offending value, possibly even in hex. >> Indeed, there are several other places in Character.java where exceptions are >> thrown that lack diagnostic information. Maybe as part of a separate cleanup >> pass? >> >> s'marks >> >> On 3/2/18 3:37 PM, naoto.sato at oracle.com wrote: >>> Thanks for comments, Martin, Roger. Updated the fix as follows: >>> >>> http://cr.openjdk.java.net/~naoto/4993841/webrev.04/ >>> >>> Naoto >>> >>> On 3/1/18 6:47 PM, naoto.sato at oracle.com wrote: >>>> Hi, >>>> >>>> Please review the fix to the following issue: >>>> >>>> https://bugs.openjdk.java.net/browse/JDK-4993841 >>>> >>>> The proposed changeset is located at: >>>> >>>> http://cr.openjdk.java.net/~naoto/4993841/webrev.03/ >>>> >>>> This stems from the recent discussion regarding String.repeat().[1] The >>>> corresponding CSR has already been approved. >>>> >>>> Naoto >>>> >>>> -- >>>> [1] >>>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051568.html From martinrb at google.com Wed Mar 7 02:44:47 2018 From: martinrb at google.com (Martin Buchholz) Date: Tue, 6 Mar 2018 18:44:47 -0800 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: <5A9DAE87.8020801@oracle.com> References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> <5A9D8F33.5060500@oracle.com> <5A9DAC84.906@oracle.com> <5A9DAE87.8020801@oracle.com> Message-ID: Thanks Ian and Sherman for the excellent presentation and memories of ancient efforts. Yes, Sherman, I still have vague memory that attempts to touch any implementation detail in this area was asking for trouble and someone would complain. I was happy to let you deal with those problems! There's a continual struggle in the industry to enable more checking at test time, and -Xcheck:jni does look like it should be possible to routinely turn on for running all tests. (Google tests run with a time limit, and so any low-level performance regression immediately causes test failures, for better or worse) Our problem reduces to accessing a primitive array slice from native code. The only way to get O(1) access is via GetPrimitiveArrayCritical, BUT when it fails you have to pay for a copy of the entire array. An obvious solution is to introduce a slice variant GetPrimitiveArrayRegionCritical that would only degrade to a copy of the slice. Offhand that seems relatively easy to implement though we would hold our noses at adding yet more *Critical* functions to the JNI spec. In spirit though it's a straightforward generalization. Implementing Deflater in pure Java seems very reasonable and we've had good success with "nearby" code, but we likely cannot reuse the GNU Classpath code. Thanks for pointing out JDK-6311046: -Xcheck:jni should support checking of GetPrimitiveArrayCritical which went into jdk8 in u40. We can probably be smarter about choosing a better buffer size, e.g. in ZipOutputStream. Here's an idea: In code like this try (DeflaterOutputStream dout = new DeflaterOutputStream(deflated)) { dout.write(inflated, 0, inflated.length); } when the DeflaterOutputStream is given an input that is clearly too large for the current buffer size, reorganize internals dynamically to use a much bigger buffer size. It's possible (but hard work!) to adjust algorithms based on whether critical array access is available. It would be nice if we could get the JVM to tell us (but it might depend, e.g. on the size of the array). From poweruserm at live.com.au Wed Mar 7 03:46:02 2018 From: poweruserm at live.com.au (A Z) Date: Wed, 7 Mar 2018 03:46:02 +0000 Subject: Java SE Language Changes In-Reply-To: References: Message-ID: from Zachary Mitchell ... 'But you seem to be alone on that score.' -People have in fact just quit on this with one language in time. That doesn't mean that valid points don't continue to exist, and mending changes shouldn't happen. I am in fact quite far from alone. 'Basic Java arithmetic won't change.' -I have been told this from Oracle on supposedly technical grounds. However, because there is no way to know when a double or float arithmetic will do this beforehand, and no longer the same direct route to calculate the value, in fact in this region things MUST be changed, and the technical objections are only limited. There can even remain both modes of float and double arithmetic. Just an extra keyword to enforce accuracy arithmetic when requested. Double a = 0.1; Double b = 0.1; Double x = a*b; out.println(x == 0.01) //true 'Back in 1998 the aim was to make Java as appealing as possible to as many kinds of developers as possible so that it would be a success. But the numerics work went nowhere and Java was a success without it...' My polite contention here is that Java is a curtailed or a limited success without certain innate changes, which are real object oversights, ever since Java 1.1. Java 1.2 changed to floating point arithmetic approximation, but did not include a default accuracy mode or an accuracy keyword. Is there any route forward with these changes? JDK-8190947 JDK-8197995 JDK-8190991 From patrick at reini.net Wed Mar 7 10:41:00 2018 From: patrick at reini.net (Patrick Reinhart) Date: Wed, 7 Mar 2018 11:41:00 +0100 Subject: RFR 8196298 Add null Reader and Writer with latest changes In-Reply-To: <5D587382-6466-4854-8C70-68CBC8C7332E@oracle.com> References: <6AF3DEA9-5572-47B1-804E-AD7B0E46D833@reini.net> <3ebd00ec-aa2d-65b9-9f68-0d693628ef2b@oracle.com> <5a9ef0dc.77b0df0a.bb39.cc95@mx.google.com> <5D587382-6466-4854-8C70-68CBC8C7332E@oracle.com> Message-ID: <21DAB782-B121-4117-BBC4-CEA983DC523D@reini.net> I applied those changes here: http://cr.openjdk.java.net/~reinhapa/reviews/8196298/webrev.02 -Patrick > Am 06.03.2018 um 23:12 schrieb Brian Burkhalter : > > Yes, I think so and and also the parameter ?csq' is allowed to be null so Objects.requireNonNull(csq) should be removed at lines 100 and 107 as no NPE is specified for these methods [1, 2]. > > Thanks, > > Brian > > [1] https://download.java.net/java/jdk10/docs/api/java/io/Writer.html#append(java.lang.CharSequence) > [2] https://download.java.net/java/jdk10/docs/api/java/io/Writer.html#append(java.lang.CharSequence,int,int) > > On Mar 6, 2018, at 11:49 AM, Bernd Eckenfels wrote: > >> Just a nit, Should append(CharSequence,int,int) also use checkFromIndexSize? > From aph at redhat.com Wed Mar 7 11:47:50 2018 From: aph at redhat.com (Andrew Haley) Date: Wed, 7 Mar 2018 11:47:50 +0000 Subject: Java SE Language Changes In-Reply-To: References: Message-ID: <4f0bf754-2432-c39e-5073-8051a88ae025@redhat.com> On 07/03/18 03:46, A Z wrote: > Is there any route forward with these changes? I believe not. Java floating-point arithmetic is specified by IEEE-754. If you want something different, Java is not the language you are looking for. -- Andrew Haley Java Platform Lead Engineer Red Hat UK Ltd. EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671 From brian.goetz at oracle.com Wed Mar 7 16:59:15 2018 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 7 Mar 2018 11:59:15 -0500 Subject: Reactive Streams utility API In-Reply-To: References: Message-ID: To answer the questions at the bottom: the next step is to start working on this and get folks excited about contributing.? There's plenty of time for process later, but filing a JEP or creating a project shouldn't be a barrier to innovating. On 2/28/2018 10:33 PM, James Roper wrote: > Hi all, > > We've put together a simple proposal for this. Please read the README for > an introduction to this proposal. > > https://github.com/lightbend/reactive-streams-utils > > Regards, > > James > > On 22 February 2018 at 11:47, James Roper wrote: > >> Hi all, >> >> This is an email to give people a heads up that we'd like to look at >> creating an API, in the same vein as the JDK8 Streams API, for building >> reactive streams (a la JDK9 juc.Flow). Our goals for this are: >> >> * To fill a gap in the JDK where if a developer wants to do even the >> simplest of things with a JDK9 juc.Flow, such as map or filter, they need >> to bring in a third party library that implements that. >> * To produce an API that can build Publishers, Subscribers, Processors, >> and complete graphs, for the purposes of consuming APIs that use reactive >> streams (for example, JDK9 Http Client). >> * To produce an API that aligns closely with ju.stream.Stream, using it >> for inspiration for naming, scope, general API shape, and other aspects. >> The purpose of this goal is to ensure familiarity of Java developers with >> the new API, and to limit the number of concepts Java developers need to >> understand to do the different types of streaming offered by the JDK. >> * To produce an API that can be implemented by multiple providers >> (including an RI in the JDK itself), using the ServiceLoader mechanism to >> provide and load a default implementation (while allowing custom >> implementations to be manually provided). There are a lot of concerns that >> each different streams implementation provides and implements, beyond >> streaming, for example monitoring/tracing, concurrency modelling, buffering >> strategies, performance aspects of the streams handling including fusing, >> and context (eg thread local) propagation. This will allow libraries to use >> and provide contracts based on this API without depending on a particular >> implementation, and allows developers to select the implementation that >> meets their needs. >> >> Non goals: >> >> * To produce a kitchen sink of utilities for working with reactive >> streams. There already exist a number of reactive streams implementations >> that seek to meet this goal (eg, Akka Streams, Reactor, RxJava), and once >> you go past the basics (map, filter, collect), and start dealing with >> things like fan in/out, cycles, restarting, etc, the different approaches >> to solving this start to vary greatly. The JDK should provide enough to be >> useful for typical every day streaming use cases, with developers being >> able to select a third party library for anything more advanced. >> >> We will update this list when we have something ready for public review. >> This probably won't be far off. Our hope is that we can propose this as a >> JEP. >> >> Regards, >> >> James >> >> -- >> *James Roper* >> *Senior Octonaut* >> >> Lightbend ? Build reactive apps! >> Twitter: @jroper >> > > From ekaterina.pavlova at oracle.com Wed Mar 7 18:05:01 2018 From: ekaterina.pavlova at oracle.com (Ekaterina Pavlova) Date: Wed, 7 Mar 2018 10:05:01 -0800 Subject: RFR(XS) [closed] : 8198924: java/lang/StackWalker/LocalsAndOperands.java timeouts with Graal In-Reply-To: <4fcc3671-214a-accd-105b-9aeb83e6e62b@oracle.com> References: <571e551e-f40c-dbf6-0094-4a841fda42a3@oracle.com> <4fcc3671-214a-accd-105b-9aeb83e6e62b@oracle.com> Message-ID: Mandy, Brent, thanks for reviews. Removing @bug will not allow to find this testcase by bugid (jtreg -bug:). So, I think it is safe to omit only @summary. regards, -katya On 3/6/18 2:30 PM, Brent Christian wrote: > Looks good, Katya - thanks. > I agree with omitting @bug and @summary from the second @test tag. > > Thanks, > -Brent > > On 3/6/18 1:59 PM, mandy chung wrote: >> Running #1 and #2 when Graal is enabled is fine. >> >> For the second @test, does it need @bug and @summary to run?? If not, I suggest to take it out as it's already mentioned in the first @test. >> >> Mandy >> >> >> On 3/6/18 1:45 PM, Ekaterina Pavlova wrote: >>> Hi all, >>> >>> java/lang/StackWalker/LocalsAndOperands.java runs LocalsAndOperands 3 times with following set of jvm flags: >>> ?1) -Xint -DtestUnused=true >>> ?2) -Xcomp >>> ?3) -Xcomp -XX:-TieredCompilation >>> >>> When running with Graal as JIT (-XX:+TieredCompilation -XX:+UseJVMCICompiler -Djvmci.Compiler=graal) >>> 3rd scenario could take more than 10 minutes and the test could fail by timeout. >>> Actually running LocalsAndOperands with Graal and with "-Xcomp -XX:-TieredCompilation" doesn't provide >>> big benefit and it would be reasonable to disable this scenario in case Graal is enabled. >>> >>> Please review the change. >>> >>> ????? JBS: https://bugs.openjdk.java.net/browse/JDK-8198924 >>> ?? webrev: http://cr.openjdk.java.net/~epavlova//8198924/webrev.00/index.html >>> >>> ? testing: Tested by running the test in Graal as JIT mode. >>> >>> thanks, >>> -katya >>> >>> p.s. >>> ?Igor Ignatyev volunteered to sponsor this change. >> From irogers at google.com Wed Mar 7 18:16:25 2018 From: irogers at google.com (Ian Rogers) Date: Wed, 07 Mar 2018 18:16:25 +0000 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> <5A9D8F33.5060500@oracle.com> <5A9DAC84.906@oracle.com> <5A9DAE87.8020801@oracle.com> Message-ID: Thanks Martin! Profiling shows most of the time spent in this code is in the call to libz's deflate. I worry that increasing the buffer size increases that work and holds the critical lock for longer. Profiling likely won't show this issue as there's needs to be contention on the GC locker. In HotSpot: http://hg.openjdk.java.net/jdk/jdk/file/2854589fd853/src/hotspot/share/gc/shared/gcLocker.hpp#l34 "Avoid calling these if at all possible" could be taken to suggest that JNI critical regions should also be avoided if at all possible. I think HotSpot and the JDK are out of step if this is the case and there could be work done to remove JNI critical regions from the JDK and replace either with Java code (JITs are better now) or with Get/Set...ArrayRegion. This does appear to be a O(1) to O(n) transition so perhaps the HotSpot folks could speak to it. Thanks, Ian On Tue, Mar 6, 2018 at 6:44 PM Martin Buchholz wrote: > Thanks Ian and Sherman for the excellent presentation and memories of > ancient efforts. > > Yes, Sherman, I still have vague memory that attempts to touch any > implementation detail in this area was asking for trouble and someone would > complain. I was happy to let you deal with those problems! > > There's a continual struggle in the industry to enable more checking at > test time, and -Xcheck:jni does look like it should be possible to > routinely turn on for running all tests. (Google tests run with a time > limit, and so any low-level performance regression immediately causes test > failures, for better or worse) > > Our problem reduces to accessing a primitive array slice from native > code. The only way to get O(1) access is via GetPrimitiveArrayCritical, > BUT when it fails you have to pay for a copy of the entire array. An > obvious solution is to introduce a slice variant GetPrimitiveArrayRegionCritical > that would only degrade to a copy of the slice. Offhand that seems > relatively easy to implement though we would hold our noses at adding yet > more *Critical* functions to the JNI spec. In spirit though it's a > straightforward generalization. > > Implementing Deflater in pure Java seems very reasonable and we've had > good success with "nearby" code, but we likely cannot reuse the GNU > Classpath code. > > Thanks for pointing out > JDK-6311046: -Xcheck:jni should support checking of > GetPrimitiveArrayCritical > which went into jdk8 in u40. > > We can probably be smarter about choosing a better buffer size, e.g. in > ZipOutputStream. > > Here's an idea: In code like this > try (DeflaterOutputStream dout = new DeflaterOutputStream(deflated)) { > dout.write(inflated, 0, inflated.length); > } > when the DeflaterOutputStream is given an input that is clearly too large > for the current buffer size, reorganize internals dynamically to use a much > bigger buffer size. > > It's possible (but hard work!) to adjust algorithms based on whether > critical array access is available. It would be nice if we could get the > JVM to tell us (but it might depend, e.g. on the size of the array). > From brian.burkhalter at oracle.com Wed Mar 7 18:57:01 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 7 Mar 2018 10:57:01 -0800 Subject: RFR 8182684: Further clarify InputStream#available() Message-ID: <3D3C3FC0-D15D-4993-BC91-0379B7D84B2C@oracle.com> https://bugs.openjdk.java.net/browse/JDK-8182684 http://cr.openjdk.java.net/~bpb/8182684/webrev.00/ Unfortunately the change is somewhat obfuscated by reformatting. The main changes are the first sentence and the fourth paragraph. A CSR will follow. Thanks, Brian From brian.burkhalter at oracle.com Wed Mar 7 19:21:53 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 7 Mar 2018 11:21:53 -0800 Subject: RFR 8199258: BigInteger.bitLength() should explicitly specify behavior when the value is zero Message-ID: https://bugs.openjdk.java.net/browse/JDK-8199258 A diff is included below. If this looks good then a CSR will follow. Thanks, Brian --- a/src/java.base/share/classes/java/math/BigInteger.java +++ b/src/java.base/share/classes/java/math/BigInteger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3556,8 +3556,8 @@ * Returns the number of bits in the minimal two's-complement * representation of this BigInteger, excluding a sign bit. * For positive BigIntegers, this is equivalent to the number of bits in - * the ordinary binary representation. (Computes - * {@code (ceil(log2(this < 0 ? -this : this+1)))}.) + * the ordinary binary representation. For zero this method returns + * {@code 0}. (Computes {@code (ceil(log2(this < 0 ? -this : this+1)))}.) * * @return number of bits in the minimal two's-complement * representation of this BigInteger, excluding a sign bit From Roger.Riggs at Oracle.com Wed Mar 7 19:31:21 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Wed, 7 Mar 2018 14:31:21 -0500 Subject: RFR 8199258: BigInteger.bitLength() should explicitly specify behavior when the value is zero In-Reply-To: References: Message-ID: <75eee8fe-72f5-1d0d-fba9-e62dfbc8f707@Oracle.com> +1, looks fine. Roger On 3/7/2018 2:21 PM, Brian Burkhalter wrote: > https://bugs.openjdk.java.net/browse/JDK-8199258 > > A diff is included below. If this looks good then a CSR will follow. > > Thanks, > > Brian > > --- a/src/java.base/share/classes/java/math/BigInteger.java > +++ b/src/java.base/share/classes/java/math/BigInteger.java > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. > + * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. > * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. > * > * This code is free software; you can redistribute it and/or modify it > @@ -3556,8 +3556,8 @@ > * Returns the number of bits in the minimal two's-complement > * representation of this BigInteger, excluding a sign bit. > * For positive BigIntegers, this is equivalent to the number of bits in > - * the ordinary binary representation. (Computes > - * {@code (ceil(log2(this < 0 ? -this : this+1)))}.) > + * the ordinary binary representation. For zero this method returns > + * {@code 0}. (Computes {@code (ceil(log2(this < 0 ? -this : this+1)))}.) > * > * @return number of bits in the minimal two's-complement > * representation of this BigInteger, excluding a sign bit From lance.andersen at oracle.com Wed Mar 7 19:35:45 2018 From: lance.andersen at oracle.com (Lance Andersen) Date: Wed, 7 Mar 2018 14:35:45 -0500 Subject: RFR 8199258: BigInteger.bitLength() should explicitly specify behavior when the value is zero In-Reply-To: References: Message-ID: <89ACD7B9-07F1-4127-98B7-D295330A579B@oracle.com> looks fine > On Mar 7, 2018, at 2:21 PM, Brian Burkhalter wrote: > > https://bugs.openjdk.java.net/browse/JDK-8199258 > > A diff is included below. If this looks good then a CSR will follow. > > Thanks, > > Brian > > --- a/src/java.base/share/classes/java/math/BigInteger.java > +++ b/src/java.base/share/classes/java/math/BigInteger.java > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. > + * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. > * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. > * > * This code is free software; you can redistribute it and/or modify it > @@ -3556,8 +3556,8 @@ > * Returns the number of bits in the minimal two's-complement > * representation of this BigInteger, excluding a sign bit. > * For positive BigIntegers, this is equivalent to the number of bits in > - * the ordinary binary representation. (Computes > - * {@code (ceil(log2(this < 0 ? -this : this+1)))}.) > + * the ordinary binary representation. For zero this method returns > + * {@code 0}. (Computes {@code (ceil(log2(this < 0 ? -this : this+1)))}.) > * > * @return number of bits in the minimal two's-complement > * representation of this BigInteger, excluding a sign bit Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From roger.riggs at oracle.com Wed Mar 7 19:52:05 2018 From: roger.riggs at oracle.com (Roger Riggs) Date: Wed, 7 Mar 2018 14:52:05 -0500 Subject: RFR 8182684: Further clarify InputStream#available() In-Reply-To: <3D3C3FC0-D15D-4993-BC91-0379B7D84B2C@oracle.com> References: <3D3C3FC0-D15D-4993-BC91-0379B7D84B2C@oracle.com> Message-ID: <0092dbce-f432-2c06-1d99-ccc8e2cb81a7@oracle.com> +1, Thanks, Roger On 3/7/18 1:57 PM, Brian Burkhalter wrote: > https://bugs.openjdk.java.net/browse/JDK-8182684 > http://cr.openjdk.java.net/~bpb/8182684/webrev.00/ > > Unfortunately the change is somewhat obfuscated by reformatting. The main changes are the first sentence and the fourth paragraph. > > A CSR will follow. > > Thanks, > > Brian From joe.darcy at oracle.com Wed Mar 7 20:35:51 2018 From: joe.darcy at oracle.com (joe darcy) Date: Wed, 7 Mar 2018 12:35:51 -0800 Subject: Floating Point and Arithmetic Changes for Java SE Lnguage In-Reply-To: References: Message-ID: <5d829ac2-3a69-15e7-edb9-dbb65485274a@oracle.com> Legend has it that after the ancient Greek Hippasus shared with his fellow travelers the elegant proof [1] that the square root of 2 is not a rational number, he was thrown off the ship by Pythagoreans outraged that such numbers should exist. Hippasus subsequently drowned. Whatever catharsis was released by his death did not change the fact that mathematically sqrt(2) cannot be exactly represented by the ratio of two integers. Rational numbers are simple and elegant. However, in many areas we cannot limit ourselves to dealing with rational numbers since values like sqrt(2) cannot be accommodated. To greatly abbreviate the development of different kinds of numbers, real numbers are commonly used, despite their complexities, since they contain their limits, meaning that transcendental values like pi are inside the system. Floating-point arithmetic is a systematic approximation to real arithmetic, an approximation with pragmatic compromises to facilitate calculation on computers. Floating-point numbers can represent numbers over vast scales and are (typically) fixed-sized. These aspects of floating-point arithmetic force most field axioms to fail to hold, field axioms being the familiar properties of arithmetic such as addition being associative ((a+b) + c == a + (b+c)). Other fixed-size approximations that have been explored, such as fixed-slash and floating-slash arithmetic, have been found to have worse computational shortcomings than floating-point arithmetic. It is true that using a binary floating-point representation rather than a decimal floating-point representation can cause additional surprises since 1/10 is not exactly representable in binary. However, all the field axioms that fail to hold for binary floating-point arithmetic also fail to hold for decimal floating-point arithmetic. In addition, the distances between adjacent decimal numbers makes a larger relative jump (ten-fold) across exponent boundaries than for binary (doubling). The IEEE 754-2008 standard incorporated decimal arithmetic into an update of the 1985 version of the standard. This included fixed-size 64 and 128 bit decimal formats, amenable for hardware support. However, few architectures have added such support. Moreover, the roundoff errors from floating-point computation are only one source of errors in a computation. *Even if arithmetic were done exactly, numerical analysis would still be needed.* As numerical analyst Nick Trefethen has said "If rounding errors vanished, 95% of numerical analysis would remain." For example, exact arithmetic does not remove modeling error, where the model does have sufficient fidelity with reality. Many calculations involve sums of an infinite number of decreasing terms so truncation errors occurs for the tail of the total sum once the terms are no longer included. The bugs have you filed and the emails you have sent to this alias are all known situations and have all received responses: ??? JDK-8190947 -- Insufficient arithmetic Behaviour ??? Closed -- will not fix, including citations to additional explanations of floating-point. ??? JDK-8197995 - BigDecimal and BigInteger Defaulting Behaviour ??? Closed -- not an issue, long-existing documentation describes exactly how to avoid the reported problem. ??? JDK-8190991 - Forward and Inverse operations accuracy. ??? Closed -- not an issue. With fixed-precision, it is not possible to invert operations over the entire domain,??? as previously discussed on this list http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-December/050393.html. ??? JDK-8190946 - There is no elementary functions support for BigDecimal and BigInteger. ??? Closed as a duplicate of? JDK-4297957, which in turn was created in 1999 and closed as will not fix in 2006. Repeatedly ignoring these responses and the reasons given for them will not make advancing your cause easier and wastes the time of those crafting the replies. To examine a few of these more closely, for JDK-8190991: "Forward and Inverse operations accuracy" the responses give examples where for a fixed-precision result, the function cannot be exacted inverted even in the case where the true function is monotonically increasing (where it is defined), like square root. The concrete example previously sent to core libs: sqrt on the domain [1, 2) is in the range [1, ~1.4). From the pigeon-hole principle, this cannot be in inverted in the same precision since (of necessity) multiple elements of the domain map to the same element in the domain. In fact, a majority of elements of range must have two or more corresponding domain elements. For JDK-8190946: "There is no elementary functions support for BigDecimal and BigInteger", it is a true observation that BigDecimal and BigInteger offer few elementary math functions, many fewer functions than are supported for double in java.lang.{Math, StrictMath}. It is also true that a larger suite of math library methods for BigDecimal would be useful to some users. However, the mere fact that a set of new library methods would be useful for some users is *not* sufficient cause to have the JDK team work to develop, test, and maintain such a library. It is perfectly acceptable and in many ways preferable for limited-use libraries to be developed outside of the JDK and not shipped as part of the JDK. One of the use-cases for the value type changes being worked on in Project Valhalla is lower-overhead for numerical types, such as BigDecimal and BigInteger and potential classes like complex, etc. IMO, it would also be reasonable to have syntactic support for operators on such types. There are no prospects for a fundamental redefinition of the floating-point semantics of the Java language and VM. It is possible a faster and looser mode will be defined at some point, but altering the default is extremely unlikely. Long-term, decimal-based arithmetic (and other kinds of arithmetic) may get better support as a consequence of the features in Valhalla. Filing additional bugs or additional emails to this alias will not change any of this or make it happen faster. A few notes on what this mailing list is and is not. This list and other lists under of the OpenJDK umbrella are forums for people participating in OpenJDK development and who want to be informed about OpenJDK development. These lists are not a free support channel. These lists are not a forum to drop in, issue demands for large projects without so much as an offer of assistance, and then check back a few months later to see why more progress hasn't been made. -Joe [1] Assume sqrt(2) is a rational in lowest terms, p/q. Then, by definition, 2 = (p^2)/(q^2) and therefor 2(q^2) = p^2. Consequently p^2 is even which implies p is even as well. Let r = p/2; r is an integer. p^2 = (2r)^2 = 4r^2. Substituting, 2(q^2) = 4(r^2), reducing q^2 = 2(r^2). Therefore, q^2 is even and q is even as well. However, we have reached a contradiction. If both p and q are even, then p/q is *not* in lowest terms. Therefore, there is no rational number which is the square root of 2. From neugens.limasoftware at gmail.com Wed Mar 7 22:19:02 2018 From: neugens.limasoftware at gmail.com (Mario Torre) Date: Wed, 07 Mar 2018 22:19:02 +0000 Subject: Floating Point and Arithmetic Changes for Java SE Lnguage In-Reply-To: <5d829ac2-3a69-15e7-edb9-dbb65485274a@oracle.com> References: <5d829ac2-3a69-15e7-edb9-dbb65485274a@oracle.com> Message-ID: I don?t remember ever having read another reply to this mailing list with so much interest in years! Cheers, Mario On Wed 7. Mar 2018 at 21:36, joe darcy wrote: > Legend has it that after the ancient Greek Hippasus shared with his > fellow travelers the elegant proof [1] that the square root of 2 is not > a rational number, he was thrown off the ship by Pythagoreans outraged > that such numbers should exist. Hippasus subsequently drowned. Whatever > catharsis was released by his death did not change the fact that > mathematically sqrt(2) cannot be exactly represented by the ratio of two > integers. > > Rational numbers are simple and elegant. However, in many areas we > cannot limit ourselves to dealing with rational numbers since values > like sqrt(2) cannot be accommodated. To greatly abbreviate the > development of different kinds of numbers, real numbers are commonly > used, despite their complexities, since they contain their limits, > meaning that transcendental values like pi are inside the system. > > Floating-point arithmetic is a systematic approximation to real > arithmetic, an approximation with pragmatic compromises to facilitate > calculation on computers. Floating-point numbers can represent numbers > over vast scales and are (typically) fixed-sized. These aspects of > floating-point arithmetic force most field axioms to fail to hold, field > axioms being the familiar properties of arithmetic such as addition > being associative ((a+b) + c == a + (b+c)). > > Other fixed-size approximations that have been explored, such as > fixed-slash and floating-slash arithmetic, have been found to have worse > computational shortcomings than floating-point arithmetic. > > It is true that using a binary floating-point representation rather than > a decimal floating-point representation can cause additional surprises > since 1/10 is not exactly representable in binary. However, all the > field axioms that fail to hold for binary floating-point arithmetic also > fail to hold for decimal floating-point arithmetic. In addition, the > distances between adjacent decimal numbers makes a larger relative jump > (ten-fold) across exponent boundaries than for binary (doubling). > > The IEEE 754-2008 standard incorporated decimal arithmetic into an > update of the 1985 version of the standard. This included fixed-size 64 > and 128 bit decimal formats, amenable for hardware support. However, few > architectures have added such support. > > Moreover, the roundoff errors from floating-point computation are only > one source of errors in a computation. *Even if arithmetic were done > exactly, numerical analysis would still be needed.* As numerical analyst > Nick Trefethen has said "If rounding errors vanished, 95% of numerical > analysis would remain." For example, exact arithmetic does not remove > modeling error, where the model does have sufficient fidelity with > reality. Many calculations involve sums of an infinite number of > decreasing terms so truncation errors occurs for the tail of the total > sum once the terms are no longer included. > > The bugs have you filed and the emails you have sent to this alias are > all known situations and have all received responses: > > JDK-8190947 -- Insufficient arithmetic Behaviour > Closed -- will not fix, including citations to additional > explanations of floating-point. > > JDK-8197995 - BigDecimal and BigInteger Defaulting Behaviour > Closed -- not an issue, long-existing documentation describes > exactly how to avoid the reported problem. > > JDK-8190991 - Forward and Inverse operations accuracy. > Closed -- not an issue. With fixed-precision, it is not possible to > invert operations over the entire domain, as previously discussed on > this list > > http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-December/050393.html > . > > JDK-8190946 - There is no elementary functions support for > BigDecimal and BigInteger. > Closed as a duplicate of JDK-4297957, which in turn was created in > 1999 and closed as will not fix in 2006. > > Repeatedly ignoring these responses and the reasons given for them will > not make advancing your cause easier and wastes the time of those > crafting the replies. > > To examine a few of these more closely, for JDK-8190991: "Forward and > Inverse operations accuracy" the responses give examples where for a > fixed-precision result, the function cannot be exacted inverted even in > the case where the true function is monotonically increasing (where it > is defined), like square root. The concrete example previously sent to > core libs: sqrt on the domain [1, 2) is in the range [1, ~1.4). From the > pigeon-hole principle, this cannot be in inverted in the same precision > since (of necessity) multiple elements of the domain map to the same > element in the domain. In fact, a majority of elements of range must > have two or more corresponding domain elements. > > For JDK-8190946: "There is no elementary functions support for > BigDecimal and BigInteger", it is a true observation that BigDecimal and > BigInteger offer few elementary math functions, many fewer functions > than are supported for double in java.lang.{Math, StrictMath}. It is > also true that a larger suite of math library methods for BigDecimal > would be useful to some users. However, the mere fact that a set of new > library methods would be useful for some users is *not* sufficient cause > to have the JDK team work to develop, test, and maintain such a library. > It is perfectly acceptable and in many ways preferable for limited-use > libraries to be developed outside of the JDK and not shipped as part of > the JDK. > > One of the use-cases for the value type changes being worked on in > Project Valhalla is lower-overhead for numerical types, such as > BigDecimal and BigInteger and potential classes like complex, etc. IMO, > it would also be reasonable to have syntactic support for operators on > such types. > > There are no prospects for a fundamental redefinition of the > floating-point semantics of the Java language and VM. It is possible a > faster and looser mode will be defined at some point, but altering the > default is extremely unlikely. Long-term, decimal-based arithmetic (and > other kinds of arithmetic) may get better support as a consequence of > the features in Valhalla. Filing additional bugs or additional emails to > this alias will not change any of this or make it happen faster. > > A few notes on what this mailing list is and is not. This list and other > lists under of the OpenJDK umbrella are forums for people participating > in OpenJDK development and who want to be informed about OpenJDK > development. These lists are not a free support channel. These lists are > not a forum to drop in, issue demands for large projects without so much > as an offer of assistance, and then check back a few months later to see > why more progress hasn't been made. > > -Joe > > [1] Assume sqrt(2) is a rational in lowest terms, p/q. Then, by > definition, 2 = (p^2)/(q^2) and therefor 2(q^2) = p^2. Consequently p^2 > is even which implies p is even as well. Let r = p/2; r is an integer. > p^2 = (2r)^2 = 4r^2. Substituting, 2(q^2) = 4(r^2), reducing q^2 = > 2(r^2). Therefore, q^2 is even and q is even as well. However, we have > reached a contradiction. If both p and q are even, then p/q is *not* in > lowest terms. Therefore, there is no rational number which is the square > root of 2. > From rachna.goel at oracle.com Thu Mar 8 11:56:39 2018 From: rachna.goel at oracle.com (Rachna Goel) Date: Thu, 8 Mar 2018 17:26:39 +0530 Subject: [11] RFR: 8191410 : Unicode 10.0.0 Message-ID: Hi, Please review the proposed changes for JDK-819410. Bug : https://bugs.openjdk.java.net/browse/JDK-8191410 proposed changeset is located at : http://cr.openjdk.java.net/~rgoel/JDK-8191410/webrev/ This serves as the implementation for JEP 327. -- Thanks, Rachna From Alan.Bateman at oracle.com Thu Mar 8 15:49:56 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 8 Mar 2018 15:49:56 +0000 Subject: RFR 8182684: Further clarify InputStream#available() In-Reply-To: <3D3C3FC0-D15D-4993-BC91-0379B7D84B2C@oracle.com> References: <3D3C3FC0-D15D-4993-BC91-0379B7D84B2C@oracle.com> Message-ID: <02365d6b-1acb-224d-a24e-08cba091b9dd@oracle.com> On 07/03/2018 18:57, Brian Burkhalter wrote: > https://bugs.openjdk.java.net/browse/JDK-8182684 > http://cr.openjdk.java.net/~bpb/8182684/webrev.00/ > > Unfortunately the change is somewhat obfuscated by reformatting. The main changes are the first sentence and the fourth paragraph. > > Looks good okay it doesn't really change anything as available has always been allowed to return 0, even if not at end of input. -Alan From Roger.Riggs at Oracle.com Thu Mar 8 16:17:44 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 8 Mar 2018 11:17:44 -0500 Subject: [11] RFR: 8191410 : Unicode 10.0.0 In-Reply-To: References: Message-ID: Hi Rachna, sun/text/normalizer/NormalizerImpl.java: Is there a higher level description of the algorithmic changes? 102-105:?? These look like accidental changes: the space should not be removed and the trailing "{" doesn't make sense in a comment. Regards, Roger On 3/8/2018 6:56 AM, Rachna Goel wrote: > Hi, > > Please review the proposed changes for JDK-819410. > > Bug : https://bugs.openjdk.java.net/browse/JDK-8191410 > > proposed changeset is located at : > > http://cr.openjdk.java.net/~rgoel/JDK-8191410/webrev/ > > This serves as the implementation for JEP 327. > From ivan.gerasimov at oracle.com Thu Mar 8 18:52:27 2018 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Thu, 8 Mar 2018 10:52:27 -0800 Subject: [11] RFR: 8191410 : Unicode 10.0.0 In-Reply-To: References: Message-ID: Hi Rachna! Just minor comments: You may want to update the initial capacity for the HashMaps: 1) private static Map map = new HashMap<>((int)(638 / 0.75f + 1.0f)); (the number 638 was determined as `cat Character.java | grep -A 2 'new UnicodeBlock' | grep '"' | wc -l`) 2) aliases = new HashMap<>((int)(142 / 0.75f + 1.0f)); (the number 142 was determined as `cat Character.java | grep '\saliases.put' | wc -l`) Also, I noticed that Character.java has got trailing spaces at some lines (e.g. at the line 2938). I assume these can be caught by `hg jcheck`. With kind regards, Ivan On 3/8/18 3:56 AM, Rachna Goel wrote: > Hi, > > Please review the proposed changes for JDK-819410. > > Bug : https://bugs.openjdk.java.net/browse/JDK-8191410 > > proposed changeset is located at : > > http://cr.openjdk.java.net/~rgoel/JDK-8191410/webrev/ > > This serves as the implementation for JEP 327. > -- With kind regards, Ivan Gerasimov From brian.goetz at oracle.com Thu Mar 8 21:46:09 2018 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 8 Mar 2018 16:46:09 -0500 Subject: Floating Point and Arithmetic Changes for Java SE Lnguage In-Reply-To: <5d829ac2-3a69-15e7-edb9-dbb65485274a@oracle.com> References: <5d829ac2-3a69-15e7-edb9-dbb65485274a@oracle.com> Message-ID: > One of the use-cases for the value type changes being worked on in > Project Valhalla is lower-overhead for numerical types, such as > BigDecimal and BigInteger and potential classes like complex, etc. > IMO, it would also be reasonable to have syntactic support for > operators on such types. > > There are no prospects for a fundamental redefinition of the > floating-point semantics of the Java language and VM. It is possible a > faster and looser mode will be defined at some point, but altering the > default is extremely unlikely. Long-term, decimal-based arithmetic > (and other kinds of arithmetic) may get better support as a > consequence of the features in Valhalla. Filing additional bugs or > additional emails to this alias will not change any of this or make it > happen faster. For those who are not aware of what's going on in Project Valhalla... There is an obvious gap between primitive and reference types in Java.? The primitive types we have are fixed and we effectively cannot make more.? This makes many people sad, as they would like to have their favorite numeric type built into the platform.? As Guy Steele taught us in Growing a Language, adding every possible numeric type into a language that some user might find useful is a losing game; you want to be able to write these as ordinary user-written libraries instead. Java makes it easy to write libraries, but classes have an inherent performance cost, because of their pervasive object identity (even when it is not actually needed, in so-called "value-based classes.")? I can easily write a complex or unsigned 64 bit int or 37-bit BCD numeric class, and give it all the operations I want, but because instances of objects are stored in the heap, they will come at a performance disadvantage, in space and time, to primitives. Project Valhalla's solution is: value types.? Value types are like classes in that they can have fields, methods, constructors, type variables, implement interfaces, and many of the other characteristics of a class, but are like primitives in that they are laid out flat and dense in memory -- no object header, no indirection.? So an array of Complex would be laid out re/im/re/im, rather than as a sequence of pointers to [ re, im ] boxes.? "Codes like a class, works like an int." Value types let us write new numeric (and other) types as library classes, and get the performance characteristics of primitives. Users will be able to write their 37-bit BCD classes as plain library code, and will not have to beg the Java maintainers for fundamental (and effectively impossible) changes to satisfy their specific numeric needs. Project Valhalla has been rolling for a few years, and will likely go for a few more until we reach the point where this is practical -- and more after that before value types can fit cleanly into the generic type system.? Its a big project, into which Oracle (and IBM, and Red Hat) have already made substantial investments.?? We invite others who have the requisite skills to join us; right now most of the work is going on in the interpreter and JIT.? The language work will follow, and the library work will follow that. From claes.redestad at oracle.com Fri Mar 9 11:42:57 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 9 Mar 2018 12:42:57 +0100 Subject: RFR: 8199009: test/jdk/java/util/Locale/SoftKeys.java fails with OutOfMemoryError Message-ID: <43f117e1-5714-ce3b-75a6-67f826030d23@oracle.com> Hi, the stress test I introduced together with JDK-8196869 to guard against introducing NPE issues in the Locale cache handling has been shown to fail with OOME on some very particular machine configurations. Experiments show that we could make such OOMEs easily go away by increasing the heap size in the test to allow GC to keep up, but then the test will no longer reliably reproduce the NPE issues the test was designed to guard against. I think the best we can do is to ignore the OOMEs in this particular stress test (which runs reliably on almost all of our test systems): http://cr.openjdk.java.net/~redestad/8199009/jdk.00/ Bugs: https://bugs.openjdk.java.net/browse/JDK-8199009 Another option would be to remove the test, since it's "only" testing for a very particular coding error that I was about to commit when working on JDK-8196869.. Thanks! /Claes From david.lloyd at redhat.com Fri Mar 9 15:11:38 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Fri, 9 Mar 2018 09:11:38 -0600 Subject: [JDK-6341887] RFR: Patch V4: java.util.zip: Add ByteBuffer methods to Inflater/Deflater Message-ID: The fourth version of this patch is attached. There is one functional change; the rest are documentation changes. The functional change is that Inflater now updates both the input and output buffer position, as well as the produced/consumed byte count and remaining count, in the event of a DataFormatException. The documentation changes reflect this change. An online version of this patch can be found here [1]. [1] https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v12 -- - DML -------------- next part -------------- commit 48f02037c6958828c41579748827134f1d6b58e9 Author: David M. Lloyd Date: Fri Feb 16 11:00:10 2018 -0600 [JDK-6341887] Update Inflater/Deflater to handle ByteBuffer diff --git a/make/mapfiles/libzip/mapfile-vers b/make/mapfiles/libzip/mapfile-vers index d711d8e17f4..11ccc2d6ecb 100644 --- a/make/mapfiles/libzip/mapfile-vers +++ b/make/mapfiles/libzip/mapfile-vers @@ -33,20 +33,28 @@ SUNWprivate_1.1 { Java_java_util_zip_CRC32_update; Java_java_util_zip_CRC32_updateBytes0; Java_java_util_zip_CRC32_updateByteBuffer0; - Java_java_util_zip_Deflater_deflateBytes; + Java_java_util_zip_Deflater_deflateBytesBytes; + Java_java_util_zip_Deflater_deflateBytesBuffer; + Java_java_util_zip_Deflater_deflateBufferBytes; + Java_java_util_zip_Deflater_deflateBufferBuffer; Java_java_util_zip_Deflater_end; Java_java_util_zip_Deflater_getAdler; Java_java_util_zip_Deflater_init; Java_java_util_zip_Deflater_initIDs; Java_java_util_zip_Deflater_reset; Java_java_util_zip_Deflater_setDictionary; + Java_java_util_zip_Deflater_setDictionaryBuffer; Java_java_util_zip_Inflater_end; Java_java_util_zip_Inflater_getAdler; - Java_java_util_zip_Inflater_inflateBytes; + Java_java_util_zip_Inflater_inflateBytesBytes; + Java_java_util_zip_Inflater_inflateBytesBuffer; + Java_java_util_zip_Inflater_inflateBufferBytes; + Java_java_util_zip_Inflater_inflateBufferBuffer; Java_java_util_zip_Inflater_init; Java_java_util_zip_Inflater_initIDs; Java_java_util_zip_Inflater_reset; Java_java_util_zip_Inflater_setDictionary; + Java_java_util_zip_Inflater_setDictionaryBuffer; ZIP_Close; ZIP_CRC32; ZIP_FreeEntry; diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java b/src/java.base/share/classes/java/util/zip/Deflater.java index c75dd4a33f0..40f0d9736e2 100644 --- a/src/java.base/share/classes/java/util/zip/Deflater.java +++ b/src/java.base/share/classes/java/util/zip/Deflater.java @@ -26,7 +26,13 @@ package java.util.zip; import java.lang.ref.Cleaner.Cleanable; +import java.lang.ref.Reference; +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; +import java.util.Objects; + import jdk.internal.ref.CleanerFactory; +import sun.nio.ch.DirectBuffer; /** * This class provides support for general purpose compression using the @@ -92,8 +98,9 @@ import jdk.internal.ref.CleanerFactory; public class Deflater { private final DeflaterZStreamRef zsRef; - private byte[] buf = new byte[0]; - private int off, len; + private ByteBuffer input = ZipUtils.defaultBuf; + private byte[] inputArray; + private int inputPos, inputLim; private int level, strategy; private boolean setParams; private boolean finish, finished; @@ -170,9 +177,14 @@ public class Deflater { */ public static final int FULL_FLUSH = 3; + /** + * Flush mode to use at the end of output. Can only be provided by the + * user by way of {@link #finish()}. + */ + private static final int FINISH = 4; + static { ZipUtils.loadLibrary(); - initIDs(); } /** @@ -216,16 +228,14 @@ public class Deflater { * @see Deflater#needsInput */ public void setInput(byte[] b, int off, int len) { - if (b== null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { - this.buf = b; - this.off = off; - this.len = len; + this.input = null; + this.inputArray = b; + this.inputPos = off; + this.inputLim = off + len; } } @@ -239,6 +249,31 @@ public class Deflater { setInput(b, 0, b.length); } + /** + * Sets input data for compression. This should be called whenever + * needsInput() returns true indicating that more input data is required. + *

+ * The given buffer's position will be updated as deflate operations are + * performed. The input buffer may be modified (refilled) between deflate + * operations; doing so is equivalent to creating a new buffer and setting + * it with this method. + *

+ * Modifying the input buffer's contents, position, or limit concurrently with + * a deflate operation will result in undefined behavior, which may include + * incorrect operation results or operation failure. + * + * @param byteBuffer the input data bytes + * @see Deflater#needsInput + * @since 11 + */ + public void setInput(ByteBuffer byteBuffer) { + Objects.requireNonNull(byteBuffer); + synchronized (zsRef) { + this.input = byteBuffer; + this.inputArray = null; + } + } + /** * Sets preset dictionary for compression. A preset dictionary is used * when the history buffer can be predetermined. When the data is later @@ -252,9 +287,6 @@ public class Deflater { * @see Inflater#getAdler */ public void setDictionary(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } @@ -278,6 +310,41 @@ public class Deflater { setDictionary(b, 0, b.length); } + /** + * Sets preset dictionary for compression. A preset dictionary is used + * when the history buffer can be predetermined. When the data is later + * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called + * in order to get the Adler-32 value of the dictionary required for + * decompression. + *

+ * The bytes in given byte buffer will be fully consumed by this method. On + * return, its position will equal its limit. + * + * @param byteBuffer the dictionary data bytes + * @see Inflater#inflate + * @see Inflater#getAdler + */ + public void setDictionary(ByteBuffer byteBuffer) { + synchronized (zsRef) { + final int position = byteBuffer.position(); + final int remaining = Math.max(byteBuffer.limit() - position, 0); + ensureOpen(); + if (byteBuffer.isDirect()) { + final long address = ((DirectBuffer) byteBuffer).address(); + try { + setDictionaryBuffer(zsRef.address(), address + position, remaining); + } finally { + Reference.reachabilityFence(byteBuffer); + } + } else { + final byte[] array = ZipUtils.getBufferArray(byteBuffer); + final int offset = ZipUtils.getBufferOffset(byteBuffer); + setDictionary(zsRef.address(), array, offset + position, remaining); + } + byteBuffer.position(position + remaining); + } + } + /** * Sets the compression strategy to the specified value. * @@ -331,14 +398,17 @@ public class Deflater { } /** - * Returns true if the input data buffer is empty and setInput() - * should be called in order to provide more input. + * Returns true if no data remains in the input buffer. This can + * be used to determine if one of the {@code setInput()} methods should be + * called in order to provide more input. + * * @return true if the input data buffer is empty and setInput() * should be called in order to provide more input */ public boolean needsInput() { synchronized (zsRef) { - return len <= 0; + final ByteBuffer input = this.input; + return input == null ? inputLim == inputPos : ! input.hasRemaining(); } } @@ -404,6 +474,26 @@ public class Deflater { return deflate(b, 0, b.length, NO_FLUSH); } + /** + * Compresses the input data and fills specified buffer with compressed + * data. Returns actual number of bytes of compressed data. A return value + * of 0 indicates that {@link #needsInput() needsInput} should be called + * in order to determine if more input data is required. + * + *

This method uses {@link #NO_FLUSH} as its compression flush mode. + * An invocation of this method of the form {@code deflater.deflate(output)} + * yields the same result as the invocation of + * {@code deflater.deflate(output, Deflater.NO_FLUSH)}. + * + * @param output the buffer for the compressed data + * @return the actual number of bytes of compressed data written to the + * output buffer + * @since 11 + */ + public int deflate(ByteBuffer output) { + return deflate(output, NO_FLUSH); + } + /** * Compresses the input data and fills the specified buffer with compressed * data. Returns actual number of bytes of data compressed. @@ -441,6 +531,10 @@ public class Deflater { * repeatedly output to the output buffer every time this method is * invoked. * + *

If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation. + * * @param b the buffer for the compressed data * @param off the start offset of the data * @param len the maximum number of bytes of compressed data @@ -452,24 +546,247 @@ public class Deflater { * @since 1.7 */ public int deflate(byte[] b, int off, int len, int flush) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } + if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) { + throw new IllegalArgumentException(); + } synchronized (zsRef) { ensureOpen(); - if (flush == NO_FLUSH || flush == SYNC_FLUSH || - flush == FULL_FLUSH) { - int thisLen = this.len; - int n = deflateBytes(zsRef.address(), b, off, len, flush); - bytesWritten += n; - bytesRead += (thisLen - this.len); - return n; + + final ByteBuffer input = this.input; + if (finish) { + // disregard given flush mode in this case + flush = FINISH; + } + final int params; + if (setParams) { + // bit 0: true to set params + // bit 1-2: strategy (0, 1, or 2) + // bit 3-31: level (0..9 or -1) + params = 1 | strategy << 1 | level << 3; + } else { + params = 0; + } + final int inputPos; + final long result; + if (input == null) { + inputPos = this.inputPos; + result = deflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + b, off, len, + flush, params); + } else { + inputPos = input.position(); + final int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + try { + final long inputAddress = ((DirectBuffer) input).address(); + result = deflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + b, off, len, + flush, params); + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + b, off, len, + flush, params); + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if (params != 0 && (result >>> 63 & 1) == 0) { + setParams = false; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; } + bytesWritten += written; + bytesRead += read; + return written; + } + } + + /** + * Compresses the input data and fills the specified buffer with compressed + * data. Returns actual number of bytes of data compressed. + * + *

Compression flush mode is one of the following three modes: + * + *

    + *
  • {@link #NO_FLUSH}: allows the deflater to decide how much data + * to accumulate, before producing output, in order to achieve the best + * compression (should be used in normal use scenario). A return value + * of 0 in this flush mode indicates that {@link #needsInput()} should + * be called in order to determine if more input data is required. + * + *
  • {@link #SYNC_FLUSH}: all pending output in the deflater is flushed, + * to the specified output buffer, so that an inflater that works on + * compressed data can get all input data available so far (In particular + * the {@link #needsInput()} returns {@code true} after this invocation + * if enough output space is provided). Flushing with {@link #SYNC_FLUSH} + * may degrade compression for some compression algorithms and so it + * should be used only when necessary. + * + *
  • {@link #FULL_FLUSH}: all pending output is flushed out as with + * {@link #SYNC_FLUSH}. The compression state is reset so that the inflater + * that works on the compressed output data can restart from this point + * if previous compressed data has been damaged or if random access is + * desired. Using {@link #FULL_FLUSH} too often can seriously degrade + * compression. + *
+ * + *

In the case of {@link #FULL_FLUSH} or {@link #SYNC_FLUSH}, if + * the return value is {@code len}, the space available in output + * buffer {@code output}, this method should be invoked again with the same + * {@code flush} parameter and more output space. Make sure that + * {@code len} is greater than 6 to avoid flush marker (5 bytes) being + * repeatedly output to the output buffer every time this method is + * invoked. + * + *

On success, the position of the given {@code output} byte buffer will be + * advanced by as many bytes as were produced by the operation, which is equal + * to the number returned by this method. + * + *

If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation. + * + * @param output the buffer for the compressed data + * @param flush the compression flush mode + * @return the actual number of bytes of compressed data written to + * the output buffer + * + * @throws IllegalArgumentException if the flush mode is invalid + * @since 11 + */ + public int deflate(ByteBuffer output, int flush) { + if (output.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) { throw new IllegalArgumentException(); } + synchronized (zsRef) { + ensureOpen(); + + final ByteBuffer input = this.input; + if (finish) { + // disregard given flush mode in this case + flush = FINISH; + } + final int params; + if (setParams) { + // bit 0: true to set params + // bit 1-2: strategy (0, 1, or 2) + // bit 3-31: level (0..9 or -1) + params = 1 | strategy << 1 | level << 3; + } else { + params = 0; + } + final int outputPos = output.position(); + final int outputRem = Math.max(output.limit() - outputPos, 0); + final int inputPos; + final long result; + if (input == null) { + inputPos = this.inputPos; + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = deflateBytesBuffer(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputAddress + outputPos, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } else { + inputPos = input.position(); + final int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + final long inputAddress = ((DirectBuffer) input).address(); + try { + if (output.isDirect()) { + final long outputAddress = outputPos + ((DirectBuffer) output).address(); + try { + result = deflateBufferBuffer(zsRef.address(), + inputAddress + inputPos, inputRem, + outputAddress, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = deflateBytesBuffer(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputAddress + outputPos, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if (params != 0 && (result >>> 63 & 1) == 0) { + setParams = false; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + output.position(outputPos + written); + bytesWritten += written; + bytesRead += read; + return written; + } } /** @@ -545,7 +862,8 @@ public class Deflater { reset(zsRef.address()); finish = false; finished = false; - off = len = 0; + input = ZipUtils.defaultBuf; + inputArray = null; bytesRead = bytesWritten = 0; } } @@ -560,7 +878,7 @@ public class Deflater { public void end() { synchronized (zsRef) { zsRef.clean(); - buf = null; + input = ZipUtils.defaultBuf; } } @@ -585,11 +903,26 @@ public class Deflater { throw new NullPointerException("Deflater has been closed"); } - private static native void initIDs(); private static native long init(int level, int strategy, boolean nowrap); - private static native void setDictionary(long addr, byte[] b, int off, int len); - private native int deflateBytes(long addr, byte[] b, int off, int len, - int flush); + private static native void setDictionary(long addr, byte[] b, int off, + int len); + private static native void setDictionaryBuffer(long addr, long bufAddress, int len); + private native long deflateBytesBytes(long addr, + byte[] inputArray, int inputOff, int inputLen, + byte[] outputArray, int outputOff, int outputLen, + int flush, int params); + private native long deflateBytesBuffer(long addr, + byte[] inputArray, int inputOff, int inputLen, + long outputAddress, int outputLen, + int flush, int params); + private native long deflateBufferBytes(long addr, + long inputAddress, int inputLen, + byte[] outputArray, int outputOff, int outputLen, + int flush, int params); + private native long deflateBufferBuffer(long addr, + long inputAddress, int inputLen, + long outputAddress, int outputLen, + int flush, int params); private static native int getAdler(long addr); private static native void reset(long addr); private static native void end(long addr); diff --git a/src/java.base/share/classes/java/util/zip/Inflater.java b/src/java.base/share/classes/java/util/zip/Inflater.java index 9c6d8aa3d83..7ab2ec33187 100644 --- a/src/java.base/share/classes/java/util/zip/Inflater.java +++ b/src/java.base/share/classes/java/util/zip/Inflater.java @@ -26,7 +26,13 @@ package java.util.zip; import java.lang.ref.Cleaner.Cleanable; +import java.lang.ref.Reference; +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; +import java.util.Objects; + import jdk.internal.ref.CleanerFactory; +import sun.nio.ch.DirectBuffer; /** * This class provides support for general purpose decompression using the @@ -92,14 +98,20 @@ import jdk.internal.ref.CleanerFactory; public class Inflater { private final InflaterZStreamRef zsRef; - private byte[] buf = defaultBuf; - private int off, len; + private ByteBuffer input = ZipUtils.defaultBuf; + private byte[] inputArray; + private int inputPos, inputLim; private boolean finished; private boolean needDict; private long bytesRead; private long bytesWritten; - private static final byte[] defaultBuf = new byte[0]; + /* + * These fields are used as an "out" parameter from JNI when a + * DataFormatException is thrown during the inflate operation. + */ + private int inputConsumed; + private int outputConsumed; static { ZipUtils.loadLibrary(); @@ -138,16 +150,14 @@ public class Inflater { * @see Inflater#needsInput */ public void setInput(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { - this.buf = b; - this.off = off; - this.len = len; + this.input = null; + this.inputArray = b; + this.inputPos = off; + this.inputLim = off + len; } } @@ -162,6 +172,32 @@ public class Inflater { setInput(b, 0, b.length); } + /** + * Sets input data for decompression. Should be called whenever + * needsInput() returns true indicating that more input data is + * required. + *

+ * The given buffer's position will be updated as inflate operations are + * performed. The input buffer may be modified (refilled) between inflate + * operations; doing so is equivalent to creating a new buffer and setting + * it with this method. + *

+ * Modifying the input buffer's contents, position, or limit concurrently with + * an inflate operation will result in undefined behavior, which may include + * incorrect operation results or operation failure. + * + * @param byteBuffer the input data bytes + * @see Inflater#needsInput + * @since 11 + */ + public void setInput(ByteBuffer byteBuffer) { + Objects.requireNonNull(byteBuffer); + synchronized (zsRef) { + this.input = byteBuffer; + this.inputArray = null; + } + } + /** * Sets the preset dictionary to the given array of bytes. Should be * called when inflate() returns 0 and needsDictionary() returns true @@ -174,9 +210,6 @@ public class Inflater { * @see Inflater#getAdler */ public void setDictionary(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } @@ -200,6 +233,42 @@ public class Inflater { setDictionary(b, 0, b.length); } + /** + * Sets the preset dictionary to the given array of bytes. Should be + * called when inflate() returns 0 and needsDictionary() returns true + * indicating that a preset dictionary is required. The method getAdler() + * can be used to get the Adler-32 value of the dictionary needed. + *

+ * The bytes in given byte buffer will be fully consumed by this method. On + * return, its position will equal its limit. + * + * @param byteBuffer the dictionary data bytes + * @see Inflater#needsDictionary + * @see Inflater#getAdler + * @since 11 + */ + public void setDictionary(ByteBuffer byteBuffer) { + synchronized (zsRef) { + final int position = byteBuffer.position(); + final int remaining = Math.max(byteBuffer.limit() - position, 0); + ensureOpen(); + if (byteBuffer.isDirect()) { + final long address = ((DirectBuffer) byteBuffer).address(); + try { + setDictionaryBuffer(zsRef.address(), address + position, remaining); + } finally { + Reference.reachabilityFence(byteBuffer); + } + } else { + final byte[] array = ZipUtils.getBufferArray(byteBuffer); + final int offset = ZipUtils.getBufferOffset(byteBuffer); + setDictionary(zsRef.address(), array, offset + position, remaining); + } + byteBuffer.position(position + remaining); + needDict = false; + } + } + /** * Returns the total number of bytes remaining in the input buffer. * This can be used to find out what bytes still remain in the input @@ -208,19 +277,22 @@ public class Inflater { */ public int getRemaining() { synchronized (zsRef) { - return len; + final ByteBuffer input = this.input; + return input == null ? inputLim - inputPos : input.remaining(); } } /** * Returns true if no data remains in the input buffer. This can - * be used to determine if #setInput should be called in order - * to provide more input. + * be used to determine if one of the {@code setInput()} methods should be + * called in order to provide more input. + * * @return true if no data remains in the input buffer */ public boolean needsInput() { synchronized (zsRef) { - return len <= 0; + final ByteBuffer input = this.input; + return input == null ? inputLim == inputPos : ! input.hasRemaining(); } } @@ -254,30 +326,100 @@ public class Inflater { * determine if more input data or a preset dictionary is required. * In the latter case, getAdler() can be used to get the Adler-32 * value of the dictionary required. + *

+ * If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation, even in the event that a {@link DataFormatException} + * is thrown. + *

+ * The {@linkplain #getRemaining() remaining byte count} will be reduced by + * the number of consumed input bytes. If the {@link #setInput(ByteBuffer)} + * method was called to provide a buffer for input, the input buffer's position + * will be advanced the number of consumed bytes. + *

+ * These byte totals, as well as + * the {@linkplain #getBytesRead() total bytes read} + * and the {@linkplain #getBytesWritten() total bytes written} + * values, will be updated even in the event that a {@link DataFormatException} + * is thrown to reflect the amount of data consumed and produced before the + * exception occurred. + * * @param b the buffer for the uncompressed data * @param off the start offset of the data * @param len the maximum number of uncompressed bytes * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid + * @throws DataFormatException if the compressed data format is invalid * @see Inflater#needsInput * @see Inflater#needsDictionary */ public int inflate(byte[] b, int off, int len) throws DataFormatException { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { ensureOpen(); - int thisLen = this.len; - int n = inflateBytes(zsRef.address(), b, off, len); - bytesWritten += n; - bytesRead += (thisLen - this.len); - return n; + final ByteBuffer input = this.input; + final long result; + final int inputPos; + if (input == null) { + inputPos = this.inputPos; + try { + result = inflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + b, off, len); + } catch (DataFormatException e) { + int read = inputConsumed; + this.inputPos = inputPos + read; + bytesRead += read; + inputConsumed = 0; + throw e; + } + } else { + inputPos = input.position(); + try { + final int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + try { + final long inputAddress = ((DirectBuffer) input).address(); + result = inflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + b, off, len); + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + b, off, len); + } + } catch (DataFormatException e) { + int read = inputConsumed; + input.position(inputPos + read); + bytesRead += read; + inputConsumed = 0; + throw e; + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if ((result >>> 63 & 1) != 0) { + needDict = true; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + bytesWritten += written; + bytesRead += read; + return written; } } @@ -288,9 +430,22 @@ public class Inflater { * determine if more input data or a preset dictionary is required. * In the latter case, getAdler() can be used to get the Adler-32 * value of the dictionary required. + *

+ * The {@linkplain #getRemaining() remaining byte count} will be reduced by + * the number of consumed input bytes. If the {@link #setInput(ByteBuffer)} + * method was called to provide a buffer for input, the input buffer's position + * will be advanced the number of consumed bytes. + *

+ * These byte totals, as well as + * the {@linkplain #getBytesRead() total bytes read} + * and the {@linkplain #getBytesWritten() total bytes written} + * values, will be updated even in the event that a {@link DataFormatException} + * is thrown to reflect the amount of data consumed and produced before the + * exception occurred. + * * @param b the buffer for the uncompressed data * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid + * @throws DataFormatException if the compressed data format is invalid * @see Inflater#needsInput * @see Inflater#needsDictionary */ @@ -298,6 +453,158 @@ public class Inflater { return inflate(b, 0, b.length); } + /** + * Uncompresses bytes into specified buffer. Returns actual number + * of bytes uncompressed. A return value of 0 indicates that + * needsInput() or needsDictionary() should be called in order to + * determine if more input data or a preset dictionary is required. + * In the latter case, getAdler() can be used to get the Adler-32 + * value of the dictionary required. + *

+ * On success, the position of the given {@code output} byte buffer will be + * advanced by as many bytes as were produced by the operation, which is equal + * to the number returned by this method. Note that the position of the + * {@code output} buffer will be advanced even in the event that a + * {@link DataFormatException} is thrown. + *

+ * The {@linkplain #getRemaining() remaining byte count} will be reduced by + * the number of consumed input bytes. If the {@link #setInput(ByteBuffer)} + * method was called to provide a buffer for input, the input buffer's position + * will be advanced the number of consumed bytes. + *

+ * These byte totals, as well as + * the {@linkplain #getBytesRead() total bytes read} + * and the {@linkplain #getBytesWritten() total bytes written} + * values, will be updated even in the event that a {@link DataFormatException} + * is thrown to reflect the amount of data consumed and produced before the + * exception occurred. + * + * @param output the buffer for the uncompressed data + * @return the actual number of uncompressed bytes + * @throws DataFormatException if the compressed data format is invalid + * @throws ReadOnlyBufferException if the given output buffer is read-only + * @see Inflater#needsInput + * @see Inflater#needsDictionary + * @since 11 + */ + public int inflate(ByteBuffer output) throws DataFormatException { + if (output.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + synchronized (zsRef) { + ensureOpen(); + final ByteBuffer input = this.input; + final long result; + final int inputPos; + final int outputPos = output.position(); + final int outputRem = Math.max(output.limit() - outputPos, 0); + if (input == null) { + inputPos = this.inputPos; + try { + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBytesBuffer(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputArray, outputOffset + outputPos, outputRem); + } + } catch (DataFormatException e) { + int read = inputConsumed; + this.inputPos = inputPos + read; + bytesRead += read; + inputConsumed = 0; + int written = outputConsumed; + output.position(outputPos + written); + outputConsumed = 0; + throw e; + } + } else { + inputPos = input.position(); + final int inputRem = Math.max(input.limit() - inputPos, 0); + try { + if (input.isDirect()) { + final long inputAddress = ((DirectBuffer) input).address(); + try { + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBufferBuffer(zsRef.address(), + inputAddress + inputPos, inputRem, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem); + } + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBytesBuffer(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem); + } + } + } catch (DataFormatException e) { + int read = inputConsumed; + input.position(inputPos + read); + bytesRead += read; + inputConsumed = 0; + int written = outputConsumed; + output.position(outputPos + written); + outputConsumed = 0; + throw e; + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if ((result >>> 63 & 1) != 0) { + needDict = true; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + // Note: this method call also serves to keep the byteBuffer ref alive + output.position(outputPos + written); + bytesWritten += written; + bytesRead += read; + return written; + } + } + /** * Returns the ADLER-32 value of the uncompressed data. * @return the ADLER-32 value of the uncompressed data @@ -368,10 +675,10 @@ public class Inflater { synchronized (zsRef) { ensureOpen(); reset(zsRef.address()); - buf = defaultBuf; + input = ZipUtils.defaultBuf; + inputArray = null; finished = false; needDict = false; - off = len = 0; bytesRead = bytesWritten = 0; } } @@ -386,7 +693,8 @@ public class Inflater { public void end() { synchronized (zsRef) { zsRef.clean(); - buf = null; + input = ZipUtils.defaultBuf; + inputArray = null; } } @@ -416,18 +724,23 @@ public class Inflater { throw new NullPointerException("Inflater has been closed"); } - boolean ended() { - synchronized (zsRef) { - return zsRef.address() == 0; - } - } - private static native void initIDs(); private static native long init(boolean nowrap); private static native void setDictionary(long addr, byte[] b, int off, int len); - private native int inflateBytes(long addr, byte[] b, int off, int len) - throws DataFormatException; + private static native void setDictionaryBuffer(long addr, long bufAddress, int len); + private native long inflateBytesBytes(long addr, + byte[] inputArray, int inputOff, int inputLen, + byte[] outputArray, int outputOff, int outputLen) throws DataFormatException; + private native long inflateBytesBuffer(long addr, + byte[] inputArray, int inputOff, int inputLen, + long outputAddress, int outputLen) throws DataFormatException; + private native long inflateBufferBytes(long addr, + long inputAddress, int inputLen, + byte[] outputArray, int outputOff, int outputLen) throws DataFormatException; + private native long inflateBufferBuffer(long addr, + long inputAddress, int inputLen, + long outputAddress, int outputLen) throws DataFormatException; private static native int getAdler(long addr); private static native void reset(long addr); private static native void end(long addr); diff --git a/src/java.base/share/classes/java/util/zip/ZipUtils.java b/src/java.base/share/classes/java/util/zip/ZipUtils.java index 45c5d8dbb67..07e64e4fa92 100644 --- a/src/java.base/share/classes/java/util/zip/ZipUtils.java +++ b/src/java.base/share/classes/java/util/zip/ZipUtils.java @@ -25,6 +25,8 @@ package java.util.zip; +import java.nio.Buffer; +import java.nio.ByteBuffer; import java.nio.file.attribute.FileTime; import java.security.AccessController; import java.security.PrivilegedAction; @@ -37,6 +39,9 @@ import java.util.concurrent.TimeUnit; import static java.util.zip.ZipConstants.ENDHDR; +import jdk.internal.misc.Unsafe; +import sun.nio.ch.DirectBuffer; + class ZipUtils { // used to adjust values between Windows and java epoch @@ -45,6 +50,8 @@ class ZipUtils { // used to indicate the corresponding windows time is not available public static final long WINDOWS_TIME_NOT_AVAILABLE = Long.MIN_VALUE; + static final ByteBuffer defaultBuf = ByteBuffer.allocateDirect(0); + /** * Converts Windows time (in microseconds, UTC/GMT) time to FileTime. */ @@ -281,4 +288,17 @@ class ZipUtils { AccessController.doPrivileged(pa); } } + + private static final Unsafe unsafe = Unsafe.getUnsafe(); + + private static final long byteBufferArrayOffset = unsafe.objectFieldOffset(ByteBuffer.class, "hb"); + private static final long byteBufferOffsetOffset = unsafe.objectFieldOffset(ByteBuffer.class, "offset"); + + static byte[] getBufferArray(ByteBuffer byteBuffer) { + return (byte[]) unsafe.getObject(byteBuffer, byteBufferArrayOffset); + } + + static int getBufferOffset(ByteBuffer byteBuffer) { + return unsafe.getInt(byteBuffer, byteBufferOffsetOffset); + } } diff --git a/src/java.base/share/native/libzip/Deflater.c b/src/java.base/share/native/libzip/Deflater.c index b666a16145a..b56df5ecc1b 100644 --- a/src/java.base/share/native/libzip/Deflater.c +++ b/src/java.base/share/native/libzip/Deflater.c @@ -38,34 +38,6 @@ #define DEF_MEM_LEVEL 8 -static jfieldID levelID; -static jfieldID strategyID; -static jfieldID setParamsID; -static jfieldID finishID; -static jfieldID finishedID; -static jfieldID bufID, offID, lenID; - -JNIEXPORT void JNICALL -Java_java_util_zip_Deflater_initIDs(JNIEnv *env, jclass cls) -{ - levelID = (*env)->GetFieldID(env, cls, "level", "I"); - CHECK_NULL(levelID); - strategyID = (*env)->GetFieldID(env, cls, "strategy", "I"); - CHECK_NULL(strategyID); - setParamsID = (*env)->GetFieldID(env, cls, "setParams", "Z"); - CHECK_NULL(setParamsID); - finishID = (*env)->GetFieldID(env, cls, "finish", "Z"); - CHECK_NULL(finishID); - finishedID = (*env)->GetFieldID(env, cls, "finished", "Z"); - CHECK_NULL(finishedID); - bufID = (*env)->GetFieldID(env, cls, "buf", "[B"); - CHECK_NULL(bufID); - offID = (*env)->GetFieldID(env, cls, "off", "I"); - CHECK_NULL(offID); - lenID = (*env)->GetFieldID(env, cls, "len", "I"); - CHECK_NULL(lenID); -} - JNIEXPORT jlong JNICALL Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level, jint strategy, jboolean nowrap) @@ -104,17 +76,9 @@ Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level, } } -JNIEXPORT void JNICALL -Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, - jarray b, jint off, jint len) +static void doSetDictionary(JNIEnv *env, jlong addr, jbyte *buf, jint len) { - Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - int res; - if (buf == 0) {/* out of memory */ - return; - } - res = deflateSetDictionary((z_stream *)jlong_to_ptr(addr), buf + off, len); - (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); + int res = deflateSetDictionary(jlong_to_ptr(addr), (Bytef *) buf, len); switch (res) { case Z_OK: break; @@ -127,94 +91,169 @@ Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, } } -JNIEXPORT jint JNICALL -Java_java_util_zip_Deflater_deflateBytes(JNIEnv *env, jobject this, jlong addr, - jarray b, jint off, jint len, jint flush) +JNIEXPORT void JNICALL +Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, + jbyteArray b, jint off, jint len) +{ + jbyte *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); + if (buf == NULL) /* out of memory */ + return; + doSetDictionary(env, addr, buf + off, len); + (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); +} + +JNIEXPORT void JNICALL +Java_java_util_zip_Deflater_setDictionaryBuffer(JNIEnv *env, jclass cls, jlong addr, + jlong bufferAddr, jint len) +{ + jbyte *buf = jlong_to_ptr(bufferAddr); + doSetDictionary(env, addr, buf, len); +} + +static jlong doDeflate(JNIEnv *env, jobject this, jlong addr, + jbyte *input, jint inputLen, + jbyte *output, jint outputLen, + jint flush, jint params) { z_stream *strm = jlong_to_ptr(addr); + jint inputUsed = 0, outputUsed = 0; - jarray this_buf = (*env)->GetObjectField(env, this, bufID); - jint this_off = (*env)->GetIntField(env, this, offID); - jint this_len = (*env)->GetIntField(env, this, lenID); - jbyte *in_buf; - jbyte *out_buf; - int res; - if ((*env)->GetBooleanField(env, this, setParamsID)) { - int level = (*env)->GetIntField(env, this, levelID); - int strategy = (*env)->GetIntField(env, this, strategyID); - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - // Throw OOME only when length is not zero - if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } + strm->next_in = (Bytef *) input; + strm->next_out = (Bytef *) output; + strm->avail_in = inputLen; + strm->avail_out = outputLen; + + int finished = 0; + int setParams = params & 1; - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - res = deflateParams(strm, level, strategy); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + if (setParams) { + int strategy = (params >> 1) & 3; + int level = params >> 3; + int res = deflateParams(strm, level, strategy); switch (res) { case Z_OK: - (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE); + setParams = 0; + /* fall through */ case Z_BUF_ERROR: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return (jint) (len - strm->avail_out); + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; default: JNU_ThrowInternalError(env, strm->msg); return 0; } } else { - jboolean finish = (*env)->GetBooleanField(env, this, finishID); - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - if (this_len != 0) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0) - JNU_ThrowOutOfMemoryError(env, 0); - - return 0; - } - - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - res = deflate(strm, finish ? Z_FINISH : flush); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + int res = deflate(strm, flush); switch (res) { case Z_STREAM_END: - (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); + finished = 1; /* fall through */ case Z_OK: case Z_BUF_ERROR: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return len - strm->avail_out; + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; default: JNU_ThrowInternalError(env, strm->msg); return 0; } } + return ((jlong)inputUsed) | (((jlong)outputUsed) << 31) | (((jlong)finished) << 62) | (((jlong)setParams) << 63); +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBytesBytes(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen, + jint flush, jint params) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doDeflate(env, this, addr, + input + inputOff, inputLen, + output + outputOff, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0); + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBytesBuffer(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jlong outputBuffer, jint outputLen, + jint flush, jint params) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = jlong_to_ptr(outputBuffer); + + jlong retVal = doDeflate(env, this, addr, + input + inputOff, inputLen, + output, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBufferBytes(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen, + jint flush, jint params) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doDeflate(env, this, addr, + input, inputLen, + output + outputOff, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBufferBuffer(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jlong outputBuffer, jint outputLen, + jint flush, jint params) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = jlong_to_ptr(outputBuffer); + + return doDeflate(env, this, addr, + input, inputLen, + output, outputLen, + flush, params); } JNIEXPORT jint JNICALL diff --git a/src/java.base/share/native/libzip/Inflater.c b/src/java.base/share/native/libzip/Inflater.c index 2e21d084b39..d1a020d803f 100644 --- a/src/java.base/share/native/libzip/Inflater.c +++ b/src/java.base/share/native/libzip/Inflater.c @@ -42,23 +42,16 @@ #define ThrowDataFormatException(env, msg) \ JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg) -static jfieldID needDictID; -static jfieldID finishedID; -static jfieldID bufID, offID, lenID; +static jfieldID inputConsumedID; +static jfieldID outputConsumedID; JNIEXPORT void JNICALL Java_java_util_zip_Inflater_initIDs(JNIEnv *env, jclass cls) { - needDictID = (*env)->GetFieldID(env, cls, "needDict", "Z"); - CHECK_NULL(needDictID); - finishedID = (*env)->GetFieldID(env, cls, "finished", "Z"); - CHECK_NULL(finishedID); - bufID = (*env)->GetFieldID(env, cls, "buf", "[B"); - CHECK_NULL(bufID); - offID = (*env)->GetFieldID(env, cls, "off", "I"); - CHECK_NULL(offID); - lenID = (*env)->GetFieldID(env, cls, "len", "I"); - CHECK_NULL(lenID); + inputConsumedID = (*env)->GetFieldID(env, cls, "inputConsumed", "I"); + outputConsumedID = (*env)->GetFieldID(env, cls, "outputConsumed", "I"); + CHECK_NULL(inputConsumedID); + CHECK_NULL(outputConsumedID); } JNIEXPORT jlong JNICALL @@ -94,16 +87,9 @@ Java_java_util_zip_Inflater_init(JNIEnv *env, jclass cls, jboolean nowrap) } } -JNIEXPORT void JNICALL -Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, - jarray b, jint off, jint len) +static void doSetDictionary(JNIEnv *env, jlong addr, jbyte *buf, jint len) { - Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - int res; - if (buf == 0) /* out of memory */ - return; - res = inflateSetDictionary(jlong_to_ptr(addr), buf + off, len); - (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); + int res = inflateSetDictionary(jlong_to_ptr(addr), (Bytef *) buf, len); switch (res) { case Z_OK: break; @@ -117,68 +103,155 @@ Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, } } -JNIEXPORT jint JNICALL -Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr, - jarray b, jint off, jint len) +JNIEXPORT void JNICALL +Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, + jbyteArray b, jint off, jint len) +{ + jbyte *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); + if (buf == NULL) /* out of memory */ + return; + doSetDictionary(env, addr, buf + off, len); + (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); +} + +JNIEXPORT void JNICALL +Java_java_util_zip_Inflater_setDictionaryBuffer(JNIEnv *env, jclass cls, jlong addr, + jlong bufferAddr, jint len) +{ + jbyte *buf = jlong_to_ptr(bufferAddr); + doSetDictionary(env, addr, buf, len); +} + +static jlong doInflate(JNIEnv *env, jobject this, jlong addr, + jbyte *input, jint inputLen, + jbyte *output, jint outputLen) { z_stream *strm = jlong_to_ptr(addr); - jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID); - jint this_off = (*env)->GetIntField(env, this, offID); - jint this_len = (*env)->GetIntField(env, this, lenID); + jint inputUsed = 0, outputUsed = 0; - jbyte *in_buf; - jbyte *out_buf; - int ret; + strm->next_in = (Bytef *) input; + strm->next_out = (Bytef *) output; + strm->avail_in = inputLen; + strm->avail_out = outputLen; - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - ret = inflate(strm, Z_PARTIAL_FLUSH); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + int ret = inflate(strm, Z_PARTIAL_FLUSH); + int finished = 0; + int needDict = 0; switch (ret) { case Z_STREAM_END: - (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); + finished = 1; /* fall through */ case Z_OK: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return (jint) (len - strm->avail_out); + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; case Z_NEED_DICT: - (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE); + needDict = 1; /* Might have consumed some input here! */ - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return 0; + inputUsed = inputLen - strm->avail_in; + break; case Z_BUF_ERROR: - return 0; + break; case Z_DATA_ERROR: + inputUsed = inputLen - strm->avail_in; + (*env)->SetIntField(env, this, inputConsumedID, inputUsed); ThrowDataFormatException(env, strm->msg); - return 0; + break; case Z_MEM_ERROR: JNU_ThrowOutOfMemoryError(env, 0); - return 0; + break; default: JNU_ThrowInternalError(env, strm->msg); - return 0; + break; + } + return ((jlong)inputUsed) | (((jlong)outputUsed) << 31) | (((jlong)finished) << 62) | (((jlong)needDict) << 63); +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBytesBytes(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doInflate(env, this, addr, + input + inputOff, inputLen, + output + outputOff, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0); + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBytesBuffer(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jlong outputBuffer, jint outputLen) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = jlong_to_ptr(outputBuffer); + + jlong retVal = doInflate(env, this, addr, + input + inputOff, inputLen, + output, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBufferBytes(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; } + + jlong retVal = doInflate(env, this, addr, + input, inputLen, + output + outputOff, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBufferBuffer(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jlong outputBuffer, jint outputLen) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = jlong_to_ptr(outputBuffer); + + return doInflate(env, this, addr, + input, inputLen, + output, outputLen); } JNIEXPORT jint JNICALL diff --git a/test/jdk/java/util/zip/FlaterTest.java b/test/jdk/java/util/zip/FlaterTest.java index 7245440d033..b5aff0319b3 100644 --- a/test/jdk/java/util/zip/FlaterTest.java +++ b/test/jdk/java/util/zip/FlaterTest.java @@ -29,7 +29,6 @@ * @key randomness */ -import java.io.*; import java.nio.*; import java.util.*; import java.util.zip.*; @@ -41,35 +40,37 @@ import java.util.zip.*; */ public class FlaterTest extends Thread { private static final int DATA_LEN = 1024 * 128; - private static byte[] data; + + private static ByteBuffer dataDirect; + private static ByteBuffer dataHeap; // If true, print extra info. private static final boolean debug = false; // Set of Flater threads running. - private static Set flaters = - Collections.synchronizedSet(new HashSet()); + private static Set flaters = + Collections.synchronizedSet(new HashSet<>()); /** Fill in {@code data} with random values. */ static void createData() { - ByteBuffer bb = ByteBuffer.allocate(8); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - for (int i = 0; i < DATA_LEN; i++) { - bb.putDouble(0, Math.random()); - baos.write(bb.array(), 0, 8); + ByteBuffer bb = ByteBuffer.allocateDirect(DATA_LEN * 8); + for (int i = 0; i < DATA_LEN * 8; i += 8) { + bb.putDouble(i, Math.random()); } - data = baos.toByteArray(); - if (debug) System.out.println("data length is " + data.length); + dataDirect = bb; + final ByteBuffer hb = ByteBuffer.allocate(bb.capacity()); + hb.duplicate().put(bb.duplicate()); + dataHeap = hb; + if (debug) System.out.println("data length is " + bb.capacity()); } /** @return the length of the deflated {@code data}. */ - private static int getDeflatedLength() throws Throwable { - int rc = 0; + private static int getDeflatedLength() { Deflater deflater = new Deflater(); - deflater.setInput(data); + deflater.setInput(dataDirect.duplicate()); deflater.finish(); - byte[] out = new byte[data.length]; - rc = deflater.deflate(out); + byte[] out = new byte[dataDirect.capacity()]; + int rc = deflater.deflate(out); deflater.end(); if (debug) System.out.println("deflatedLength is " + rc); return rc; @@ -78,70 +79,98 @@ public class FlaterTest extends Thread { /** Compares given bytes with those in {@code data}. * @throws Exception if given bytes don't match {@code data}. */ - private static void validate(byte[] buf, int offset, int len) throws Exception { + private static void validate(ByteBuffer buf, int offset, int len) throws Exception { for (int i = 0; i < len; i++ ) { - if (buf[i] != data[offset+i]) { + if (buf.get(i) != dataDirect.get(offset+i)) { throw new Exception("mismatch at " + (offset + i)); } } } - public static void realMain(String[] args) throws Throwable { - createData(); + public static void realMain(String[] args) { int numThreads = args.length > 0 ? Integer.parseInt(args[0]) : 5; - new FlaterTest().go(numThreads); + createData(); + for (int srcMode = 0; srcMode <= 2; srcMode ++) { + for (int dstMode = 0; dstMode <= 2; dstMode ++) { + new FlaterTest().go(numThreads, srcMode, dstMode); + } + } } - private synchronized void go(int numThreads) throws Throwable { + private synchronized void go(int numThreads, int srcMode, int dstMode) { int deflatedLength = getDeflatedLength(); long time = System.currentTimeMillis(); for (int i = 0; i < numThreads; i++) { - Flater f = new Flater(deflatedLength); + Flater f = new Flater(deflatedLength, srcMode, dstMode); flaters.add(f); f.start(); } - while (flaters.size() != 0) { - try { - Thread.currentThread().sleep(10); - } catch (InterruptedException ex) { - unexpected(ex); + synchronized (flaters) { + while (flaters.size() != 0) { + try { + flaters.wait(); + } catch (InterruptedException ex) { + unexpected(ex); + } } } time = System.currentTimeMillis() - time; System.out.println("Time needed for " + numThreads - + " threads to deflate/inflate: " + time + " ms."); + + " threads to deflate/inflate: " + time + " ms (srcMode="+srcMode+",dstMode="+dstMode+")"); } /** Deflates and inflates data. */ static class Flater extends Thread { private final int deflatedLength; + private final int srcMode, dstMode; - private Flater(int length) { + private Flater(int length, int srcMode, int dstMode) { this.deflatedLength = length; + this.srcMode = srcMode; + this.dstMode = dstMode; } /** Deflates and inflates {@code data}. */ public void run() { if (debug) System.out.println(getName() + " starting run()"); try { - byte[] deflated = DeflateData(deflatedLength); + ByteBuffer deflated = DeflateData(deflatedLength); InflateData(deflated); } catch (Throwable t) { t.printStackTrace(); fail(getName() + " failed"); } finally { - flaters.remove(this); + synchronized (flaters) { + flaters.remove(this); + if (flaters.isEmpty()) { + flaters.notifyAll(); + } + } } } /** Returns a copy of {@code data} in deflated form. */ - private byte[] DeflateData(int length) throws Throwable { + private ByteBuffer DeflateData(int length) { Deflater deflater = new Deflater(); - deflater.setInput(data); + if (srcMode == 0) { + deflater.setInput(dataHeap.array()); + } else if (srcMode == 1) { + deflater.setInput(dataHeap.duplicate()); + } else { + assert srcMode == 2; + deflater.setInput(dataDirect.duplicate()); + } deflater.finish(); - byte[] out = new byte[length]; - deflater.deflate(out); + ByteBuffer out = dstMode == 2 ? ByteBuffer.allocateDirect(length) : ByteBuffer.allocate(length); + int deflated; + if (dstMode == 0) { + deflated = deflater.deflate(out.array(), 0, length); + out.position(deflated); + } else { + deflater.deflate(out); + } + out.flip(); return out; } @@ -149,14 +178,30 @@ public class FlaterTest extends Thread { * inflation. * @throws Exception if inflated bytes don't match {@code data}. */ - private void InflateData(byte[] bytes) throws Throwable { + private void InflateData(ByteBuffer bytes) throws Throwable { Inflater inflater = new Inflater(); - inflater.setInput(bytes, 0, bytes.length); + if (dstMode == 0) { + inflater.setInput(bytes.array(), 0, bytes.remaining()); + } else { + inflater.setInput(bytes); + } + if (inflater.getRemaining() == 0) { + throw new Exception("Nothing to inflate (bytes=" + bytes + ")"); + } int len = 1024 * 8; int offset = 0; + ByteBuffer buf = srcMode == 2 ? ByteBuffer.allocateDirect(len) : ByteBuffer.allocate(len); while (inflater.getRemaining() > 0) { - byte[] buf = new byte[len]; - int inflated = inflater.inflate(buf, 0, len); + buf.clear(); + int inflated; + if (srcMode == 0) { + inflated = inflater.inflate(buf.array(), 0, buf.remaining()); + } else { + inflated = inflater.inflate(buf); + } + if (inflated == 0) { + throw new Exception("Nothing inflated (dst=" + buf + ",offset=" + offset + ",rem=" + inflater.getRemaining() + ",srcMode="+srcMode+",dstMode="+dstMode+")"); + } validate(buf, offset, inflated); offset += inflated; } From paul.sandoz at oracle.com Fri Mar 9 18:31:41 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 9 Mar 2018 10:31:41 -0800 Subject: RFR: 8199009: test/jdk/java/util/Locale/SoftKeys.java fails with OutOfMemoryError In-Reply-To: <43f117e1-5714-ce3b-75a6-67f826030d23@oracle.com> References: <43f117e1-5714-ce3b-75a6-67f826030d23@oracle.com> Message-ID: <6BDF9CEA-314D-45A4-B226-54E76B43BED5@oracle.com> > On Mar 9, 2018, at 3:42 AM, Claes Redestad wrote: > > Hi, > > the stress test I introduced together with JDK-8196869 to guard against introducing NPE issues > in the Locale cache handling has been shown to fail with OOME on some very particular machine > configurations. Experiments show that we could make such OOMEs easily go away by increasing > the heap size in the test to allow GC to keep up, but then the test will no longer reliably > reproduce the NPE issues the test was designed to guard against. > > I think the best we can do is to ignore the OOMEs in this particular stress test (which > runs reliably on almost all of our test systems): > > http://cr.openjdk.java.net/~redestad/8199009/jdk.00/ > > Bugs: https://bugs.openjdk.java.net/browse/JDK-8199009 > 49 } catch (OutOfMemoryError e) { 50 // Can happen on some system configurations, and while increasing heap 51 // size would allow GC to keep up, it makes it impractically hard to 52 // reproduce NPE issues that could arise when references are being 53 // cleared. Do a System.gc() to try to reclaim enough memory to not 54 // throw an OOME again in the jtreg wrapper. 55 System.gc(); 56 } Since the test is run with main/othervm why bother with System.gc? Paul. > Another option would be to remove the test, since it's "only" testing for a very particular > coding error that I was about to commit when working on JDK-8196869.. > > Thanks! > > /Claes From Roger.Riggs at Oracle.com Fri Mar 9 18:34:32 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 9 Mar 2018 13:34:32 -0500 Subject: RFR 8199420 Update javadoc tags in java.lang.System and related Message-ID: <44cf5622-815f-cb06-fbcb-91a2b80ef7c9@Oracle.com> Please review some javadoc tag cleanup in java.lang.System, Threads, etc. The changes are using {@code } instead of ,? @throws instead of @exception and the removal of a few unnecessary

tags. The are more many more files but these bugged me recently and I didn't want the changeset to be too large. Webrev: http://cr.openjdk.java.net/~rriggs/webrev-system-javadoc/index.html Thanks, Roger From claes.redestad at oracle.com Fri Mar 9 18:56:55 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Fri, 9 Mar 2018 19:56:55 +0100 Subject: RFR: 8199009: test/jdk/java/util/Locale/SoftKeys.java fails with OutOfMemoryError In-Reply-To: <6BDF9CEA-314D-45A4-B226-54E76B43BED5@oracle.com> References: <43f117e1-5714-ce3b-75a6-67f826030d23@oracle.com> <6BDF9CEA-314D-45A4-B226-54E76B43BED5@oracle.com> Message-ID: <16cfd248-12b1-9c65-b1d5-471a78ba891e@oracle.com> On 2018-03-09 19:31, Paul Sandoz wrote: > 49 } catch (OutOfMemoryError e) { > 50 // Can happen on some system configurations, and while increasing heap > 51 // size would allow GC to keep up, it makes it impractically hard to > 52 // reproduce NPE issues that could arise when references are being > 53 // cleared. Do a System.gc() to try to reclaim enough memory to not > 54 // throw an OOME again in the jtreg wrapper. > 55 System.gc(); > 56 } > > Since the test is run with main/othervm why bother with System.gc? If I don't the test still fails almost all the time with an OOME in whatever jtreg wrapper method is calling main. /Claes From paul.sandoz at oracle.com Fri Mar 9 18:59:09 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 9 Mar 2018 10:59:09 -0800 Subject: RFR: 8199009: test/jdk/java/util/Locale/SoftKeys.java fails with OutOfMemoryError In-Reply-To: <16cfd248-12b1-9c65-b1d5-471a78ba891e@oracle.com> References: <43f117e1-5714-ce3b-75a6-67f826030d23@oracle.com> <6BDF9CEA-314D-45A4-B226-54E76B43BED5@oracle.com> <16cfd248-12b1-9c65-b1d5-471a78ba891e@oracle.com> Message-ID: <91D910F6-4AEC-478D-A973-B6C74E1E39AF@oracle.com> > On Mar 9, 2018, at 10:56 AM, Claes Redestad wrote: > > > > On 2018-03-09 19:31, Paul Sandoz wrote: >> 49 } catch (OutOfMemoryError e) { >> 50 // Can happen on some system configurations, and while increasing heap >> 51 // size would allow GC to keep up, it makes it impractically hard to >> 52 // reproduce NPE issues that could arise when references are being >> 53 // cleared. Do a System.gc() to try to reclaim enough memory to not >> 54 // throw an OOME again in the jtreg wrapper. >> 55 System.gc(); >> 56 } >> >> Since the test is run with main/othervm why bother with System.gc? > > If I don't the test still fails almost all the time with an OOME in whatever jtreg > wrapper method is calling main. > Ah, ok, even the thin shim. +1 Paul. From lance.andersen at oracle.com Fri Mar 9 18:56:54 2018 From: lance.andersen at oracle.com (Lance Andersen) Date: Fri, 9 Mar 2018 13:56:54 -0500 Subject: RFR 8199420 Update javadoc tags in java.lang.System and related In-Reply-To: <44cf5622-815f-cb06-fbcb-91a2b80ef7c9@Oracle.com> References: <44cf5622-815f-cb06-fbcb-91a2b80ef7c9@Oracle.com> Message-ID: Looks good Roger, I know JDBC needs a pass as well and is on the todo list... > On Mar 9, 2018, at 1:34 PM, Roger Riggs wrote: > > Please review some javadoc tag cleanup in java.lang.System, Threads, etc. > The changes are using {@code } instead of , @throws instead of @exception > and the removal of a few unnecessary

tags. > > The are more many more files but these bugged me recently and I didn't want the changeset to be too large. > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-system-javadoc/index.html > > Thanks, Roger > 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 naoto.sato at oracle.com Fri Mar 9 19:03:17 2018 From: naoto.sato at oracle.com (naoto.sato at oracle.com) Date: Fri, 9 Mar 2018 11:03:17 -0800 Subject: RFR: 8199009: test/jdk/java/util/Locale/SoftKeys.java fails with OutOfMemoryError In-Reply-To: <43f117e1-5714-ce3b-75a6-67f826030d23@oracle.com> References: <43f117e1-5714-ce3b-75a6-67f826030d23@oracle.com> Message-ID: <34a92cbc-13e8-a15f-d238-172dc3b3f905@oracle.com> Looks good to me. Thanks for fixing this, Claes! Naoto On 3/9/18 3:42 AM, Claes Redestad wrote: > Hi, > > the stress test I introduced together with JDK-8196869 to guard against > introducing NPE issues > in the Locale cache handling has been shown to fail with OOME on some > very particular machine > configurations. Experiments show that we could make such OOMEs easily go > away by increasing > the heap size in the test to allow GC to keep up, but then the test will > no longer reliably > reproduce the NPE issues the test was designed to guard against. > > I think the best we can do is to ignore the OOMEs in this particular > stress test (which > runs reliably on almost all of our test systems): > > http://cr.openjdk.java.net/~redestad/8199009/jdk.00/ > > Bugs: https://bugs.openjdk.java.net/browse/JDK-8199009 > > Another option would be to remove the test, since it's "only" testing > for a very particular > coding error that I was about to commit when working on JDK-8196869.. > > Thanks! > > /Claes From xueming.shen at oracle.com Fri Mar 9 22:34:37 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 09 Mar 2018 14:34:37 -0800 Subject: RFR JDK-8196748,tools/jar tests need to tolerate unrelated warnings Message-ID: <5AA30BFD.4090604@oracle.com> Hi, Please help codereview the change for JDK-8196748. Issue: https://bugs.openjdk.java.net/browse/JDK-8196748 webrev: http://cr.openjdk.java.net/~sherman/8196748/webrev Those tests are based on parsing the std in/err of the jar command. It appears the "best wau" for now is to hardcode the filter to filter out the specific jvm warning msg case by case. Verified with the warning msg turned on as http://cr.openjdk.java.net/~sherman/8196748/webrev.hs/src/hotspot/share/runtime/arguments.cpp.sdiff.html and ran the jtreg with -XX:+FastTLABRefill. btw: tools/jar/LeadingGarbage.java is not failing in 11, so it is not touched. Thanks, Sherman From sergei.tsypanov at yandex.ru Sat Mar 10 08:42:46 2018 From: sergei.tsypanov at yandex.ru (=?utf-8?B?0KHQtdGA0LPQtdC5INCm0YvQv9Cw0L3QvtCy?=) Date: Sat, 10 Mar 2018 10:42:46 +0200 Subject: [PATCH] Duplicated indexOf/lasIndexOf in array-based collections Message-ID: <3495951520671366@web26g.yandex.ru> Hi everyone, currently array-based collections, in particular java.util.ArrayList, java.util.Arrays$ArrayList, java.util.Vector, java.util.concurrent.CopyOnWriteArrayList have duplicated code in indexOf() and lastIndexOf(). My proposal is to extract this code into java.util.Arrays helping JIT and saving space in ReservedCodeCache. Moreover, developers quite often use code snippets like Arras.asList(array).indexOf(obj) Arras.asList(array).contains(obj) or even Arrays.stream(names).anyMatch(existing -> existing.equals(name)); or write similar utility code for allocation-free cases like the one in https://github.com/hibernate/hibernate-orm/blob/0a2a5c622e3eb30724e80bc8661c0ac55ebfb2be/hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/tracker/SimpleFieldTracker.java#L40 Also see https://github.com/JetBrains/intellij-community/blob/200f59d7cf3b0f66feb3a4abebbb90864dc5edc7/platform/util/src/com/intellij/util/ArrayUtil.java#L726 https://github.com/JetBrains/intellij-community/blob/200f59d7cf3b0f66feb3a4abebbb90864dc5edc7/platform/util-rt/src/com/intellij/util/ArrayUtilRt.java#L63 https://github.com/spring-projects/spring-framework/blob/5f4d1a4628513ab34098fa3f92ba03aa20fc4204/spring-oxm/src/main/java/org/springframework/oxm/jibx/JibxMarshaller.java#L256 If java.util.Arrays incorporates contains() and indexOf() then all that boilerplate can be replaced with usage of JDK-provided standard API. Patch is attached to this mail. Regards, Sergey Tsypanov -------------- next part -------------- A non-text attachment was scrubbed... Name: indexOf.patch Type: text/x-diff Size: 12549 bytes Desc: not available URL: From peter.levart at gmail.com Sun Mar 11 09:03:31 2018 From: peter.levart at gmail.com (Peter Levart) Date: Sun, 11 Mar 2018 10:03:31 +0100 Subject: [PATCH] Reduce Chance Of Mistakenly Early Backing Memory Cleanup In-Reply-To: References: <7215566D-A8BA-4D51-8262-E70E7FA55982@oracle.com> <135224D1-153F-4544-A06D-A7D799E65F27@oracle.com> <785979c9-c2a5-29dd-aada-b7926191e132@oracle.com> Message-ID: <0b0598e4-8a47-48e1-7a68-55aa0851cd27@gmail.com> Hi, On 03/02/18 18:15, Paul Sandoz wrote: > Thanks! > Paul. > >> On Mar 2, 2018, at 9:11 AM, Vladimir Ivanov wrote: >> >> >> >> On 3/2/18 8:01 PM, Paul Sandoz wrote: >>> Here?s an update Ben and I tweaked: >>> http://cr.openjdk.java.net/~psandoz/jdk/buffer-reachability-fence/webrev/index.html >>> I think this looks good but would still like to double check with Vladimir that the @ForceInline is not problematic. >> I confirm that my previous analysis [1] still applies when method is marked w/ @ForceInline. >> >> Best regards, >> Vladimir Ivanov >> >> [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051312.html I was going to suggest to add a test for that JIT assumption, but I see there's already a test called ReachabilityFenceTest that should catch a change in JIT behavior that would break reachabilityFence(). I spotted a flaw in that test. See method fenced(): ??? public static boolean fenced() { ??????? AtomicBoolean finalized = new AtomicBoolean(); ??????? MyFinalizeable o = new MyFinalizeable(finalized); ??????? for (int i = 0; i < LOOP_ITERS; i++) { ??????????? if (finalized.get()) break; ??????????? if (i > WARMUP_LOOP_ITERS) { ??????????????? System.gc(); ??????????????? System.runFinalization(); ??????????? } ??????? } ??????? Reference.reachabilityFence(o); ??????? return finalized.get(); ??? } The last two statements should be reversed or else the test could produce a false alarm: ??? ??? boolean fin = finalized.get(); ??? ??? Reference.reachabilityFence(o); ??? ??? return fin; Regards, Peter From xuelei.fan at oracle.com Sun Mar 11 16:04:41 2018 From: xuelei.fan at oracle.com (Xuelei Fan) Date: Sun, 11 Mar 2018 09:04:41 -0700 Subject: RFR 8181594: Efficient and constant-time modular arithmetic In-Reply-To: <9021dd99-4ac1-f7a1-fc91-ab0a9cf1685b@oracle.com> References: <7bd6c1ae-4173-4384-fc57-66d1b185ba56@oracle.com> <9021dd99-4ac1-f7a1-fc91-ab0a9cf1685b@oracle.com> Message-ID: On 2/26/2018 10:39 AM, Adam Petcher wrote: > > http://cr.openjdk.java.net/~apetcher/8181594/webrev.01/ > > See inline below. > > On 2/23/2018 12:46 PM, Xuelei Fan wrote: > >> ArrayUtil.java: >> =============== >> I'm not very sure how widely this utilities will be used in the >> future. Looks like only BigIntegerModuloP uses this classes.? I may >> prefer to define private methods for byte array swap in >> BigIntegerModuloP. > > It is also used by XDHPublicKeyImpl (in the XDH code review). XDH public > keys are represented as BigInteger, and I use the array reverse method > to convert encoded keys to BigInteger. > If it is not widely used by other classes, please have these methods in the class where is get called. The sun.security.util is exported to other modules as well, we may not want to add stuff into this package unless it is really necessary. >> >> MutableIntegerModuloP.java >> ========================== >> void conditionalSwapWith(MutableIntegerModuloP b, int swap); >> As the 'swap' parameter can only be 0 or 1, could it be a boolean >> parameter? > > I couldn't come up with a way to implement this without branching when > the swap parameter is boolean. See IntegerPolynomial.conditionalSwap to > see how this is implemented in arithmetic with an int swap argument. If > you (or anyone) can think of a way to do this with boolean, let me know. > > I added a sentence to the comment above conditionalSwapWith that > describes why it is an int instead of a boolean. > I did not get the point about the need to avoid branching. Can you have more details? >> >> Except the conditionalSwapWith() method, I did not get the points why >> we need a mutable version.? Would you please have more description of >> this requirement? > > The comment above the class definition has this sentence: > > "This interface can be used to improve performance and avoid the > allocation of a large number of temporary objects." > > Do you need more information than this in the comments? The performance > motivation is so that a.add(b).multiply(c)... can be done without > allocating a new buffer for each operation. For example, without mutable > field elements, an X25519 point multiplication would allocate around > 4,300 temporary arrays totaling 350,000 bytes. If I remember correctly, > switching the X25519 implementation to mutable field elements reduced > the point multiplication time by about half. > I see your point. The benefits is obviously. OK, why you need the immutable version then? Sounds like the mutable version interface is sufficient, including performance. If an immutable version is really needed, we can have the implementation making the decision. Accordingly, the conditionalSwapWith() can be defined as optional method, if it is not required to be implemented in immutable implementation. It's confusing to me that the immutable and mutable and the base versions/interfaces mixed together. It would be nice if we can simplify the interface a little bit. For internal APIs, sometimes we don't want the same quality level as public APIs. I think this set of class will be widely used by new EC curves, ChaCha20/Poly1305, or more in the future. It would be nice if we could do it good at the beginning. >> >> >> IntegerModuloP_Base.java >> ======================== >> default byte[] addModPowerTwo(IntegerModuloP_Base b, int len) >> void addModPowerTwo(IntegerModuloP_Base b, byte[] result); >> >> For the first sign of the method names, I thought it is to calculate >> as "(this + b) ^ 2 mod m". > > To be precise, it calculates "((this % p) + (b % p)) % 2^m" (where p is > the prime that defines the field, and m is the desired length, in bits). > Note that the addition here is normal integer addition (not addition in > GF(p)). > > This operation is not used in XDH, but it is used in Poly1305 to add the > AES encryption of a nonce to a field element. So you can get more > information about this operation by reading the Poly1305 paper/RFC. > I was not meant to say the function of the method. I meant that the method name is a little bit misleading, not very straightforward to me. >> Besides, what's the benefits of the two methods?? Could we just use: >> ????? this.add(b).asByteArray() > > No, because that would calculate "((this + b) mod p) mod 2^m". The value > of (this + b) can be larger than p, so this would not produce the > desired result. > >> >> I guess, but not very sure, it is for constant time calculation. If >> the function is required, could it be renamed as: >> >> ????? // the result is inside of the size range >> ????? IntegerModuloP addModSize(IntegerModuloP_Base b, int size) >> Or >> ????? // the result is wrapped if outside of the size range >> ????? IntegerModuloP addOnWrap(IntegerModuloP_Base b, int size) >> >> and the use may look like: >> ????? this.addModSize(b, size).asByteArray() >> > > Any attempt to perform the addition in IntegerModuloP and then pull out > the byte array will not work. Does it mean if I perform a addition, and cannot get the byte array in the following step? that = this.add(b); byte[] bs = that.asByteArray(); // does not work? or byte[] bs = that.asByteArray(length); // does not work? or byte[] bs = that.asByteArray(byteArray); // does not work? > This class can only represent field > elements, so the sum would be in the field, which is not what we want. > I did not get the point. If getting an add result, the add is done (sum in the field). Did you have an example that pulling out the byte array will not work? Xuelei >> >> Will review the rest when I understand more about the interfaces design. >> >> Thanks, >> Xuelei >> >> On 1/30/2018 8:52 AM, Adam Petcher wrote: >>> +core-libs-dev >>> >>> >>> On 1/26/2018 4:06 PM, Adam Petcher wrote: >>>> JBS: https://bugs.openjdk.java.net/browse/JDK-8181594 >>>> Webrev: http://cr.openjdk.java.net/~apetcher/8181594/webrev.00/ >>>> >>>> This is a code review for the field arithmetic that will be used in >>>> implementations of X25519/X448 key agreement, the Poly1305 >>>> authenticator, and EdDSA signatures. I believe that the library has >>>> all the features necessary for X25519/X448 and Poly1305, and I >>>> expect at most a couple of minor enhancements will be required to >>>> support EdDSA. There is no public API for this library, so we can >>>> change it in the future to suit the needs of new algorithms without >>>> breaking compatibility with external code. Still, I made an attempt >>>> to clearly structure and document the (internal) API, and I want to >>>> make sure it is understandable and easy to use. >>>> >>>> This is not a general-purpose modular arithmetic library. It will >>>> only work well in circumstances where the sequence of operations is >>>> restricted, and where the prime that defines the field has some >>>> useful structure. Moreover, each new field will require some >>>> field-specific code that takes into account the structure of the >>>> prime and the way the field is used in the application. The initial >>>> implementation includes a field for Poly1305 and the fields for >>>> X25519/X448 which should also work for EdDSA. >>>> >>>> The benefits of using this library are that it is much more >>>> efficient than using similar operations in BigInteger. Also, many >>>> operations are branch-free, making them suitable for use in a >>>> side-channel resistant implementation that does not branch on secrets. >>>> >>>> To provide some context, I have attached a code snippet describing >>>> how this library can be used. The snippet is the constant-time >>>> Montgomery ladder from my X25519/X448 implementation, which I expect >>>> to be out for review soon. X25519/X448 only uses standard arithmetic >>>> operations, and the more unusual features (e.g. add modulo a power >>>> of 2) are needed by Poly1305. >>>> >>>> The field arithmetic (for all fields) is implemented using a 32-bit >>>> representation similar to the one described in the Ed448 paper[1] >>>> (in the "Implementation on 32-bit platforms" section). Though my >>>> implementation uses signed limbs, and grade-school multiplication >>>> instead of Karatsuba. The argument for correctness is essentially >>>> the same for all three fields: the magnitude of each 64-bit limb is >>>> at most 2^(k-1) after reduction, except for the last limb which may >>>> have a magnitude of up to 2^k. The values of k are between 26 to 28 >>>> (depending on the field), and we can calculate that the maximum >>>> magnitude for any limb during an add-multiply-carry-reduce sequence >>>> is always less than 2^63. Therefore, no overflow occurs and all >>>> operations are correct. >>>> >>>> Process note: this enhancement is part of JEP 324 (Key Agreement >>>> with Curve25519 and Curve448). When this code review is complete, >>>> nothing will happen until all other work for this JEP is complete, >>>> and the JEP is accepted as part of some release. This means that >>>> this code will be pushed to the repo along with the X25519/X448 code >>>> that uses it. >>>> >>>> [1] https://eprint.iacr.org/2015/625.pdf >>>> >>>> >>>> >>> > From david.holmes at oracle.com Mon Mar 12 02:48:19 2018 From: david.holmes at oracle.com (David Holmes) Date: Mon, 12 Mar 2018 12:48:19 +1000 Subject: RFR JDK-8196748,tools/jar tests need to tolerate unrelated warnings In-Reply-To: <5AA30BFD.4090604@oracle.com> References: <5AA30BFD.4090604@oracle.com> Message-ID: <8a381284-1c1b-ae71-c8dd-5bb8540a403a@oracle.com> Hi Sherman, On 10/03/2018 8:34 AM, Xueming Shen wrote: > Hi, > > Please help codereview the change for JDK-8196748. > > Issue: https://bugs.openjdk.java.net/browse/JDK-8196748 > webrev: http://cr.openjdk.java.net/~sherman/8196748/webrev > > Those tests are based on parsing the std in/err of the jar command. > It appears the "best wau" for now is to hardcode the filter to filter > out the specific jvm warning msg case by case. Thanks for working on this and adding the new functionality to OutputAnalyzer, but note that: + private static final String jvmwarningmsg = + "Java HotSpot\\(TM\\) 64-Bit Server VM warning:.*"; is Oracle JDK specific and 64-bit and server VM specific! Other tests use: Pattern.compile(".*VM warning.*") to exclude all VM warnings. Sorry that wasn't clear from previous discussions. > Verified with the warning msg turned on as > http://cr.openjdk.java.net/~sherman/8196748/webrev.hs/src/hotspot/share/runtime/arguments.cpp.sdiff.html > and ran the jtreg with -XX:+FastTLABRefill. That will not hit all cases as it requires the -XX:+FastTLABRefill to be passed through to all JVMs launched by tests. The original problem occurred with unconditional warnings that did not depend on a particular flag being specified on the command-line. All of those cases have now been fixed however so just reenabling the message doesn't achieve anything. I tweaked the obsolete flag table to reintroduce the failure mode: diff -r 2085742233ed src/hotspot/share/runtime/arguments.cpp --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -516,7 +516,7 @@ { "VMThreadHintNoPreempt", JDK_Version::jdk(11), JDK_Version::jdk(12), JDK_Version::jdk(13) }, { "PrintSafepointStatistics", JDK_Version::jdk(11), JDK_Version::jdk(12), JDK_Version::jdk(13) }, { "PrintSafepointStatisticsTimeout", JDK_Version::jdk(11), JDK_Version::jdk(12), JDK_Version::jdk(13) }, - { "PrintSafepointStatisticsCount",JDK_Version::jdk(11), JDK_Version::jdk(12), JDK_Version::jdk(13) }, + { "PrintSafepointStatisticsCount",JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(13) }, // --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in: { "DefaultMaxRAMFraction", JDK_Version::jdk(8), JDK_Version::undefined(), JDK_Version::undefined() }, @@ -739,7 +739,7 @@ if (!version_less_than(JDK_Version::current(), flag.obsolete_in)) { if (Flag::find_flag(flag.name) != NULL) { // Temporarily disable the warning: 8196739 - // warning("Global variable for obsolete special flag entry \"%s\" should be removed", flag.name); + warning("Global variable for obsolete special flag entry \"%s\" should be removed", flag.name); } } } @@ -749,7 +749,7 @@ if (!version_less_than(JDK_Version::current(), flag.expired_in)) { if (Flag::find_flag(flag.name) != NULL) { // Temporarily disable the warning: 8196739 - // warning("Global variable for expired flag entry \"%s\" should be removed", flag.name); + warning("Global variable for expired flag entry \"%s\" should be removed", flag.name); } } } > btw: tools/jar/LeadingGarbage.java is not failing in 11, so it is not > touched. It fails with my patch above - as per the original bug report. Thanks, David > Thanks, > Sherman From claes.redestad at oracle.com Mon Mar 12 12:37:33 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 12 Mar 2018 13:37:33 +0100 Subject: RFR: 8199453: Enable link-time generation of constructor forms Message-ID: <13d8afdb-b00f-6d58-7d4c-bced011590ce@oracle.com> Hi, I found what appears to be a simple omission from my earlier work to pre-generate LambdaForms at jlink time, in that the DIRECT_NEW_INVOKE_SPECIAL kind is never looked up nor pregenerated. Fixing that means we're covering a few more kinds of LFs at link-time and realizing a small startup optimization on first linking of constructor lambdas (Foo::new) Webrev: http://cr.openjdk.java.net/~redestad/8199453/jdk.00/ Bug:??? https://bugs.openjdk.java.net/browse/JDK-8199453 I also piled on a trivial micro-optimization to the bogusMethod, which is no longer used with more than one arg thus doesn't have to use a vararg parameter. This means an insignificant reduction in Object[] creation during bootstrap - hope noone minds.. Thanks! /Claes From Roger.Riggs at Oracle.com Mon Mar 12 14:08:26 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Mon, 12 Mar 2018 10:08:26 -0400 Subject: RFR (JDK11) 8183554: Add constructors with Charset parameter for FileReader and FileWriter In-Reply-To: <95db0276-5ca9-5e4e-7830-cdfd7f772bc4@oracle.com> References: <95db0276-5ca9-5e4e-7830-cdfd7f772bc4@oracle.com> Message-ID: <51e7c001-a868-cee4-795a-0c337a6cfe02@Oracle.com> Hi Joe, Looks good Thanks, Roger On 3/5/2018 2:25 PM, Joe Wang wrote: > Hi, > > Adding constructors with a Charset parameter for FileReader and > FileWriter. Please review. > > JBS: https://bugs.openjdk.java.net/browse/JDK-8183554 > webrev: http://cr.openjdk.java.net/~joehw/jdk11/8183554/webrev/ > > Thanks, > Joe > From Alan.Bateman at oracle.com Mon Mar 12 15:03:59 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 12 Mar 2018 15:03:59 +0000 Subject: RFR: 8199453: Enable link-time generation of constructor forms In-Reply-To: <13d8afdb-b00f-6d58-7d4c-bced011590ce@oracle.com> References: <13d8afdb-b00f-6d58-7d4c-bced011590ce@oracle.com> Message-ID: <597e536d-1cdb-6bb8-3859-a1bb8230033c@oracle.com> On 12/03/2018 12:37, Claes Redestad wrote: > Hi, > > I found what appears to be a simple omission from my earlier work to > pre-generate > LambdaForms at jlink time, in that the DIRECT_NEW_INVOKE_SPECIAL kind > is never looked > up nor pregenerated. > > Fixing that means we're covering a few more kinds of LFs at link-time > and realizing a > small startup optimization on first linking of constructor lambdas > (Foo::new) > > Webrev: http://cr.openjdk.java.net/~redestad/8199453/jdk.00/ > Bug:??? https://bugs.openjdk.java.net/browse/JDK-8199453 This looks okay to me. In case anyone wonders, this is one of several jlink plugins that are tightly coupled to java.base. They are never run when the java.base going into target run-time image doesn't have the same feature and interim version as the version that the plugins were developed for. -Alan > > I also piled on a trivial micro-optimization to the bogusMethod, which > is no longer > used with more than one arg thus doesn't have to use a vararg > parameter. This means > an insignificant reduction in Object[] creation during bootstrap - > hope noone minds.. > > Thanks! > > /Claes From claes.redestad at oracle.com Mon Mar 12 15:21:57 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 12 Mar 2018 16:21:57 +0100 Subject: RFR: 8199453: Enable link-time generation of constructor forms In-Reply-To: <597e536d-1cdb-6bb8-3859-a1bb8230033c@oracle.com> References: <13d8afdb-b00f-6d58-7d4c-bced011590ce@oracle.com> <597e536d-1cdb-6bb8-3859-a1bb8230033c@oracle.com> Message-ID: <4e57e361-2a8b-c465-28f2-f77aa02be138@oracle.com> On 2018-03-12 16:03, Alan Bateman wrote: >> >> Webrev: http://cr.openjdk.java.net/~redestad/8199453/jdk.00/ >> Bug: https://bugs.openjdk.java.net/browse/JDK-8199453 > This looks okay to me. Thanks, Alan! > > In case anyone wonders, this is one of several jlink plugins that are > tightly coupled to java.base. They are never run when the java.base > going into target run-time image doesn't have the same feature and > interim version as the version that the plugins were developed for. Right. Support for loading a different implementation of java.lang.invoke and related code into the jlink-executing JVM to generate bytecode suitable for another version of java.base would require a lot of refurbishing of some rather tricky and sensitive code. /Claes From paul.sandoz at oracle.com Mon Mar 12 15:34:03 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 12 Mar 2018 08:34:03 -0700 Subject: RFR: 8199453: Enable link-time generation of constructor forms In-Reply-To: <13d8afdb-b00f-6d58-7d4c-bced011590ce@oracle.com> References: <13d8afdb-b00f-6d58-7d4c-bced011590ce@oracle.com> Message-ID: <852CFDA4-3221-4E86-B803-2ABFACB1C5BE@oracle.com> +1 Paul. > On Mar 12, 2018, at 5:37 AM, Claes Redestad wrote: > > Hi, > > I found what appears to be a simple omission from my earlier work to pre-generate > LambdaForms at jlink time, in that the DIRECT_NEW_INVOKE_SPECIAL kind is never looked > up nor pregenerated. > > Fixing that means we're covering a few more kinds of LFs at link-time and realizing a > small startup optimization on first linking of constructor lambdas (Foo::new) > > Webrev: http://cr.openjdk.java.net/~redestad/8199453/jdk.00/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8199453 > > I also piled on a trivial micro-optimization to the bogusMethod, which is no longer > used with more than one arg thus doesn't have to use a vararg parameter. This means > an insignificant reduction in Object[] creation during bootstrap - hope noone minds.. > > Thanks! > > /Claes From huizhe.wang at oracle.com Mon Mar 12 16:05:05 2018 From: huizhe.wang at oracle.com (Joe Wang) Date: Mon, 12 Mar 2018 09:05:05 -0700 Subject: RFR (JDK11) 8183554: Add constructors with Charset parameter for FileReader and FileWriter In-Reply-To: <51e7c001-a868-cee4-795a-0c337a6cfe02@Oracle.com> References: <95db0276-5ca9-5e4e-7830-cdfd7f772bc4@oracle.com> <51e7c001-a868-cee4-795a-0c337a6cfe02@Oracle.com> Message-ID: <3c4de0cd-26e7-a53d-5c06-9a1af89ab04c@oracle.com> Thanks! Will check it in once the CSR is approved. Best, Joe On 3/12/2018 7:08 AM, Roger Riggs wrote: > Hi Joe, > > Looks good > > Thanks, Roger > > > On 3/5/2018 2:25 PM, Joe Wang wrote: >> Hi, >> >> Adding constructors with a Charset parameter for FileReader and >> FileWriter. Please review. >> >> JBS: https://bugs.openjdk.java.net/browse/JDK-8183554 >> webrev: http://cr.openjdk.java.net/~joehw/jdk11/8183554/webrev/ >> >> Thanks, >> Joe >> > From paul.sandoz at oracle.com Mon Mar 12 16:28:00 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 12 Mar 2018 09:28:00 -0700 Subject: [PATCH] Reduce Chance Of Mistakenly Early Backing Memory Cleanup In-Reply-To: <0b0598e4-8a47-48e1-7a68-55aa0851cd27@gmail.com> References: <7215566D-A8BA-4D51-8262-E70E7FA55982@oracle.com> <135224D1-153F-4544-A06D-A7D799E65F27@oracle.com> <785979c9-c2a5-29dd-aada-b7926191e132@oracle.com> <0b0598e4-8a47-48e1-7a68-55aa0851cd27@gmail.com> Message-ID: Hi Peter, Thanks, well spotted. I adjusted to: try { return finalized.get(); } finally { Reference.reachabilityFence(o); } I also created this issue: https://bugs.openjdk.java.net/browse/JDK-8199462 http://cr.openjdk.java.net/~psandoz/jdk/buffer-reachability-fence/webrev/ I will push today or tomorrow. Paul. > On Mar 11, 2018, at 1:03 AM, Peter Levart wrote: > > Hi, > > On 03/02/18 18:15, Paul Sandoz wrote: >> Thanks! >> Paul. >> >> >>> On Mar 2, 2018, at 9:11 AM, Vladimir Ivanov >>> wrote: >>> >>> >>> >>> On 3/2/18 8:01 PM, Paul Sandoz wrote: >>> >>>> Here?s an update Ben and I tweaked: >>>> >>>> http://cr.openjdk.java.net/~psandoz/jdk/buffer-reachability-fence/webrev/index.html >>>> >>>> I think this looks good but would still like to double check with Vladimir that the @ForceInline is not problematic. >>>> >>> I confirm that my previous analysis [1] still applies when method is marked w/ @ForceInline. >>> >>> Best regards, >>> Vladimir Ivanov >>> >>> [1] >>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-February/051312.html > > > I was going to suggest to add a test for that JIT assumption, but I see there's already a test called ReachabilityFenceTest that should catch a change in JIT behavior that would break reachabilityFence(). I spotted a flaw in that test. See method fenced(): > > public static boolean fenced() { > AtomicBoolean finalized = new AtomicBoolean(); > MyFinalizeable o = new MyFinalizeable(finalized); > > for (int i = 0; i < LOOP_ITERS; i++) { > if (finalized.get()) break; > if (i > WARMUP_LOOP_ITERS) { > System.gc(); > System.runFinalization(); > } > } > > Reference.reachabilityFence(o); > > return finalized.get(); > } > > > The last two statements should be reversed or else the test could produce a false alarm: > > > boolean fin = finalized.get(); > Reference.reachabilityFence(o); > return fin; > > > Regards, Peter > From mandy.chung at oracle.com Mon Mar 12 17:03:41 2018 From: mandy.chung at oracle.com (mandy chung) Date: Mon, 12 Mar 2018 10:03:41 -0700 Subject: RFR: 8199453: Enable link-time generation of constructor forms In-Reply-To: <13d8afdb-b00f-6d58-7d4c-bced011590ce@oracle.com> References: <13d8afdb-b00f-6d58-7d4c-bced011590ce@oracle.com> Message-ID: <140d632f-63b2-0b70-b03f-8e0edcfbef44@oracle.com> On 3/12/18 5:37 AM, Claes Redestad wrote: > Hi, > > I found what appears to be a simple omission from my earlier work to > pre-generate > LambdaForms at jlink time, in that the DIRECT_NEW_INVOKE_SPECIAL kind > is never looked > up nor pregenerated. > > Fixing that means we're covering a few more kinds of LFs at link-time > and realizing a > small startup optimization on first linking of constructor lambdas > (Foo::new) > > Webrev: http://cr.openjdk.java.net/~redestad/8199453/jdk.00/ > Bug:??? https://bugs.openjdk.java.net/browse/JDK-8199453 > This looks good. Mandy From claes.redestad at oracle.com Mon Mar 12 17:37:02 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 12 Mar 2018 18:37:02 +0100 Subject: RFR: 8199453: Enable link-time generation of constructor forms In-Reply-To: <140d632f-63b2-0b70-b03f-8e0edcfbef44@oracle.com> References: <13d8afdb-b00f-6d58-7d4c-bced011590ce@oracle.com> <140d632f-63b2-0b70-b03f-8e0edcfbef44@oracle.com> Message-ID: <371489b6-fc2b-6318-ef7f-f1cf227509af@oracle.com> Paul, Mandy, thanks for reviewing! Pushed. /Claes On 2018-03-12 18:03, mandy chung wrote: > > > On 3/12/18 5:37 AM, Claes Redestad wrote: >> Hi, >> >> I found what appears to be a simple omission from my earlier work to >> pre-generate >> LambdaForms at jlink time, in that the DIRECT_NEW_INVOKE_SPECIAL kind >> is never looked >> up nor pregenerated. >> >> Fixing that means we're covering a few more kinds of LFs at link-time >> and realizing a >> small startup optimization on first linking of constructor lambdas >> (Foo::new) >> >> Webrev: http://cr.openjdk.java.net/~redestad/8199453/jdk.00/ >> Bug: https://bugs.openjdk.java.net/browse/JDK-8199453 >> > > This looks good. > > Mandy > From brian.burkhalter at oracle.com Mon Mar 12 18:32:32 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Mon, 12 Mar 2018 11:32:32 -0700 Subject: RFR 8198997: Cache normalized/resolved user.dir property Message-ID: https://bugs.openjdk.java.net/browse/JDK-8198997 http://cr.openjdk.java.net/~bpb/8198997/webrev.00/ Lazily cache the value of the user.dir property on first access. This change is for Windows only as there does not appear to be any percentage in doing something similar on Unix. Thanks, Brian From claes.redestad at oracle.com Mon Mar 12 18:42:54 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 12 Mar 2018 19:42:54 +0100 Subject: RFR 8198997: Cache normalized/resolved user.dir property In-Reply-To: References: Message-ID: Hi, mixing volatiles and non-volatiles fields that are read and written to outside of synchronized makes me somewhat queasy... Instead of a volatile boolean and a mutable userDir field, couldn't this just as well be modelled as: - keep userDir final (always the not normalized value of System.getProperty("user.dir")) - replace volatile boolean isUserDirNormal with volatile String normalizedUserDir - then implement the DCL in getUserPath like: String normalizedUserDir = this.normalizedUserDir; if (normalizedUserDir == null) { ??? synchronized(userDir) { ??????? if (normalizedUserDir == null) { ??????????? normalizedUserDir = this.normalizedUserDir = normalize(userDir); ??????? } ??? } } return normalizedUserDir; WDYT? /Claes On 2018-03-12 19:32, Brian Burkhalter wrote: > https://bugs.openjdk.java.net/browse/JDK-8198997 > http://cr.openjdk.java.net/~bpb/8198997/webrev.00/ > > Lazily cache the value of the user.dir property on first access. This change is for Windows only as there does not appear to be any percentage in doing something similar on Unix. > > Thanks, > > Brian From brian.burkhalter at oracle.com Mon Mar 12 18:46:13 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Mon, 12 Mar 2018 11:46:13 -0700 Subject: RFR 8198997: Cache normalized/resolved user.dir property In-Reply-To: References: Message-ID: Hi Claes, That was what I had originally but did not post as I did not like the extra String variable increasing the memory footprint. Of course this would only be true were the user.dir accessed at all. Thanks, Brian On Mar 12, 2018, at 11:42 AM, Claes Redestad wrote: > Instead of a volatile boolean and a mutable userDir field, couldn't this just > as well be modelled as: > > - keep userDir final (always the not normalized value of System.getProperty("user.dir")) > - replace volatile boolean isUserDirNormal with volatile String normalizedUserDir > - then implement the DCL in getUserPath like: > > String normalizedUserDir = this.normalizedUserDir; > if (normalizedUserDir == null) { > synchronized(userDir) { > if (normalizedUserDir == null) { > normalizedUserDir = this.normalizedUserDir = normalize(userDir); > } > } > } > return normalizedUserDir; From claes.redestad at oracle.com Mon Mar 12 18:53:10 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 12 Mar 2018 19:53:10 +0100 Subject: RFR 8198997: Cache normalized/resolved user.dir property In-Reply-To: References: Message-ID: Hi Brian, I expect the original user.dir property to be kept resident in memory by System.properties (thus no memory loss), and going from a boolean field to an Object reference field on an object that I expect to be a singleton(?) is unlikely to be a footprint concern[1]. /Claes [1] Chances are the two approaches are footprint neutral on most archs due to padding. On 2018-03-12 19:46, Brian Burkhalter wrote: > Hi Claes, > > That was what I had originally but did not post as I did not like the > extra String variable increasing the memory footprint. Of course this > would only be true were the user.dir accessed at all. > > Thanks, > > Brian > > On Mar 12, 2018, at 11:42 AM, Claes Redestad > > wrote: > >> Instead of a volatile boolean and a mutable userDir field, couldn't >> this just >> as well be modelled as: >> >> - keep userDir final (always the not normalized value of >> System.getProperty("user.dir")) >> - replace volatile boolean isUserDirNormal with volatile String >> normalizedUserDir >> - then implement the DCL in getUserPath like: >> >> String normalizedUserDir = this.normalizedUserDir; >> if (normalizedUserDir == null) { >> synchronized(userDir) { >> ??????? if (normalizedUserDir == null) { >> normalizedUserDir = this.normalizedUserDir = normalize(userDir); >> ??????? } >> ??? } >> } >> return normalizedUserDir; > From brian.burkhalter at oracle.com Mon Mar 12 18:56:15 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Mon, 12 Mar 2018 11:56:15 -0700 Subject: RFR 8198997: Cache normalized/resolved user.dir property In-Reply-To: References: Message-ID: <997AA19E-0C9C-4DF5-B662-4BB8BDA51F91@oracle.com> Hi Clase, Thanks for the helpful observations. Given this information I would be inclined to agree with your suggested approach. Brian On Mar 12, 2018, at 11:53 AM, Claes Redestad wrote: > I expect the original user.dir property to be kept resident in memory by System.properties > (thus no memory loss), and going from a boolean field to an Object reference field on an > object that I expect to be a singleton(?) is unlikely to be a footprint concern[1]. > > /Claes > > [1] Chances are the two approaches are footprint neutral on most archs due to padding. From claes.redestad at oracle.com Mon Mar 12 18:59:39 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 12 Mar 2018 19:59:39 +0100 Subject: RFR: 8199471: Enable generation of callSiteForms at link time Message-ID: <47b2682d-141e-5124-554a-f8e3a3199242@oracle.com> Hi, LFs generated via Invokers.callSiteForm only depend on the MethodTypeForm and link type, and can be generated ahead of time by jlink --generate-jli-classes: Webrev: http://cr.openjdk.java.net/~redestad/8199471/open.00/ Bug:??? https://bugs.openjdk.java.net/browse/JDK-8199471 The current training runs done during build shows this is somewhat effective at reducing the number of LF classes we generate at runtime, avoiding spinning up up to 6 classes during bootstrap. Thanks! /Claes From xueming.shen at oracle.com Mon Mar 12 19:13:10 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Mon, 12 Mar 2018 12:13:10 -0700 Subject: RFR JDK-8196748, tools/jar tests need to tolerate unrelated warnings In-Reply-To: <8a381284-1c1b-ae71-c8dd-5bb8540a403a@oracle.com> References: <5AA30BFD.4090604@oracle.com> <8a381284-1c1b-ae71-c8dd-5bb8540a403a@oracle.com> Message-ID: <5AA6D146.1050603@oracle.com> On 3/11/18, 7:48 PM, David Holmes wrote: > Hi Sherman, > > > Thanks for working on this and adding the new functionality to > OutputAnalyzer, but note that: > > + private static final String jvmwarningmsg = > + "Java HotSpot\\(TM\\) 64-Bit Server VM warning:.*"; > > is Oracle JDK specific and 64-bit and server VM specific! Other tests > use: > > Pattern.compile(".*VM warning.*") > > to exclude all VM warnings. Sorry that wasn't clear from previous > discussions. Hi David, I was trying to be conservative to only filter out the "vm warnings" particularly for this test failure. The webrev has been updated as suggested to filter out any line with "VM warning". > >> Verified with the warning msg turned on as >> http://cr.openjdk.java.net/~sherman/8196748/webrev.hs/src/hotspot/share/runtime/arguments.cpp.sdiff.html >> >> and ran the jtreg with -XX:+FastTLABRefill. > > That will not hit all cases as it requires the -XX:+FastTLABRefill to > be passed through to all JVMs launched by tests. The original problem > occurred with unconditional warnings that did not depend on a > particular flag being specified on the command-line. All of those > cases have now been fixed however so just reenabling the message > doesn't achieve anything. The reason I did not try to turn "PrintSafepointStatisticsCount" back on (to reproduce) is that it was not included in the changeset published in JDK-8196739 as http://hg.openjdk.java.net/jdk/jdk/rev/74be5b4ed152 It appears the reason I failed to reproduce LeadingGarbage.java is the test in my repo does not forward the vm options (I'm not sure why the test forwards those vm options in your repo). I have updated the test case to use the new test.lib (it was using the "old" jdk.testlibrary), and forward the vmoptions (this one should have nothing to do with old libs or new libs though) Now the failure is reproducible and has been fixed with new method in OutputAnalyzer.java. webrev: http://cr.openjdk.java.net/~sherman/8196748/webrev (arguments.cpp will not be put back, just to help reproduce) Thanks, Sherman From paul.sandoz at oracle.com Mon Mar 12 19:23:01 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 12 Mar 2018 12:23:01 -0700 Subject: RFR 8198997: Cache normalized/resolved user.dir property In-Reply-To: References: Message-ID: > On Mar 12, 2018, at 11:42 AM, Claes Redestad wrote: > > Hi, > > mixing volatiles and non-volatiles fields that are read and written to outside of > synchronized makes me somewhat queasy? > Synchronizing on a string also makes me queasy, especially given that string can be input by the user, i dunno if there is any interning going on? It's a little dirty but you might be able to piggyback off another field e.g. those of ExpiringCache. Paul. > Instead of a volatile boolean and a mutable userDir field, couldn't this just > as well be modelled as: > > - keep userDir final (always the not normalized value of System.getProperty("user.dir")) > - replace volatile boolean isUserDirNormal with volatile String normalizedUserDir > - then implement the DCL in getUserPath like: > > String normalizedUserDir = this.normalizedUserDir; > if (normalizedUserDir == null) { > synchronized(userDir) { > if (normalizedUserDir == null) { > normalizedUserDir = this.normalizedUserDir = normalize(userDir); > } > } > } > return normalizedUserDir; > > WDYT? > > /Claes > > On 2018-03-12 19:32, Brian Burkhalter wrote: >> https://bugs.openjdk.java.net/browse/JDK-8198997 >> http://cr.openjdk.java.net/~bpb/8198997/webrev.00/ >> >> Lazily cache the value of the user.dir property on first access. This change is for Windows only as there does not appear to be any percentage in doing something similar on Unix. >> >> Thanks, >> >> Brian > From Roger.Riggs at Oracle.com Mon Mar 12 20:30:10 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Mon, 12 Mar 2018 16:30:10 -0400 Subject: RFR 8199470 : Remove unused property file.encoding.pkg Message-ID: Please review a small cleanup of property initialization, property file.encoding.pkg is initialized but never used. Webrev: http://cr.openjdk.java.net/~rriggs/webrev-encode-pkg-8199470/index.html Issue: ? https://bugs.openjdk.java.net/browse/JDK-8199470 Thanks, Roger From xueming.shen at oracle.com Mon Mar 12 21:01:39 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Mon, 12 Mar 2018 14:01:39 -0700 Subject: RFR 8199470 : Remove unused property file.encoding.pkg In-Reply-To: References: Message-ID: <5AA6EAB3.1010009@oracle.com> +1 On 3/12/18, 1:30 PM, Roger Riggs wrote: > Please review a small cleanup of property initialization, > property file.encoding.pkg is initialized but never used. > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-encode-pkg-8199470/index.html > Issue: > https://bugs.openjdk.java.net/browse/JDK-8199470 > > Thanks, Roger From brian.burkhalter at oracle.com Mon Mar 12 21:11:02 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Mon, 12 Mar 2018 14:11:02 -0700 Subject: RFR 8199470 : Remove unused property file.encoding.pkg In-Reply-To: References: Message-ID: <011FBFB7-C577-4931-A2C1-4E2FD3C20FE4@oracle.com> +1 On Mar 12, 2018, at 1:30 PM, Roger Riggs wrote: > Please review a small cleanup of property initialization, > property file.encoding.pkg is initialized but never used. > > Webrev: > http://cr.openjdk.java.net/~rriggs/webrev-encode-pkg-8199470/index.html > Issue: > https://bugs.openjdk.java.net/browse/JDK-8199470 > > Thanks, Roger From naoto.sato at oracle.com Mon Mar 12 22:29:25 2018 From: naoto.sato at oracle.com (Naoto Sato) Date: Mon, 12 Mar 2018 15:29:25 -0700 Subject: [11] RFR: 8198989: Provide more diagnostic IAE messages Message-ID: Hi, Please review a simple fix to the following issue: https://bugs.openjdk.java.net/browse/JDK-8198989 The proposed changeset is located at: http://cr.openjdk.java.net/~naoto/8198989/webrev.00/ It simply supplies thrown IllegalArgumentException with a message with the offending argument. Naoto From lance.andersen at oracle.com Mon Mar 12 22:52:21 2018 From: lance.andersen at oracle.com (Lance Andersen) Date: Mon, 12 Mar 2018 18:52:21 -0400 Subject: [11] RFR: 8198989: Provide more diagnostic IAE messages In-Reply-To: References: Message-ID: <968DA980-9338-439F-9354-35919B6697E8@oracle.com> looks fine Naoto > On Mar 12, 2018, at 6:29 PM, Naoto Sato wrote: > > Hi, > > Please review a simple fix to the following issue: > > https://bugs.openjdk.java.net/browse/JDK-8198989 > > The proposed changeset is located at: > > http://cr.openjdk.java.net/~naoto/8198989/webrev.00/ > > It simply supplies thrown IllegalArgumentException with a message with the offending argument. > > 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 david.holmes at oracle.com Tue Mar 13 06:57:11 2018 From: david.holmes at oracle.com (David Holmes) Date: Tue, 13 Mar 2018 16:57:11 +1000 Subject: RFR JDK-8196748,tools/jar tests need to tolerate unrelated warnings In-Reply-To: <5AA6D146.1050603@oracle.com> References: <5AA30BFD.4090604@oracle.com> <8a381284-1c1b-ae71-c8dd-5bb8540a403a@oracle.com> <5AA6D146.1050603@oracle.com> Message-ID: <5b8b8832-8199-c758-2c88-abc552a29180@oracle.com> Hi Sherman, On 13/03/2018 5:13 AM, Xueming Shen wrote: > On 3/11/18, 7:48 PM, David Holmes wrote: >> Hi Sherman, >> >> >> Thanks for working on this and adding the new functionality to >> OutputAnalyzer, but note that: >> >> +?? private static final String jvmwarningmsg = >> +?????? "Java HotSpot\\(TM\\) 64-Bit Server VM warning:.*"; >> >> is Oracle JDK specific and 64-bit and server VM specific! Other tests >> use: >> >> Pattern.compile(".*VM warning.*") >> >> to exclude all VM warnings. Sorry that wasn't clear from previous >> discussions. > > Hi David, > > I was trying to be conservative to only filter out the "vm warnings" > particularly for this > test failure. The webrev has been updated as suggested to filter out any > line with > "VM warning". The issue isn't about being conservative. You need to exclude the warnings no matter what VM the test is executed on. The original code would only pass on the Oracle JDK, and 64-bit Server VM. If run on OpenJDK the warning has the form: OpenJDK 64-Bit Server VM warning: ... If run on 32-bit there's no "64-bit". If run on Client VM there's no "Server". >> >>> Verified with the warning msg turned on as >>> http://cr.openjdk.java.net/~sherman/8196748/webrev.hs/src/hotspot/share/runtime/arguments.cpp.sdiff.html >>> >>> and ran the jtreg with -XX:+FastTLABRefill. >> >> That will not hit all cases as it requires the -XX:+FastTLABRefill to >> be passed through to all JVMs launched by tests. The original problem >> occurred with unconditional warnings that did not depend on a >> particular flag being specified on the command-line. All of those >> cases have now been fixed however so just reenabling the message >> doesn't achieve anything. > > The reason I did not try to turn "PrintSafepointStatisticsCount" back on > (to reproduce) is that it was > not included in the changeset published in JDK-8196739 as > http://hg.openjdk.java.net/jdk/jdk/rev/74be5b4ed152 > > It appears the reason I failed to reproduce LeadingGarbage.java is the > test in my repo does not forward > the vm options (I'm not sure why the test forwards those vm options in > your repo). I have updated the test I think there is a misunderstanding here. It doesn't matter what flag generates the warning - I modified PrintSafepointStatisticsCount as a convenience because the flags that originally triggered this problem no longer exist as flags (and so can't trigger the problem). The flag that generates the warning does not get specified as a VM argument to jtreg and does not get passed through to any other tools or VMs launched (there's no difference between our repos). That is the key point. In its original form (before the relevant flags were actually removed) we experience unconditional warnings from the VM and every execution of the VM (whether java, javac, jar, javap etc) is affected. Your test only triggered a warning due to the use of the FastTLABRefill flag and only the VM's that are explicitly passed that flag will encounter the warning. That excluded the VM (jar?) that actually triggers the test failure. > case to use the new test.lib (it was using the "old" jdk.testlibrary), > and forward the vmoptions (this one > should have nothing to do with old libs or new libs though) Right. Good to modernize the test, but not directly related to current issue. > Now the failure is reproducible and has been fixed with new method in > OutputAnalyzer.java. > > webrev: http://cr.openjdk.java.net/~sherman/8196748/webrev test/jdk/tools/jar/modularJar/Basic.java + } else if (line.contains("Java HotSpot(TM) 64-Bit Server VM warning:")) { + continue; // ignore server vm warning see#8196748 That needs to be any VM warning as discussed. --- test/lib/process/OutputAnalyzer.java I'm not sure if "replace" is the right strategy here, if stderr may be very large. ?? The approach in JDK-8194067 was to see if the output lines matched the warning (though there are a couple of deficiencies in the way it did it). Otherwise, my only minor concern is the assumption that the VM warnings will always be on stderr. That is the default, but it can be changed. Thanks, David > (arguments.cpp will not be put back, just to help reproduce) > > Thanks, > Sherman From xueming.shen at oracle.com Tue Mar 13 07:18:45 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Tue, 13 Mar 2018 00:18:45 -0700 Subject: RFR JDK-8196748, tools/jar tests need to tolerate unrelated warnings In-Reply-To: <5b8b8832-8199-c758-2c88-abc552a29180@oracle.com> References: <5AA30BFD.4090604@oracle.com> <8a381284-1c1b-ae71-c8dd-5bb8540a403a@oracle.com> <5AA6D146.1050603@oracle.com> <5b8b8832-8199-c758-2c88-abc552a29180@oracle.com> Message-ID: <5AA77B55.5030302@oracle.com> On 3/12/18, 11:57 PM, David Holmes wrote: > > test/jdk/tools/jar/modularJar/Basic.java > > + } else if (line.contains("Java HotSpot(TM) > 64-Bit Server VM warning:")) { > + continue; // ignore server vm warning > see#8196748 > > That needs to be any VM warning as discussed. > Thanks David! Will push with update for above comment. http://cr.openjdk.java.net/~sherman/8196748/webrev/ From rachna.goel at oracle.com Tue Mar 13 09:28:21 2018 From: rachna.goel at oracle.com (Rachna Goel) Date: Tue, 13 Mar 2018 14:58:21 +0530 Subject: [11] RFR: 8191410 : Unicode 10.0.0 In-Reply-To: References: Message-ID: <6d3c2e65-c144-280d-cd31-3eeb6ed3417d@oracle.com> Hi Roger, Ivan, There is no change in algorithm as such but there has been mainly stability improvements, defects fixed, performance enhancements. e.g Updated header check, version and loading for latest binary files, Simple case mappings will be more efficient as unnecessary checking has been removed. complete list of changes can be found at: http://bugs.icu-project.org/trac/query?status=closed&resolution=fixed&resolution=fixedbyotherticket&milestone=60.1&milestone=60.2&group=project&max=999&col=id&col=summary&col=resolution&col=milestone&col=status&col=owner&col=type&col=priority&col=project&col=weeks&order=priority Also, I have incorporated suggestions given from Ivan. Kindly have a look at updated webrev: http://cr.openjdk.java.net/~rgoel/JDK-8191410/webrev.01/ Thanks, Rachna On 3/8/18 9:47 PM, Roger Riggs wrote: > Hi Rachna, > > sun/text/normalizer/NormalizerImpl.java: > > Is there a higher level description of the algorithmic changes? > > 102-105: These look like accidental changes: the space should not be > removed and the trailing "{" doesn't make sense in a comment. > > Regards, Roger > > > On 3/8/2018 6:56 AM, Rachna Goel wrote: >> Hi, >> >> Please review the proposed changes for JDK-819410. >> >> Bug : https://bugs.openjdk.java.net/browse/JDK-8191410 >> >> proposed changeset is located at : >> >> http://cr.openjdk.java.net/~rgoel/JDK-8191410/webrev/ >> >> This serves as the implementation for JEP 327. >> > -- Thanks, Rachna From james.laskey at oracle.com Tue Mar 13 13:47:29 2018 From: james.laskey at oracle.com (Jim Laskey) Date: Tue, 13 Mar 2018 10:47:29 -0300 Subject: Raw String Literal Library Support Message-ID: With the announcement of JEP 326 Raw String Literals, we would like to open up a discussion with regards to RSL library support. Below are several implemented String methods that are believed to be appropriate. Please comment on those mentioned below including recommending alternate names or signatures. Additional methods can be considered if warranted, but as always, the bar for inclusion in String is high. You should keep a couple things in mind when reviewing these methods. Methods should be applicable to all strings, not just Raw String Literals. The number of additional methods should be minimized, not adding every possible method. Don't put any emphasis on performance. That is a separate discussion. Cheers, -- Jim A. Line support. public Stream lines() Returns a stream of substrings extracted from this string partitioned by line terminators. Internally, the stream is implemented using a Spliteratorthat extracts one line at a time. The line terminators recognized are \n, \r\n and \r. This method provides versatility for the developer working with multi-line strings. Example: String string = "abc\ndef\nghi"; Stream stream = string.lines(); List list = stream.collect(Collectors.toList()); Result: [abc, def, ghi] Example: String string = "abc\ndef\nghi"; String[] array = string.lines().toArray(String[]::new); Result: [Ljava.lang.String;@33e5ccce // [abc, def, ghi] Example: String string = "abc\ndef\r\nghi\rjkl"; String platformString = string.lines().collect(joining(System.lineSeparator())); Result: abc def ghi jkl Example: String string = " abc \n def \n ghi "; String trimmedString = string.lines().map(s -> s.trim()).collect(joining("\n")); Result: abc def ghi Example: String table = `First Name Surname Phone Al Albert 555-1111 Bob Roberts 555-2222 Cal Calvin 555-3333 `; // Extract headers String firstLine = table.lines().findFirst?().orElse(""); List headings = List.of(firstLine.trim().split(`\s{2,}`)); // Build stream of maps Stream> stream = table.lines().skip(1) .map(line -> line.trim()) .filter(line -> !line.isEmpty()) .map(line -> line.split(`\s{2,}`)) .map(columns -> { List values = List.of(columns); return IntStream.range(0, headings.size()).boxed() .collect(toMap(headings::get, values::get)); }); // print all "First Name" stream.map(row -> row.get("First Name")) .forEach(name -> System.out.println(name)); Result: Al Bob Cal B. Additions to basic trim methods. In addition to margin methods trimIndent and trimMarkers described below in Section C, it would be worth introducing trimLeft and trimRight to augment the longstanding trim method. A key question is how trimLeft and trimRight should detect whitespace, because different definitions of whitespace exist in the library. trim itself uses the simple test less than or equal to the space character, a fast test but not Unicode friendly. Character.isWhitespace(codepoint) returns true if codepoint one of the following; SPACE_SEPARATOR. LINE_SEPARATOR. PARAGRAPH_SEPARATOR. '\t', U+0009 HORIZONTAL TABULATION. '\n', U+000A LINE FEED. '\u000B', U+000B VERTICAL TABULATION. '\f', U+000C FORM FEED. '\r', U+000D CARRIAGE RETURN. '\u001C', U+001C FILE SEPARATOR. '\u001D', U+001D GROUP SEPARATOR. '\u001E', U+001E RECORD SEPARATOR. '\u001F', U+001F UNIT SEPARATOR. ' ', U+0020 SPACE. (Note: that non-breaking space (\u00A0) is excluded) Character.isSpaceChar(codepoint) returns true if codepoint one of the following; SPACE_SEPARATOR. LINE_SEPARATOR. PARAGRAPH_SEPARATOR. ' ', U+0020 SPACE. '\u00A0', U+00A0 NON-BREAKING SPACE. That sets up several kinds of whitespace; trim's whitespace (TWS), Character whitespace (CWS) and the union of the two (UWS). TWS is a fast test. CWS is a slow test. UWS is fast for Latin1 and slow-ish for UTF-16. We are recommending that trimLeft and trimRight use UWS, leave trim alone to avoid breaking the world and then possibly introduce trimWhitespace that uses UWS. public String trim() Removes characters less than equal to space from the beginning and end of the string. No, change except spec clarification and links to the new trim methods. Examples: "".trim(); // "" " ".trim(); // "" " abc ".trim(); // "abc" " \u2028abc ".trim(); // "\u2028abc" public String trimWhitespace() Removes whitespace from the beginning and end of the string. Examples: "".trimWhitespace(); // "" " ".trimWhitespace(); // "" " abc ".trimWhitespace(); // "abc" " \u2028abc ".trimWhitespace(); // "abc" public String trimLeft() Removes whitespace from the beginning of the string. Examples: "".trimLeft(); // "" " ".trimLeft(); // "" " abc ".trimLeft(); // "abc " public String trimRight() Removes whitespace from the end of the string. Examples: "".trimRight(); // "" " ".trimRight(); // "" " abc ".trimRight(); // " abc" C. Margin management. With introduction of multi-line Raw String Literals, developers will have to deal with the extraneous spacing introduced by indenting and formatting string bodies. Note that for all the methods in this group, if the first line is empty then it is removed and if the last is empty then it is removed. This removal provides a means for developers that use delimiters on separate lines to bracket string bodies. Also note, that all line separators are replaced with \n. public String trimIndent() This method determines a representative line in the string body that has a non-whitespace character closest to the left margin. Once that line has been determined, the number of leading whitespaces is tallied to produce a minimal indent amount. Consequently, the result of the method is a string with the minimal indent amount removed from each line. The first line is unaffected since it is preceded by the open delimiter. The type of whitespace used (spaces or tabs) does not affect the result as long as the developer is consistent with the whitespace used. Example: String x = ` This is a line This is a line This is a line This is a line This is a line `.trimIndent(); Result: This is a line This is a line This is a line This is a line This is a line public String trimMarkers(String leftMarker, String rightMarker) Each line of the multi-line string is first trimmed. If the trimmed line contains the leftMarker at the beginning of the string then it is removed. Finally, if the line contains the rightMarker at the end of line, it is removed. Example: String x = `|This is a line| |This is a line| |This is a line|`.trimMarkers("|", "|"); Result: This is a line This is a line This is a line Example: String x = `>> This is a line >> This is a line >> This is a line`.trimMarkers(">> ", ""); Result: This is a line This is a line This is a line D. Escape management. Since Raw String Literals do not interpret Unicode escapes (\unnnn) or escape sequences (\n, \b, etc), we need to provide a scheme for developers who just want multi-line strings but still have escape sequences interpreted. public String unescape() throws MalformedEscapeException Translates each Unicode escape or escape sequence in the string into the character represented by the escape. @jls 3.3, 3.10.6 Example: `abc\u2022def\nghi`.unescape(); Result: abc?def ghi public String unescape(EscapeType... escape) throws MalformedEscapeException Selectively translates Unicode escape or escape sequence based on the escape type flags provided. public enum EscapeType { /** Backslash escape sequences based on section 3.10.6 of the * The Java™ Language Specification. * This includes sequences for backspace, horizontal tab, * line feed, form feed, carriage return, double quote, * single quote, backslash and octal escape sequences. */ BACKSLASH, // /** Unicode sequences based on section 3.3 of the * The Java™ Language Specification. * This includes sequences in the form {@code \u005Cunnnn}. */ UNICODE } Example: `abc\u2022def\nghi`.unescape(EscapeType.BACKSLASH); Result: abc\u2022def ghi Example: `abc\u2022def\nghi`.unescape(EscapeType.UNICODE); Result: abc?def\nghi Conversely, there are circumstances where the inverse is required public String escape() Translates each quote, backslash, non-graphic character or non-ASCII character into an Unicode escape or escape sequence. The method is equivalent to escape(BACKSLASH, UNICODE) . Example: `abc?def ghi`.escape(); Result: abc\u2022def\nghi public String escape(EscapeType... escape) Selectively translates each quote, backslash, non-graphic character or non-ASCII character into an Unicode escape or escape sequence based on the escape type flags provided. Example: `abc?def ghi`.escape(EscapeType.BACKSLASH); Result: abc?def\nghi Example: `abc?def ghi`.escape(EscapeType.UNICODE); Result: abc\u2022def ghi From david.lloyd at redhat.com Tue Mar 13 17:46:33 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Tue, 13 Mar 2018 12:46:33 -0500 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: <5A999CAF.3030905@oracle.com> Message-ID: Sorry all, it looks like GMail doesn't know how to keep replies with the thread when you change the subject line. The follow-up to this thread is http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-March/051960.html with only a few small changes as discussed above. On Fri, Mar 2, 2018 at 2:36 PM, David Lloyd wrote: > On Fri, Mar 2, 2018 at 2:34 PM, David Lloyd wrote: >> On Fri, Mar 2, 2018 at 12:49 PM, Xueming Shen wrote: >>> Hi David, >>> >>> (1) Deflater.deflate(Bytebuffer) >>> the api doc regarding "no_flush" appears to be the copy/paste of the >>> byte[] version >>> without being updated to the corresponding ByteBuffer? >> >> You're right, I missed that one. I've incorporated this fix locally: > > Oops, this should have been: > > --- 8< --- cut here --- 8< --- > > diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java > b/src/java.base/share/classes/java/util/zip/Deflater.java > index 524125787a8..40f0d9736e2 100644 > --- a/src/java.base/share/classes/java/util/zip/Deflater.java > +++ b/src/java.base/share/classes/java/util/zip/Deflater.java > @@ -481,9 +481,9 @@ public class Deflater { > * in order to determine if more input data is required. > * > *

This method uses {@link #NO_FLUSH} as its compression flush mode. > - * An invocation of this method of the form {@code deflater.deflate(b)} > + * An invocation of this method of the form {@code > deflater.deflate(output)} > * yields the same result as the invocation of > - * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. > + * {@code deflater.deflate(output, Deflater.NO_FLUSH)}. > * > * @param output the buffer for the compressed data > * @return the actual number of bytes of compressed data written to the > > --- 8< --- cut here --- 8< --- > > -- > - DML -- - DML From volker.simonis at gmail.com Tue Mar 13 18:30:03 2018 From: volker.simonis at gmail.com (Volker Simonis) Date: Tue, 13 Mar 2018 19:30:03 +0100 Subject: Raw String Literal Library Support In-Reply-To: References: Message-ID: On Tue, Mar 13, 2018 at 2:47 PM, Jim Laskey wrote: > With the announcement of JEP 326 Raw String Literals, we would like to open up a discussion with regards to RSL library support. Below are several implemented String methods that are believed to be appropriate. Please comment on those mentioned below including recommending alternate names or signatures. Additional methods can be considered if warranted, but as always, the bar for inclusion in String is high. > > You should keep a couple things in mind when reviewing these methods. > > Methods should be applicable to all strings, not just Raw String Literals. > > The number of additional methods should be minimized, not adding every possible method. > > Don't put any emphasis on performance. That is a separate discussion. > > Cheers, > > -- Jim > > A. Line support. > > public Stream lines() > Returns a stream of substrings extracted from this string partitioned by line terminators. Internally, the stream is implemented using a Spliteratorthat extracts one line at a time. The line terminators recognized are \n, \r\n and \r. This method provides versatility for the developer working with multi-line strings. So "lines()" will support any mix of "\n", "\r\n" and "\r" inside a single string as line terminator? Will "\n", "\r\n" and "\r" be parsed from left to right with one character look-ahead? I.e. \n = 1 newline \n\r = 2 newlines (i.e. an empty line) \n\r\n = 2 newlines (i.e. an empty line) because "\r\n" counts as a single new line \n\r\n\r = 3 newlines (i.e. two empty lines) Would it make sense to have a versions of "lines(LINE_TERM lt)" which take a single, concrete form of line terminator? > Example: > > String string = "abc\ndef\nghi"; > Stream stream = string.lines(); > List list = stream.collect(Collectors.toList()); > > Result: > > [abc, def, ghi] > > > Example: > > String string = "abc\ndef\nghi"; > String[] array = string.lines().toArray(String[]::new); > > Result: > > [Ljava.lang.String;@33e5ccce // [abc, def, ghi] > > > Example: > > String string = "abc\ndef\r\nghi\rjkl"; > String platformString = > string.lines().collect(joining(System.lineSeparator())); > > Result: > > abc > def > ghi > jkl > > > Example: > > String string = " abc \n def \n ghi "; > String trimmedString = > string.lines().map(s -> s.trim()).collect(joining("\n")); > > Result: > > abc > def > ghi > > > Example: > > String table = `First Name Surname Phone > Al Albert 555-1111 > Bob Roberts 555-2222 > Cal Calvin 555-3333 > `; > > // Extract headers > String firstLine = table.lines().findFirst().orElse(""); > List headings = List.of(firstLine.trim().split(`\s{2,}`)); > > // Build stream of maps > Stream> stream = > table.lines().skip(1) > .map(line -> line.trim()) > .filter(line -> !line.isEmpty()) > .map(line -> line.split(`\s{2,}`)) > .map(columns -> { > List values = List.of(columns); > return IntStream.range(0, headings.size()).boxed() > .collect(toMap(headings::get, values::get)); > }); > > // print all "First Name" > stream.map(row -> row.get("First Name")) > .forEach(name -> System.out.println(name)); > > Result: > > Al > Bob > Cal > B. Additions to basic trim methods. In addition to margin methods trimIndent and trimMarkers described below in Section C, it would be worth introducing trimLeft and trimRight to augment the longstanding trim method. A key question is how trimLeft and trimRight should detect whitespace, because different definitions of whitespace exist in the library. > > trim itself uses the simple test less than or equal to the space character, a fast test but not Unicode friendly. > > Character.isWhitespace(codepoint) returns true if codepoint one of the following; > > SPACE_SEPARATOR. > LINE_SEPARATOR. > PARAGRAPH_SEPARATOR. > '\t', U+0009 HORIZONTAL TABULATION. > '\n', U+000A LINE FEED. > '\u000B', U+000B VERTICAL TABULATION. > '\f', U+000C FORM FEED. > '\r', U+000D CARRIAGE RETURN. > '\u001C', U+001C FILE SEPARATOR. > '\u001D', U+001D GROUP SEPARATOR. > '\u001E', U+001E RECORD SEPARATOR. > '\u001F', U+001F UNIT SEPARATOR. > ' ', U+0020 SPACE. > (Note: that non-breaking space (\u00A0) is excluded) > > Character.isSpaceChar(codepoint) returns true if codepoint one of the following; > > SPACE_SEPARATOR. > LINE_SEPARATOR. > PARAGRAPH_SEPARATOR. > ' ', U+0020 SPACE. > '\u00A0', U+00A0 NON-BREAKING SPACE. > That sets up several kinds of whitespace; trim's whitespace (TWS), Character whitespace (CWS) and the union of the two (UWS). TWS is a fast test. CWS is a slow test. UWS is fast for Latin1 and slow-ish for UTF-16. > > We are recommending that trimLeft and trimRight use UWS, leave trim alone to avoid breaking the world and then possibly introduce trimWhitespace that uses UWS. > > public String trim() > Removes characters less than equal to space from the beginning and end of the string. No, change except spec clarification and links to the new trim methods. > Examples: > "".trim(); // "" > " ".trim(); // "" > " abc ".trim(); // "abc" > " \u2028abc ".trim(); // "\u2028abc" > public String trimWhitespace() > Removes whitespace from the beginning and end of the string. > Examples: > > "".trimWhitespace(); // "" > " ".trimWhitespace(); // "" > " abc ".trimWhitespace(); // "abc" > " \u2028abc ".trimWhitespace(); // "abc" > public String trimLeft() > Removes whitespace from the beginning of the string. > Examples: > > "".trimLeft(); // "" > " ".trimLeft(); // "" > " abc ".trimLeft(); // "abc " > public String trimRight() > Removes whitespace from the end of the string. > Examples: > > "".trimRight(); // "" > " ".trimRight(); // "" > " abc ".trimRight(); // " abc" > C. Margin management. With introduction of multi-line Raw String Literals, developers will have to deal with the extraneous spacing introduced by indenting and formatting string bodies. > > Note that for all the methods in this group, if the first line is empty then it is removed and if the last is empty then it is removed. This removal provides a means for developers that use delimiters on separate lines to bracket string bodies. Also note, that all line separators are replaced with \n. > > public String trimIndent() > This method determines a representative line in the string body that has a non-whitespace character closest to the left margin. Once that line has been determined, the number of leading whitespaces is tallied to produce a minimal indent amount. Consequently, the result of the method is a string with the minimal indent amount removed from each line. The first line is unaffected since it is preceded by the open delimiter. The type of whitespace used (spaces or tabs) does not affect the result as long as the developer is consistent with the whitespace used. > Example: > > String x = ` > This is a line > This is a line > This is a line > This is a line > This is a line > `.trimIndent(); > > Result: > > This is a line > This is a line > This is a line > This is a line > This is a line > public String trimMarkers(String leftMarker, String rightMarker) > Each line of the multi-line string is first trimmed. If the trimmed line contains the leftMarker at the beginning of the string then it is removed. Finally, if the line contains the rightMarker at the end of line, it is removed. > Example: > > String x = `|This is a line| > |This is a line| > |This is a line|`.trimMarkers("|", "|"); > Result: > > This is a line > This is a line > This is a line > > Example: > > String x = `>> This is a line > >> This is a line > >> This is a line`.trimMarkers(">> ", ""); > Result: > > This is a line > This is a line > This is a line > D. Escape management. Since Raw String Literals do not interpret Unicode escapes (\unnnn) or escape sequences (\n, \b, etc), we need to provide a scheme for developers who just want multi-line strings but still have escape sequences interpreted. > > public String unescape() throws MalformedEscapeException > Translates each Unicode escape or escape sequence in the string into the character represented by the escape. @jls 3.3, 3.10.6 > Example: > > `abc\u2022def\nghi`.unescape(); > > Result: > > abc?def > ghi > public String unescape(EscapeType... escape) throws MalformedEscapeException > Selectively translates Unicode escape or escape sequence based on the escape type flags provided. > public enum EscapeType { > /** Backslash escape sequences based on section 3.10.6 of the > * The Java™ Language Specification. > * This includes sequences for backspace, horizontal tab, > * line feed, form feed, carriage return, double quote, > * single quote, backslash and octal escape sequences. > */ > BACKSLASH, // > > /** Unicode sequences based on section 3.3 of the > * The Java™ Language Specification. > * This includes sequences in the form {@code \u005Cunnnn}. > */ > UNICODE > } > > > Example: > > `abc\u2022def\nghi`.unescape(EscapeType.BACKSLASH); > > Result: > > abc\u2022def > ghi > > > Example: > > `abc\u2022def\nghi`.unescape(EscapeType.UNICODE); > > Result: > > abc?def\nghi > Conversely, there are circumstances where the inverse is required > > public String escape() > Translates each quote, backslash, non-graphic character or non-ASCII character into an Unicode escape or escape sequence. The method is equivalent to escape(BACKSLASH, UNICODE) . > Example: > > `abc?def > ghi`.escape(); > > Result: > > abc\u2022def\nghi > public String escape(EscapeType... escape) > Selectively translates each quote, backslash, non-graphic character or non-ASCII character into an Unicode escape or escape sequence based on the escape type flags provided. > Example: > > `abc?def > ghi`.escape(EscapeType.BACKSLASH); > > Result: > > abc?def\nghi > > > Example: > > `abc?def > ghi`.escape(EscapeType.UNICODE); > > Result: > > abc\u2022def > ghi > From paul.sandoz at oracle.com Tue Mar 13 18:37:27 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 13 Mar 2018 11:37:27 -0700 Subject: RFR 8198889 Clarify the throwing of exceptions from ConstantBootstraps.invoke Message-ID: <2E4FCD92-B941-4090-B4AC-ACAF434F2EA2@oracle.com> Hi, Please review these minor tweaks to the specification of ConstantBootstraps.invoke to clarify the throwing of exceptions. This was the result of discussion with the JCK team. A CSR has also been filed and requires a reviewer. https://bugs.openjdk.java.net/browse/JDK-8199540 Thanks, Paul. diff -r 7c795d301dbf src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java --- a/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java Mon Mar 12 16:09:18 2018 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java Tue Mar 13 11:27:34 2018 -0700 @@ -104,10 +104,10 @@ * * @param lookup the lookup context describing the class performing the * operation (normally stacked by the JVM) + * @param name the name of the constant to return, which must exactly match + * an enum constant in the specified type. * @param type the {@code Class} object describing the enum type for which * a constant is to be returned - * @param name the name of the constant to return, which must exactly match - * an enum constant in the specified type. * @param The enum type for which a constant value is to be returned * @return the enum constant of the specified enum type with the * specified name @@ -208,20 +208,25 @@ /** * Returns the result of invoking a method handle with the provided * arguments. + *

+ * This method behaves as if the method handle to be invoked is the result + * of adapting the given method handle, via {@link MethodHandle#asType}, to + * adjust the return type to the desired type. * * @param lookup unused * @param name unused - * @param type the type of the value to be returned, which must be + * @param type the desired type of the value to be returned, which must be * compatible with the return type of the method handle * @param handle the method handle to be invoked * @param args the arguments to pass to the method handle, as if with * {@link MethodHandle#invokeWithArguments}. Each argument may be * {@code null}. * @return the result of invoking the method handle - * @throws WrongMethodTypeException if the handle's return type cannot be - * adjusted to the desired type - * @throws ClassCastException if an argument cannot be converted by - * reference casting + * @throws WrongMethodTypeException if the handle's method type cannot be + * adjusted to take the given number of arguments, or if the handle's return + * type cannot be adjusted to the desired type + * @throws ClassCastException if an argument or the result produced by + * invoking the handle cannot be converted by reference casting * @throws Throwable anything thrown by the method handle invocation */ public static Object invoke(MethodHandles.Lookup lookup, String name, Class type, From forax at univ-mlv.fr Tue Mar 13 18:42:10 2018 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 13 Mar 2018 19:42:10 +0100 (CET) Subject: Raw String Literal Library Support In-Reply-To: References: Message-ID: <660695362.876295.1520966530044.JavaMail.zimbra@u-pem.fr> Hi Jim, ----- Mail original ----- > De: "Jim Laskey" > ?: "core-libs-dev" > Envoy?: Mardi 13 Mars 2018 14:47:29 > Objet: Raw String Literal Library Support > With the announcement of JEP 326 Raw String Literals, we would like to open up a > discussion with regards to RSL library support. Below are several implemented > String methods that are believed to be appropriate. Please comment on those > mentioned below including recommending alternate names or signatures. > Additional methods can be considered if warranted, but as always, the bar for > inclusion in String is high. > > You should keep a couple things in mind when reviewing these methods. > > Methods should be applicable to all strings, not just Raw String Literals. > > The number of additional methods should be minimized, not adding every possible > method. > > Don't put any emphasis on performance. That is a separate discussion. > > Cheers, > > -- Jim > > A. Line support. > > public Stream lines() > Returns a stream of substrings extracted from this string partitioned by line > terminators. Internally, the stream is implemented using a Spliteratorthat > extracts one line at a time. The line terminators recognized are \n, \r\n and > \r. This method provides versatility for the developer working with multi-line > strings. it already exists :) Stream stream = Pattern.compile("\n|\r\n|\r").splitAsStream(string); R?mi From lance.andersen at oracle.com Tue Mar 13 19:12:42 2018 From: lance.andersen at oracle.com (Lance Andersen) Date: Tue, 13 Mar 2018 15:12:42 -0400 Subject: RFR 8198889 Clarify the throwing of exceptions from ConstantBootstraps.invoke In-Reply-To: <2E4FCD92-B941-4090-B4AC-ACAF434F2EA2@oracle.com> References: <2E4FCD92-B941-4090-B4AC-ACAF434F2EA2@oracle.com> Message-ID: <85D551B8-A09D-47DC-B98D-049F41A2E137@oracle.com> Changes look reasonable Paul? Best Lance > On Mar 13, 2018, at 2:37 PM, Paul Sandoz wrote: > > Hi, > > Please review these minor tweaks to the specification of ConstantBootstraps.invoke to clarify the throwing of exceptions. This was the result of discussion with the JCK team. > > A CSR has also been filed and requires a reviewer. > > https://bugs.openjdk.java.net/browse/JDK-8199540 > > Thanks, > Paul. > > diff -r 7c795d301dbf src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java > --- a/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java Mon Mar 12 16:09:18 2018 -0700 > +++ b/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java Tue Mar 13 11:27:34 2018 -0700 > @@ -104,10 +104,10 @@ > * > * @param lookup the lookup context describing the class performing the > * operation (normally stacked by the JVM) > + * @param name the name of the constant to return, which must exactly match > + * an enum constant in the specified type. > * @param type the {@code Class} object describing the enum type for which > * a constant is to be returned > - * @param name the name of the constant to return, which must exactly match > - * an enum constant in the specified type. > * @param The enum type for which a constant value is to be returned > * @return the enum constant of the specified enum type with the > * specified name > @@ -208,20 +208,25 @@ > /** > * Returns the result of invoking a method handle with the provided > * arguments. > + *

> + * This method behaves as if the method handle to be invoked is the result > + * of adapting the given method handle, via {@link MethodHandle#asType}, to > + * adjust the return type to the desired type. > * > * @param lookup unused > * @param name unused > - * @param type the type of the value to be returned, which must be > + * @param type the desired type of the value to be returned, which must be > * compatible with the return type of the method handle > * @param handle the method handle to be invoked > * @param args the arguments to pass to the method handle, as if with > * {@link MethodHandle#invokeWithArguments}. Each argument may be > * {@code null}. > * @return the result of invoking the method handle > - * @throws WrongMethodTypeException if the handle's return type cannot be > - * adjusted to the desired type > - * @throws ClassCastException if an argument cannot be converted by > - * reference casting > + * @throws WrongMethodTypeException if the handle's method type cannot be > + * adjusted to take the given number of arguments, or if the handle's return > + * type cannot be adjusted to the desired type > + * @throws ClassCastException if an argument or the result produced by > + * invoking the handle cannot be converted by reference casting > * @throws Throwable anything thrown by the method handle invocation > */ > public static Object invoke(MethodHandles.Lookup lookup, String name, Class type, > Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 Lance.Andersen at oracle.com From Alan.Bateman at oracle.com Tue Mar 13 19:24:07 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 13 Mar 2018 19:24:07 +0000 Subject: RFR 8198997: Cache normalized/resolved user.dir property In-Reply-To: References: Message-ID: On 12/03/2018 18:32, Brian Burkhalter wrote: > https://bugs.openjdk.java.net/browse/JDK-8198997 > http://cr.openjdk.java.net/~bpb/8198997/webrev.00/ > > Lazily cache the value of the user.dir property on first access. This change is for Windows only as there does not appear to be any percentage in doing something similar on Unix. > The user.dir property comes from GetCurrentDirectoryW so it will be normalized anyway. Although unsupported, I guess there may be some deployments setting this property on the command line so it is safer to normalize. As relative paths are command then it might be simpler to just change the static initializer to initialize userDir to normalize(props.getProperty("user.dir")). -Alan From paul.sandoz at oracle.com Tue Mar 13 19:32:53 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 13 Mar 2018 12:32:53 -0700 Subject: RFR: 8199471: Enable generation of callSiteForms at link time In-Reply-To: <47b2682d-141e-5124-554a-f8e3a3199242@oracle.com> References: <47b2682d-141e-5124-554a-f8e3a3199242@oracle.com> Message-ID: <0324C583-E209-4692-9518-0788C2E76697@oracle.com> Invokers.java ? Looks good. Minor comment: 664 /* Placeholder class for Invokers generated ahead of time */ 665 final class Holder {} 666 667 /* Placeholder class for callSiteForms generated ahead of time */ 668 final class CSHolder {} is it easy for you to change, for clarity, Holder to InvokersHolder and CSHolder to CallSiteHolder? Thanks, Paul. > On Mar 12, 2018, at 11:59 AM, Claes Redestad wrote: > > Hi, > > LFs generated via Invokers.callSiteForm only depend on the MethodTypeForm and link type, > and can be generated ahead of time by jlink --generate-jli-classes: > > Webrev: http://cr.openjdk.java.net/~redestad/8199471/open.00/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8199471 > > The current training runs done during build shows this is somewhat effective at reducing > the number of LF classes we generate at runtime, avoiding spinning up up to 6 classes > during bootstrap. > > Thanks! > > /Claes From brian.burkhalter at oracle.com Tue Mar 13 19:33:38 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Tue, 13 Mar 2018 12:33:38 -0700 Subject: RFR 8198997: Cache normalized/resolved user.dir property In-Reply-To: References: Message-ID: <511EF388-9569-46E2-9BF5-7EFA00281051@oracle.com> On Mar 13, 2018, at 12:24 PM, Alan Bateman wrote: > As relative paths are command then it might be simpler to just change the static initializer Static initializer or constructor? > to initialize userDir to normalize(props.getProperty("user.dir")). I was originally going to put that in the constructor but did not know about calling the normalize() instance method from the ctor. Brian From mark at talios.com Tue Mar 13 20:54:44 2018 From: mark at talios.com (Mark Derricutt) Date: Wed, 14 Mar 2018 09:54:44 +1300 Subject: Raw String Literal Library Support In-Reply-To: <660695362.876295.1520966530044.JavaMail.zimbra@u-pem.fr> References: <660695362.876295.1520966530044.JavaMail.zimbra@u-pem.fr> Message-ID: On 14 Mar 2018, at 7:42, Remi Forax wrote: > it already exists :) > Stream stream = Pattern.compile("\n|\r\n|\r").splitAsStream(string); > > R?mi One that worked, or had support for grey-space would be a nice addition when working with RSL tho, unless grey-space is automatically handled at the compiler level ( don't believe I saw that mentioned anywhere ). Mark --- "The ease with which a change can be implemented has no relevance at all to whether it is the right change for the (Java) Platform for all time." — Mark Reinhold. Mark Derricutt http://www.theoryinpractice.net http://www.chaliceofblood.net http://plus.google.com/+MarkDerricutt http://twitter.com/talios http://facebook.com/mderricutt From mandy.chung at oracle.com Tue Mar 13 21:56:02 2018 From: mandy.chung at oracle.com (mandy chung) Date: Tue, 13 Mar 2018 14:56:02 -0700 Subject: RFR 8198889 Clarify the throwing of exceptions from ConstantBootstraps.invoke In-Reply-To: <2E4FCD92-B941-4090-B4AC-ACAF434F2EA2@oracle.com> References: <2E4FCD92-B941-4090-B4AC-ACAF434F2EA2@oracle.com> Message-ID: <11c5236b-b299-ced7-9dad-da44b1f59cda@oracle.com> +1 Mandy On 3/13/18 11:37 AM, Paul Sandoz wrote: > Hi, > > Please review these minor tweaks to the specification of ConstantBootstraps.invoke to clarify the throwing of exceptions. This was the result of discussion with the JCK team. > > A CSR has also been filed and requires a reviewer. > > https://bugs.openjdk.java.net/browse/JDK-8199540 > > Thanks, > Paul. > > diff -r 7c795d301dbf src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java > --- a/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java Mon Mar 12 16:09:18 2018 -0700 > +++ b/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java Tue Mar 13 11:27:34 2018 -0700 > @@ -104,10 +104,10 @@ > * > * @param lookup the lookup context describing the class performing the > * operation (normally stacked by the JVM) > + * @param name the name of the constant to return, which must exactly match > + * an enum constant in the specified type. > * @param type the {@code Class} object describing the enum type for which > * a constant is to be returned > - * @param name the name of the constant to return, which must exactly match > - * an enum constant in the specified type. > * @param The enum type for which a constant value is to be returned > * @return the enum constant of the specified enum type with the > * specified name > @@ -208,20 +208,25 @@ > /** > * Returns the result of invoking a method handle with the provided > * arguments. > + *

> + * This method behaves as if the method handle to be invoked is the result > + * of adapting the given method handle, via {@link MethodHandle#asType}, to > + * adjust the return type to the desired type. > * > * @param lookup unused > * @param name unused > - * @param type the type of the value to be returned, which must be > + * @param type the desired type of the value to be returned, which must be > * compatible with the return type of the method handle > * @param handle the method handle to be invoked > * @param args the arguments to pass to the method handle, as if with > * {@link MethodHandle#invokeWithArguments}. Each argument may be > * {@code null}. > * @return the result of invoking the method handle > - * @throws WrongMethodTypeException if the handle's return type cannot be > - * adjusted to the desired type > - * @throws ClassCastException if an argument cannot be converted by > - * reference casting > + * @throws WrongMethodTypeException if the handle's method type cannot be > + * adjusted to take the given number of arguments, or if the handle's return > + * type cannot be adjusted to the desired type > + * @throws ClassCastException if an argument or the result produced by > + * invoking the handle cannot be converted by reference casting > * @throws Throwable anything thrown by the method handle invocation > */ > public static Object invoke(MethodHandles.Lookup lookup, String name, Class type, > From john.r.rose at oracle.com Tue Mar 13 22:25:26 2018 From: john.r.rose at oracle.com (John Rose) Date: Tue, 13 Mar 2018 15:25:26 -0700 Subject: Raw String Literal Library Support In-Reply-To: <660695362.876295.1520966530044.JavaMail.zimbra@u-pem.fr> References: <660695362.876295.1520966530044.JavaMail.zimbra@u-pem.fr> Message-ID: <70D0FBFD-A9F0-4B1E-A691-48BE04B66535@oracle.com> On Mar 13, 2018, at 11:42 AM, Remi Forax wrote: > > it already exists :) > Stream stream = Pattern.compile("\n|\r\n|\r").splitAsStream(string); You want ` instead of " there! Somebody added support recently for `\R`, which is a more unicode-flavored version of your pattern (or just `\n`). Last time I looked it was missing; kudos to whoever added it in. There should be a fluent streamy syntax for splitting a string, string.splits(pat). Java's incomplete embrace of fluent syntax is old news, *but* there is something new here: String expression size. The raw strings are much larger than classic strings, and so they seem to need some notational assistance that doesn't always require them to be enclosed in round parens and mixed with other arguments. Having more fluent methods on String seems like a good move here. This goes beyond raw strings, and parsing is hard, but maybe there's room for richer versions of String.lines or String.splits, which can deliver both the surrounding whitespace and one or more fields, for each line (or each paragraph or whatever): public Stream matchResults(String regex) { return Pattern.compile(regex).matcher(this).results(); } The point is that a MatchResult delivers both the whole substring and any groups embedded in it as part of the match. Plus indexes, which is nice sometimes. ? John From john.r.rose at oracle.com Tue Mar 13 22:26:06 2018 From: john.r.rose at oracle.com (John Rose) Date: Tue, 13 Mar 2018 15:26:06 -0700 Subject: Raw String Literal Library Support In-Reply-To: References: Message-ID: <0C144B0D-49F9-4B4F-8323-11EA524BB5EB@oracle.com> On Mar 13, 2018, at 11:30 AM, Volker Simonis wrote: > > Would it make sense to have a versions of "lines(LINE_TERM lt)" which > take a single, concrete form of line terminator? (Regular expressions for the win!) From john.r.rose at oracle.com Tue Mar 13 22:49:16 2018 From: john.r.rose at oracle.com (John Rose) Date: Tue, 13 Mar 2018 15:49:16 -0700 Subject: Raw String Literal Library Support In-Reply-To: References: Message-ID: <9E820F71-D68B-4002-951A-23DB59EF29F5@oracle.com> On Mar 13, 2018, at 6:47 AM, Jim Laskey wrote: > > ? > A. Line support. > > public Stream lines() > Suggest factoring this as: public Stream splits(String regex) { } public Stream lines() { return splits(`\n|\r\n?`); } The reason is that "splits" is useful with several other patterns. For raw strings, splits(`\n`) is a more efficient way to get the same result (because they normalize CR NL? to NL). There's also a nifty unicode-oriented pattern splits(`\R`) which matches a larger set of line terminations. And of course splits(":") or splits(`\s`) will be old friends. A new friend might be paragraph splitting splits(`\n\n`). Splitting is old, as Remi points out, but new thing is supplying the stream-style fluent notation starting from a (potentially) large string constant. > B. Additions to basic trim methods. In addition to margin methods trimIndent and trimMarkers described below in Section C, it would be worth introducing trimLeft and trimRight to augment the longstanding trim method. A key question is how trimLeft and trimRight should detect whitespace, because different definitions of whitespace exist in the library. > ... > That sets up several kinds of whitespace; trim's whitespace (TWS), Character whitespace (CWS) and the union of the two (UWS). TWS is a fast test. CWS is a slow test. UWS is fast for Latin1 and slow-ish for UTF-16. For the record, even though we are not talking performance much, CWS is not significantly slower than UWS. You can use a 64-bit int constant for a bitmask and check for an arbitrary subset of the first 64 ASCII code points in one or two machine instructions. > We are recommending that trimLeft and trimRight use UWS, leave trim alone to avoid breaking the world and then possibly introduce trimWhitespace that uses UWS. Putting aside the performance question, I have to ask if compatibility with TWS is at all important. (Don't know the answer, suspect not.) > ? > C. Margin management. With introduction of multi-line Raw String Literals, developers will have to deal with the extraneous spacing introduced by indenting and formatting string bodies. > > Note that for all the methods in this group, if the first line is empty then it is removed and if the last is empty then it is removed. This removal provides a means for developers that use delimiters on separate lines to bracket string bodies. Also note, that all line separators are replaced with \n. (As a bonus, margin management gives a story for escaping leading and trailing backticks. If your string is a single line, surround it with pipe characters `|asdf|`. If your string is multiple lines, surround it with blank lines easy to do. Either pipes or newlines will protect backticks from merging into quotes.) There's a sort of beauty contest going on here between indents and markers. I often prefer markers, but I see how indents will often win the contest. I'll pre-emptively disagree with anyone who observes that we only need one of the two. > public String trimMarkers(String leftMarker, String rightMarker) I like this function and anticipate using it. (I use similar things in shell script here-files.) Thanks for including end-of-line markers in the mix. This allows lines with significant *trailing* whitespace to protect that whitespace as well as *leading* whitespace. Suggestion: Give users a gentle nudge toward the pipe character by making it a default argument so trimMarkers() => trimMarkers("|","|"). Suggestion: Allow the markers to be regular expressions. (So `\|` would be the default.) > > D. Escape management. Since Raw String Literals do not interpret Unicode escapes (\unnnn) or escape sequences (\n, \b, etc), we need to provide a scheme for developers who just want multi-line strings but still have escape sequences interpreted. This all looks good. Thanks, ? John From david.lloyd at redhat.com Tue Mar 13 23:06:01 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Tue, 13 Mar 2018 18:06:01 -0500 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods Message-ID: I worked up a little patch for 8188240. I was able to co-opt an existing test which now fails before the patch and passes after. It's a tiny patch so I'm including it inline. I've CC'd Mandy because she filed the original bug. Here's the patch (use patch -p1 to apply): -------- cut ------- 8< ------- cut -------- diff --git a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java index cc8dbbfffab..465a5b938e3 100644 --- a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java +++ b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java @@ -449,7 +449,9 @@ class ProxyGenerator { */ for (Class intf : interfaces) { for (Method m : intf.getMethods()) { - addProxyMethod(m, intf); + if (! Modifier.isStatic(m.getModifiers())) { + addProxyMethod(m, intf); + } } } diff --git a/test/jdk/java/lang/reflect/Proxy/Basic1.java b/test/jdk/java/lang/reflect/Proxy/Basic1.java index b2440ccd9f9..4a21470b1be 100644 --- a/test/jdk/java/lang/reflect/Proxy/Basic1.java +++ b/test/jdk/java/lang/reflect/Proxy/Basic1.java @@ -36,6 +36,10 @@ import java.util.*; public class Basic1 { + public interface ClashWithRunnable { + static int run() { return 123; } + } + public static void main(String[] args) { System.err.println( @@ -43,7 +47,7 @@ public class Basic1 { try { Class[] interfaces = - new Class[] { Runnable.class, Observer.class }; + new Class[] { ClashWithRunnable.class, Runnable.class, Observer.class }; ClassLoader loader = ClassLoader.getSystemClassLoader(); -------- cut ------- 8< ------- cut -------- -- - DML From brian.burkhalter at oracle.com Tue Mar 13 23:14:07 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Tue, 13 Mar 2018 16:14:07 -0700 Subject: RFR 8189230: JDK method:java.lang.Integer.numberOfLeadingZeros(int) can be optimized Message-ID: <37E91DDA-4CB5-4F85-B164-CBDD19A5E214@oracle.com> https://bugs.openjdk.java.net/browse/JDK-8189230 The change included below improves the performance of {Integer,Long}.numberOfLeadingZeros primarily for negative parameters by 20% to 33% as measured by JMH benchmarks. For details please refer to the bug report. Although on certain platforms there could be an intrinsic for the methods in question, given the simplicity of the change it seems worth making. Thanks, Brian --- a/src/java.base/share/classes/java/lang/Integer.java +++ b/src/java.base/share/classes/java/lang/Integer.java @@ -1625,8 +1625,8 @@ @HotSpotIntrinsicCandidate public static int numberOfLeadingZeros(int i) { // HD, Figure 5-6 - if (i == 0) - return 32; + if (i <= 0) + return i == 0 ? 32 : 0; int n = 1; if (i >>> 16 == 0) { n += 16; i <<= 16; } if (i >>> 24 == 0) { n += 8; i <<= 8; } --- a/src/java.base/share/classes/java/lang/Long.java +++ b/src/java.base/share/classes/java/lang/Long.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1771,8 +1771,8 @@ @HotSpotIntrinsicCandidate public static int numberOfLeadingZeros(long i) { // HD, Figure 5-6 - if (i == 0) - return 64; + if (i <= 0) + return i == 0 ? 64 : 0; int n = 1; int x = (int)(i >>> 32); if (x == 0) { n += 32; x = (int)i; } From paul.sandoz at oracle.com Tue Mar 13 23:22:33 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 13 Mar 2018 16:22:33 -0700 Subject: Raw String Literal Library Support In-Reply-To: <9E820F71-D68B-4002-951A-23DB59EF29F5@oracle.com> References: <9E820F71-D68B-4002-951A-23DB59EF29F5@oracle.com> Message-ID: > On Mar 13, 2018, at 3:49 PM, John Rose wrote: > > On Mar 13, 2018, at 6:47 AM, Jim Laskey wrote: >> >> ? >> A. Line support. >> >> public Stream lines() >> > > Suggest factoring this as: > > public Stream splits(String regex) { } +1 This is a natural companion to the existing array returning method (as it was the case on Pattern when we added splitAsStream), where one can use a limit() operation to achieve the same effect as the limit parameter on the array returning method. > public Stream lines() { return splits(`\n|\r\n?`); } > See also Files/BufferedReader.lines. (Without going into details Files.lines has some interesting optimizations.) Paul. From mandy.chung at oracle.com Tue Mar 13 23:31:09 2018 From: mandy.chung at oracle.com (mandy chung) Date: Tue, 13 Mar 2018 16:31:09 -0700 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: Message-ID: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> On 3/13/18 4:06 PM, David Lloyd wrote: > I worked up a little patch for 8188240. I was able to co-opt an > existing test which now fails before the patch and passes after. It's > a tiny patch so I'm including it inline. I've CC'd Mandy because she > filed the original bug. > > Here's the patch (use patch -p1 to apply): > > -------- cut ------- 8< ------- cut -------- > diff --git a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java > b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java > index cc8dbbfffab..465a5b938e3 100644 > --- a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java > +++ b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java > @@ -449,7 +449,9 @@ class ProxyGenerator { > */ > for (Class intf : interfaces) { > for (Method m : intf.getMethods()) { > - addProxyMethod(m, intf); > + if (! Modifier.isStatic(m.getModifiers())) { > + addProxyMethod(m, intf); > + } > } > } This looks okay. > > diff --git a/test/jdk/java/lang/reflect/Proxy/Basic1.java > b/test/jdk/java/lang/reflect/Proxy/Basic1.java > index b2440ccd9f9..4a21470b1be 100644 > --- a/test/jdk/java/lang/reflect/Proxy/Basic1.java > +++ b/test/jdk/java/lang/reflect/Proxy/Basic1.java > @@ -36,6 +36,10 @@ import java.util.*; > > public class Basic1 { > > + public interface ClashWithRunnable { > + static int run() { return 123; } > + } > + > public static void main(String[] args) { > > System.err.println( > @@ -43,7 +47,7 @@ public class Basic1 { > > try { > Class[] interfaces = > - new Class[] { Runnable.class, Observer.class }; > + new Class[] { ClashWithRunnable.class, > Runnable.class, Observer.class }; > > ClassLoader loader = ClassLoader.getSystemClassLoader(); > > -------- cut ------- 8< ------- cut -------- I prefer to keep the original test case i.e. create a proxy class from Runnable and Observer.?? Instead add a new test case to create a proxy class with ClashWithRunnable, Runnable and Observer and verify that it does not include static methods.? I would add another static method ClashWithRunnable::foo (no name clash) and verify proxyClass::getDeclaredMethods does not contain foo. Mandy From paul.sandoz at oracle.com Tue Mar 13 23:42:37 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 13 Mar 2018 16:42:37 -0700 Subject: RFR 8189230: JDK method:java.lang.Integer.numberOfLeadingZeros(int) can be optimized In-Reply-To: <37E91DDA-4CB5-4F85-B164-CBDD19A5E214@oracle.com> References: <37E91DDA-4CB5-4F85-B164-CBDD19A5E214@oracle.com> Message-ID: Given how trivial the changes are it looks ok, but not sure it really matters in practice. ? Note that it?s possible to selectively disable intrinsics. For future reference, when you want to avoid copying code if you happen to benchmark intrinsics in the future: -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_numberOfLeadingZeros_i But you have to know the intrinsic name, you can find ?em here: http://hg.openjdk.java.net/jdk/jdk/file/63eceefeb347/src/hotspot/share/classfile/vmSymbols.hpp#l805 Paul. > On Mar 13, 2018, at 4:14 PM, Brian Burkhalter wrote: > > https://bugs.openjdk.java.net/browse/JDK-8189230 > > The change included below improves the performance of {Integer,Long}.numberOfLeadingZeros primarily for negative parameters by 20% to 33% as measured by JMH benchmarks. For details please refer to the bug report. Although on certain platforms there could be an intrinsic for the methods in question, given the simplicity of the change it seems worth making. > > Thanks, > > Brian > > --- a/src/java.base/share/classes/java/lang/Integer.java > +++ b/src/java.base/share/classes/java/lang/Integer.java > @@ -1625,8 +1625,8 @@ > @HotSpotIntrinsicCandidate > public static int numberOfLeadingZeros(int i) { > // HD, Figure 5-6 > - if (i == 0) > - return 32; > + if (i <= 0) > + return i == 0 ? 32 : 0; > int n = 1; > if (i >>> 16 == 0) { n += 16; i <<= 16; } > if (i >>> 24 == 0) { n += 8; i <<= 8; } > > --- a/src/java.base/share/classes/java/lang/Long.java > +++ b/src/java.base/share/classes/java/lang/Long.java > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved. > + * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved. > * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. > * > * This code is free software; you can redistribute it and/or modify it > @@ -1771,8 +1771,8 @@ > @HotSpotIntrinsicCandidate > public static int numberOfLeadingZeros(long i) { > // HD, Figure 5-6 > - if (i == 0) > - return 64; > + if (i <= 0) > + return i == 0 ? 64 : 0; > int n = 1; > int x = (int)(i >>> 32); > if (x == 0) { n += 32; x = (int)i; } > From brian.burkhalter at oracle.com Tue Mar 13 23:44:39 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Tue, 13 Mar 2018 16:44:39 -0700 Subject: RFR 8189230: JDK method:java.lang.Integer.numberOfLeadingZeros(int) can be optimized In-Reply-To: References: <37E91DDA-4CB5-4F85-B164-CBDD19A5E214@oracle.com> Message-ID: <36E1B15F-7E8C-4C6A-9407-D34733B63CF1@oracle.com> On Mar 13, 2018, at 4:42 PM, Paul Sandoz wrote: > Given how trivial the changes are it looks ok, but not sure it really matters in practice. Nor do I. > > ? > > Note that it?s possible to selectively disable intrinsics. For future reference, when you want to avoid copying code if you happen to benchmark intrinsics in the future: > > -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_numberOfLeadingZeros_i Yes, I knew about that. > But you have to know the intrinsic name, you can find ?em here: > > http://hg.openjdk.java.net/jdk/jdk/file/63eceefeb347/src/hotspot/share/classfile/vmSymbols.hpp#l805 This latter is very helpful, thanks. Brian From jbluettduncan at gmail.com Wed Mar 14 00:12:47 2018 From: jbluettduncan at gmail.com (Jonathan Bluett-Duncan) Date: Wed, 14 Mar 2018 00:12:47 +0000 Subject: Raw String Literal Library Support In-Reply-To: References: <9E820F71-D68B-4002-951A-23DB59EF29F5@oracle.com> Message-ID: Paul, AFAICT, one sort of behaviour which String.split() allows which Pattern.splitAsStream() and the proposed String.splits() don't is allowing a negative limit, e.g. String.split(string, -1). Over at http://errorprone.info/bugpattern/StringSplitter, they argue that a limit of -1 has less surprising behaviour than the default of 0, because e.g. "".split(":") produces [] (empty array), whereas ":".split(":") produces [""] (array with an empty string), which IMO is not consistent. This compares with ":".split(":", -1) and "".split(":", -1) which produce ["", ""] (array with two empty strings, each representing ends of `:`) and [] (empty array) respectively - more consistent IMO. Should String.splits(`\n|\r\n?`) follow the behaviour of String.split(..., 0) or String.split(..., -1)? I'd personally argue for the latter. Cheers, Jonathan On 13 March 2018 at 23:22, Paul Sandoz wrote: > > > > On Mar 13, 2018, at 3:49 PM, John Rose wrote: > > > > On Mar 13, 2018, at 6:47 AM, Jim Laskey wrote: > >> > >> ? > >> A. Line support. > >> > >> public Stream lines() > >> > > > > Suggest factoring this as: > > > > public Stream splits(String regex) { } > > +1 > > This is a natural companion to the existing array returning method (as it > was the case on Pattern when we added splitAsStream), where one can use a > limit() operation to achieve the same effect as the limit parameter on the > array returning method. > > > > public Stream lines() { return splits(`\n|\r\n?`); } > > > > See also Files/BufferedReader.lines. (Without going into details > Files.lines has some interesting optimizations.) > > Paul. From david.lloyd at redhat.com Wed Mar 14 00:16:48 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Tue, 13 Mar 2018 19:16:48 -0500 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> Message-ID: On Tue, Mar 13, 2018 at 6:31 PM, mandy chung wrote: > I prefer to keep the original test case i.e. create a proxy class from > Runnable and Observer. Instead add a new test case to create a proxy class > with ClashWithRunnable, Runnable and Observer and verify that it does not > include static methods. I would add another static method > ClashWithRunnable::foo (no name clash) and verify > proxyClass::getDeclaredMethods does not contain foo. OK, done. It's a little bigger now so I'm attaching it. -- - DML -------------- next part -------------- diff --git a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java index cc8dbbfffab..465a5b938e3 100644 --- a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java +++ b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java @@ -449,7 +449,9 @@ class ProxyGenerator { */ for (Class intf : interfaces) { for (Method m : intf.getMethods()) { - addProxyMethod(m, intf); + if (! Modifier.isStatic(m.getModifiers())) { + addProxyMethod(m, intf); + } } } diff --git a/test/jdk/java/lang/reflect/Proxy/src/test/ProxyClashTest.java b/test/jdk/java/lang/reflect/Proxy/src/test/ProxyClashTest.java new file mode 100644 index 00000000000..5ad752880b3 --- /dev/null +++ b/test/jdk/java/lang/reflect/Proxy/src/test/ProxyClashTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8188240 + * @summary This is a test to ensure that proxies do not inherit static methods. + * + * @build ProxyClashTest + * @run main ProxyClashTest + */ + +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Observer; + +public class ProxyClashTest { + + public interface ClashWithRunnable { + static int run() { return 123; } + + static void foo() {} + } + + public static void main(String[] args) { + + System.err.println( + "\nDynamic proxy API static method clash test\n"); + + try { + Class[] interfaces = + new Class[] { ClashWithRunnable.class, Runnable.class, Observer.class }; + + ClassLoader loader = ClassLoader.getSystemClassLoader(); + + /* + * Generate a proxy class. + */ + Class proxyClass = Proxy.getProxyClass(loader, interfaces); + System.err.println("+ generated proxy class: " + proxyClass); + + for (Method method : proxyClass.getDeclaredMethods()) { + if (method.getName().equals("run") && method.getReturnType() == int.class) { + throw new RuntimeException("proxy inherited a static method"); + } + if (method.getName().equals("foo")) { + throw new RuntimeException("proxy inherited a static method"); + } + } + + System.err.println("\nTEST PASSED"); + + } catch (Throwable e) { + System.err.println("\nTEST FAILED:"); + e.printStackTrace(); + throw new RuntimeException("TEST FAILED: " + e.toString()); + } + } +} From david.lloyd at redhat.com Wed Mar 14 00:19:37 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Tue, 13 Mar 2018 19:19:37 -0500 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> Message-ID: On Tue, Mar 13, 2018 at 7:16 PM, David Lloyd wrote: > On Tue, Mar 13, 2018 at 6:31 PM, mandy chung wrote: >> I prefer to keep the original test case i.e. create a proxy class from >> Runnable and Observer. Instead add a new test case to create a proxy class >> with ClashWithRunnable, Runnable and Observer and verify that it does not >> include static methods. I would add another static method >> ClashWithRunnable::foo (no name clash) and verify >> proxyClass::getDeclaredMethods does not contain foo. > > OK, done. It's a little bigger now so I'm attaching it. Apologies, my IDE put it in the wrong directory. Here's a better one. I ran it by hand as jtreg and I are not presently on speaking terms. -- - DML -------------- next part -------------- diff --git a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java index cc8dbbfffab..465a5b938e3 100644 --- a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java +++ b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java @@ -449,7 +449,9 @@ class ProxyGenerator { */ for (Class intf : interfaces) { for (Method m : intf.getMethods()) { - addProxyMethod(m, intf); + if (! Modifier.isStatic(m.getModifiers())) { + addProxyMethod(m, intf); + } } } diff --git a/test/jdk/java/lang/reflect/Proxy/ProxyClashTest.java b/test/jdk/java/lang/reflect/Proxy/ProxyClashTest.java new file mode 100644 index 00000000000..5ad752880b3 --- /dev/null +++ b/test/jdk/java/lang/reflect/Proxy/ProxyClashTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8188240 + * @summary This is a test to ensure that proxies do not inherit static methods. + * + * @build ProxyClashTest + * @run main ProxyClashTest + */ + +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Observer; + +public class ProxyClashTest { + + public interface ClashWithRunnable { + static int run() { return 123; } + + static void foo() {} + } + + public static void main(String[] args) { + + System.err.println( + "\nDynamic proxy API static method clash test\n"); + + try { + Class[] interfaces = + new Class[] { ClashWithRunnable.class, Runnable.class, Observer.class }; + + ClassLoader loader = ClassLoader.getSystemClassLoader(); + + /* + * Generate a proxy class. + */ + Class proxyClass = Proxy.getProxyClass(loader, interfaces); + System.err.println("+ generated proxy class: " + proxyClass); + + for (Method method : proxyClass.getDeclaredMethods()) { + if (method.getName().equals("run") && method.getReturnType() == int.class) { + throw new RuntimeException("proxy inherited a static method"); + } + if (method.getName().equals("foo")) { + throw new RuntimeException("proxy inherited a static method"); + } + } + + System.err.println("\nTEST PASSED"); + + } catch (Throwable e) { + System.err.println("\nTEST FAILED:"); + e.printStackTrace(); + throw new RuntimeException("TEST FAILED: " + e.toString()); + } + } +} From jbluettduncan at gmail.com Wed Mar 14 00:31:29 2018 From: jbluettduncan at gmail.com (Jonathan Bluett-Duncan) Date: Wed, 14 Mar 2018 00:31:29 +0000 Subject: Raw String Literal Library Support In-Reply-To: References: <9E820F71-D68B-4002-951A-23DB59EF29F5@oracle.com> Message-ID: Sorry, I should really run things in an IDE before posting code examples and results! For examples ":".split(":", 0) and "".split(":", 0), they actually produce [] and [""] respectively (which I still argue is inconsistent and undesired for the proposed String.splits()). For examples ":".split(":", -1) and "".split(":", -1), they actually produce ["", ""] and [""] respectively, which I like better. Cheers, Jonathan On 14 March 2018 at 00:12, Jonathan Bluett-Duncan wrote: > Paul, > > AFAICT, one sort of behaviour which String.split() allows which > Pattern.splitAsStream() and the proposed String.splits() don't is allowing > a negative limit, e.g. String.split(string, -1). > > Over at http://errorprone.info/bugpattern/StringSplitter, they argue that > a limit of -1 has less surprising behaviour than the default of 0, because > e.g. "".split(":") produces [] (empty array), whereas ":".split(":") > produces [""] (array with an empty string), which IMO is not consistent. > > This compares with ":".split(":", -1) and "".split(":", -1) which produce > ["", ""] (array with two empty strings, each representing ends of `:`) and > [] (empty array) respectively - more consistent IMO. > > Should String.splits(`\n|\r\n?`) follow the behaviour of String.split(..., > 0) or String.split(..., -1)? I'd personally argue for the latter. > > Cheers, > Jonathan > > On 13 March 2018 at 23:22, Paul Sandoz wrote: > >> >> >> > On Mar 13, 2018, at 3:49 PM, John Rose wrote: >> > >> > On Mar 13, 2018, at 6:47 AM, Jim Laskey >> wrote: >> >> >> >> ? >> >> A. Line support. >> >> >> >> public Stream lines() >> >> >> > >> > Suggest factoring this as: >> > >> > public Stream splits(String regex) { } >> >> +1 >> >> This is a natural companion to the existing array returning method (as it >> was the case on Pattern when we added splitAsStream), where one can use a >> limit() operation to achieve the same effect as the limit parameter on the >> array returning method. >> >> >> > public Stream lines() { return splits(`\n|\r\n?`); } >> > >> >> See also Files/BufferedReader.lines. (Without going into details >> Files.lines has some interesting optimizations.) >> >> Paul. > > > From xueming.shen at oracle.com Wed Mar 14 01:35:02 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Tue, 13 Mar 2018 18:35:02 -0700 Subject: Raw String Literal Library Support In-Reply-To: References: <9E820F71-D68B-4002-951A-23DB59EF29F5@oracle.com> Message-ID: <5AA87C46.1070403@oracle.com> On 3/13/18, 5:12 PM, Jonathan Bluett-Duncan wrote: > Paul, > > AFAICT, one sort of behaviour which String.split() allows which > Pattern.splitAsStream() and the proposed String.splits() don't is allowing > a negative limit, e.g. String.split(string, -1). > > Over at http://errorprone.info/bugpattern/StringSplitter, they argue that a > limit of -1 has less surprising behaviour than the default of 0, because > e.g. "".split(":") produces [] (empty array), whereas ":".split(":") > produces [""] (array with an empty string), which IMO is not consistent. > > This compares with ":".split(":", -1) and "".split(":", -1) which produce > ["", ""] (array with two empty strings, each representing ends of `:`) and > [] (empty array) respectively - more consistent IMO. > > Should String.splits(`\n|\r\n?`) follow the behaviour of String.split(..., > 0) or String.split(..., -1)? I'd personally argue for the latter. While these look really confusing, but ":".split(":", n) and "".split(":", n) are really two different scenario. One is for a matched delimiter and the other is a split with no matched delimiter, in which the spec specifies clearly that it returns the original string, in this case the empty string "". Arguably these two don't have to be "consistent". Personally I think the returned list/array from string.split(regex, -1) might be kinda of "surprising" for end user, in which it has a "trailing" empty string, as it appears to be useless in most use scenario and you probably have to do some special deal with it. -Sherman > > Cheers, > Jonathan > > On 13 March 2018 at 23:22, Paul Sandoz wrote: > >> >>> On Mar 13, 2018, at 3:49 PM, John Rose wrote: >>> >>> On Mar 13, 2018, at 6:47 AM, Jim Laskey wrote: >>>> ? >>>> A. Line support. >>>> >>>> public Stream lines() >>>> >>> Suggest factoring this as: >>> >>> public Stream splits(String regex) { } >> +1 >> >> This is a natural companion to the existing array returning method (as it >> was the case on Pattern when we added splitAsStream), where one can use a >> limit() operation to achieve the same effect as the limit parameter on the >> array returning method. >> >> >>> public Stream lines() { return splits(`\n|\r\n?`); } >>> >> See also Files/BufferedReader.lines. (Without going into details >> Files.lines has some interesting optimizations.) >> >> Paul. From sundararajan.athijegannathan at oracle.com Wed Mar 14 03:32:19 2018 From: sundararajan.athijegannathan at oracle.com (Sundararajan Athijegannathan) Date: Wed, 14 Mar 2018 09:02:19 +0530 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> Message-ID: <5AA897C3.4070500@oracle.com> Looks good -Sundar On 14/03/18, 5:49 AM, David Lloyd wrote: > On Tue, Mar 13, 2018 at 7:16 PM, David Lloyd wrote: >> On Tue, Mar 13, 2018 at 6:31 PM, mandy chung wrote: >>> I prefer to keep the original test case i.e. create a proxy class from >>> Runnable and Observer. Instead add a new test case to create a proxy class >>> with ClashWithRunnable, Runnable and Observer and verify that it does not >>> include static methods. I would add another static method >>> ClashWithRunnable::foo (no name clash) and verify >>> proxyClass::getDeclaredMethods does not contain foo. >> OK, done. It's a little bigger now so I'm attaching it. > Apologies, my IDE put it in the wrong directory. Here's a better one. > I ran it by hand as jtreg and I are not presently on speaking terms. From chris.hegarty at oracle.com Wed Mar 14 12:56:55 2018 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Wed, 14 Mar 2018 12:56:55 +0000 Subject: RFR 8199464 [11] Remove remaining vestiges of Java_sun_reflect_Reflection_getCallerClass Message-ID: <55f25b38-f5c6-041a-ce18-29e28b164923@oracle.com> This is a review request to remove remaining vestiges of Java_sun_reflect_Reflection_getCallerClass. JDK-8179424 removed terminally deprecated jdk.unsupported/sun.reflect.Reflection.getCallerClass(int), these references are to the no-args getCallerClass that was removed a long time ago. These should be cleaned up anyway. diff --git a/make/mapfiles/libjava/reorder-sparc b/make/mapfiles/libjava/reorder-sparc --- a/make/mapfiles/libjava/reorder-sparc +++ b/make/mapfiles/libjava/reorder-sparc @@ -26,7 +26,6 @@ text: .text%Java_java_io_FileDescriptor_initIDs; text: .text%Java_java_io_FileOutputStream_initIDs; text: .text%Java_java_lang_System_setIn0; -text: .text%Java_sun_reflect_Reflection_getCallerClass__; text: .text%Java_java_lang_Class_forName0; text: .text%Java_java_lang_Object_getClass; text: .text%Java_sun_reflect_Reflection_getClassAccessFlags; diff --git a/make/mapfiles/libjava/reorder-sparcv9 b/make/mapfiles/libjava/reorder-sparcv9 --- a/make/mapfiles/libjava/reorder-sparcv9 +++ b/make/mapfiles/libjava/reorder-sparcv9 @@ -25,7 +25,6 @@ text: .text%Java_java_io_FileDescriptor_initIDs; text: .text%Java_java_io_FileOutputStream_initIDs; text: .text%Java_java_lang_System_setIn0; -text: .text%Java_sun_reflect_Reflection_getCallerClass__; text: .text%Java_java_lang_Class_forName0; text: .text%Java_java_lang_String_intern; text: .text%Java_java_lang_StringUTF16_isBigEndian; diff --git a/make/mapfiles/libjava/reorder-x86 b/make/mapfiles/libjava/reorder-x86 --- a/make/mapfiles/libjava/reorder-x86 +++ b/make/mapfiles/libjava/reorder-x86 @@ -26,7 +26,6 @@ text: .text%Java_java_io_FileDescriptor_initIDs; text: .text%Java_java_io_FileOutputStream_initIDs; text: .text%Java_java_lang_System_setIn0; -text: .text%Java_sun_reflect_Reflection_getCallerClass__; text: .text%Java_java_lang_Class_forName0; text: .text%Java_java_lang_String_intern; text: .text%Java_java_lang_StringUTF16_isBigEndian; -Chris. From christoph.langer at sap.com Wed Mar 14 13:02:42 2018 From: christoph.langer at sap.com (Langer, Christoph) Date: Wed, 14 Mar 2018 13:02:42 +0000 Subject: RFR 8199464 [11] Remove remaining vestiges of Java_sun_reflect_Reflection_getCallerClass In-Reply-To: <55f25b38-f5c6-041a-ce18-29e28b164923@oracle.com> References: <55f25b38-f5c6-041a-ce18-29e28b164923@oracle.com> Message-ID: <5542b73fd80246aaadd437e6dd17037e@sap.com> Looks good, Chris. > -----Original Message----- > From: core-libs-dev [mailto:core-libs-dev-bounces at openjdk.java.net] On > Behalf Of Chris Hegarty > Sent: Mittwoch, 14. M?rz 2018 13:57 > To: build-dev ; Core-Libs-Dev dev at openjdk.java.net> > Subject: RFR 8199464 [11] Remove remaining vestiges of > Java_sun_reflect_Reflection_getCallerClass > > This is a review request to remove remaining vestiges of > Java_sun_reflect_Reflection_getCallerClass. > > JDK-8179424 removed terminally deprecated > jdk.unsupported/sun.reflect.Reflection.getCallerClass(int), these > references are to the no-args getCallerClass that was removed a long > time ago. These should be cleaned up anyway. > > > diff --git a/make/mapfiles/libjava/reorder-sparc > b/make/mapfiles/libjava/reorder-sparc > --- a/make/mapfiles/libjava/reorder-sparc > +++ b/make/mapfiles/libjava/reorder-sparc > @@ -26,7 +26,6 @@ > text: .text%Java_java_io_FileDescriptor_initIDs; > text: .text%Java_java_io_FileOutputStream_initIDs; > text: .text%Java_java_lang_System_setIn0; > -text: .text%Java_sun_reflect_Reflection_getCallerClass__; > text: .text%Java_java_lang_Class_forName0; > text: .text%Java_java_lang_Object_getClass; > text: .text%Java_sun_reflect_Reflection_getClassAccessFlags; > diff --git a/make/mapfiles/libjava/reorder-sparcv9 > b/make/mapfiles/libjava/reorder-sparcv9 > --- a/make/mapfiles/libjava/reorder-sparcv9 > +++ b/make/mapfiles/libjava/reorder-sparcv9 > @@ -25,7 +25,6 @@ > text: .text%Java_java_io_FileDescriptor_initIDs; > text: .text%Java_java_io_FileOutputStream_initIDs; > text: .text%Java_java_lang_System_setIn0; > -text: .text%Java_sun_reflect_Reflection_getCallerClass__; > text: .text%Java_java_lang_Class_forName0; > text: .text%Java_java_lang_String_intern; > text: .text%Java_java_lang_StringUTF16_isBigEndian; > diff --git a/make/mapfiles/libjava/reorder-x86 > b/make/mapfiles/libjava/reorder-x86 > --- a/make/mapfiles/libjava/reorder-x86 > +++ b/make/mapfiles/libjava/reorder-x86 > @@ -26,7 +26,6 @@ > text: .text%Java_java_io_FileDescriptor_initIDs; > text: .text%Java_java_io_FileOutputStream_initIDs; > text: .text%Java_java_lang_System_setIn0; > -text: .text%Java_sun_reflect_Reflection_getCallerClass__; > text: .text%Java_java_lang_Class_forName0; > text: .text%Java_java_lang_String_intern; > text: .text%Java_java_lang_StringUTF16_isBigEndian; > > > -Chris. From Alan.Bateman at oracle.com Wed Mar 14 13:08:46 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 14 Mar 2018 13:08:46 +0000 Subject: RFR 8199464 [11] Remove remaining vestiges of Java_sun_reflect_Reflection_getCallerClass In-Reply-To: <55f25b38-f5c6-041a-ce18-29e28b164923@oracle.com> References: <55f25b38-f5c6-041a-ce18-29e28b164923@oracle.com> Message-ID: On 14/03/2018 12:56, Chris Hegarty wrote: > This is a review request to remove remaining vestiges of > Java_sun_reflect_Reflection_getCallerClass. > > JDK-8179424 removed terminally deprecated > jdk.unsupported/sun.reflect.Reflection.getCallerClass(int), these > references are to the no-args getCallerClass that was removed a long > time ago. These should be cleaned up anyway. Looks okay to me. AFAIK, the reorder- files are essentially obsolete, at least I haven't seen any updates promoted by startup benchmarks in a long time. -Alan From peter.levart at gmail.com Wed Mar 14 13:11:53 2018 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 14 Mar 2018 14:11:53 +0100 Subject: Raw String Literal Library Support In-Reply-To: <5AA87C46.1070403@oracle.com> References: <9E820F71-D68B-4002-951A-23DB59EF29F5@oracle.com> <5AA87C46.1070403@oracle.com> Message-ID: <89ff8fa6-21d1-cd6d-e007-0af036fdfebf@gmail.com> I think that: String delim = ...; String r = s.splits(Pattern.quote(delim)).collect(Collectors.joining(delim)); ... should always produce a result such that r.equals(s); Otherwise, is it wise to add methods that take a regex as a String? It is rarely needed for a regex parameter to be dynamic. Usually a constant is specified. Are there any plans for Java to support Pattern constants? With constant dynamic support they would be trivial to implement in bytecode. If there are any such plans, then the methods should perhaps take a Pattern instead. syntax suggestion: '~' is an unary operator for bit-wise negation of integer values. It could be overloaded for String(s) such that the following two were equivalent: ~ string Pattern.compile(string) Now if 'string' above is a constant, '~ string' could be a constant too. Combined with raw string literals, Pattern constants could be very compact. What do you think? Regards, Peter On 03/14/2018 02:35 AM, Xueming Shen wrote: > On 3/13/18, 5:12 PM, Jonathan Bluett-Duncan wrote: >> Paul, >> >> AFAICT, one sort of behaviour which String.split() allows which >> Pattern.splitAsStream() and the proposed String.splits() don't is >> allowing >> a negative limit, e.g. String.split(string, -1). >> >> Over at http://errorprone.info/bugpattern/StringSplitter, they argue >> that a >> limit of -1 has less surprising behaviour than the default of 0, because >> e.g. "".split(":") produces [] (empty array), whereas ":".split(":") >> produces [""] (array with an empty string), which IMO is not consistent. >> >> This compares with ":".split(":", -1) and "".split(":", -1) which >> produce >> ["", ""] (array with two empty strings, each representing ends of >> `:`) and >> [] (empty array) respectively - more consistent IMO. >> >> Should String.splits(`\n|\r\n?`) follow the behaviour of >> String.split(..., >> 0) or String.split(..., -1)?? I'd personally argue for the latter. > > While these look really confusing, but ":".split(":", n) and > "".split(":", n) are really two > different scenario. One is for a matched delimiter and the other is a > split with no > matched delimiter, in which the spec specifies clearly that it returns > the original string, > in this case the empty string "". Arguably these two don't have to be > "consistent". > > Personally I think the returned list/array from string.split(regex, > -1) might be kinda of > "surprising" for end user, in which it has a "trailing" empty string, > as it appears to be > useless in most use scenario and you probably have to do some special > deal with it. > > -Sherman > > > >> >> Cheers, >> Jonathan >> >> On 13 March 2018 at 23:22, Paul Sandoz? wrote: >> >>> >>>> On Mar 13, 2018, at 3:49 PM, John Rose? wrote: >>>> >>>> On Mar 13, 2018, at 6:47 AM, Jim Laskey? >>>> wrote: >>>>> ? >>>>> A. Line support. >>>>> >>>>> public Stream? lines() >>>>> >>>> Suggest factoring this as: >>>> >>>> public Stream? splits(String regex) { } >>> +1 >>> >>> This is a natural companion to the existing array returning method >>> (as it >>> was the case on Pattern when we added splitAsStream), where one can >>> use a >>> limit() operation to achieve the same effect as the limit parameter >>> on the >>> array returning method. >>> >>> >>>> public Stream? lines() { return splits(`\n|\r\n?`); } >>>> >>> See also Files/BufferedReader.lines. (Without going into details >>> Files.lines has some interesting optimizations.) >>> >>> Paul. > From chris.hegarty at oracle.com Wed Mar 14 13:18:21 2018 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Wed, 14 Mar 2018 13:18:21 +0000 Subject: RFR 8199464 [11] Remove remaining vestiges of Java_sun_reflect_Reflection_getCallerClass In-Reply-To: References: <55f25b38-f5c6-041a-ce18-29e28b164923@oracle.com> Message-ID: <0e2a54a6-283e-814c-6e6a-bbcfb8e1b660@oracle.com> On 14/03/18 13:08, Alan Bateman wrote: > On 14/03/2018 12:56, Chris Hegarty wrote: >> This is a review request to remove remaining vestiges of >> Java_sun_reflect_Reflection_getCallerClass. >> >> JDK-8179424 removed terminally deprecated >> jdk.unsupported/sun.reflect.Reflection.getCallerClass(int), these >> references are to the no-args getCallerClass that was removed a long >> time ago. These should be cleaned up anyway. > Looks okay to me. AFAIK, the reorder- files are essentially > obsolete, at least I haven't seen any updates promoted by startup > benchmarks in a long time. The following warning was noted recently in 8179424, so I decided to just remove these. Somebody must be still using them :-( ld: warning: mapfile: text segment: section '.text%Java_sun_reflect_Reflection_getCallerClass__' does not appear in any input file -Chris. From claes.redestad at oracle.com Wed Mar 14 14:09:33 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Wed, 14 Mar 2018 15:09:33 +0100 Subject: RFR: 8199471: Enable generation of callSiteForms at link time In-Reply-To: <0324C583-E209-4692-9518-0788C2E76697@oracle.com> References: <47b2682d-141e-5124-554a-f8e3a3199242@oracle.com> <0324C583-E209-4692-9518-0788C2E76697@oracle.com> Message-ID: <4728d996-cd1e-1e25-3466-e5bf03d1fd1a@oracle.com> Hi Paul, On 2018-03-13 20:32, Paul Sandoz wrote: > Invokers.java > ? > > Looks good. Thanks! > > Minor comment: > > 664 /* Placeholder class for Invokers generated ahead of time */ > 665 final class Holder {} > 666 > 667 /* Placeholder class for callSiteForms generated ahead of time */ > 668 final class CSHolder {} > > is it easy for you to change, for clarity, Holder to InvokersHolder and CSHolder to CallSiteHolder? I instead took a stab at consolidating these two holder classes into one, and instead of unnecessarily complicating the code (as I had feared), it actually reduced duplicated code, only slightly complicated one of the helper methods and made the patch smaller overall: http://cr.openjdk.java.net/~redestad/8199471/open.01/ /Claes From john.r.rose at oracle.com Wed Mar 14 15:25:32 2018 From: john.r.rose at oracle.com (John Rose) Date: Wed, 14 Mar 2018 08:25:32 -0700 Subject: Raw String Literal Library Support In-Reply-To: <89ff8fa6-21d1-cd6d-e007-0af036fdfebf@gmail.com> References: <9E820F71-D68B-4002-951A-23DB59EF29F5@oracle.com> <5AA87C46.1070403@oracle.com> <89ff8fa6-21d1-cd6d-e007-0af036fdfebf@gmail.com> Message-ID: <51EEA23F-1051-4F7B-B230-317D76EF11F2@oracle.com> On Mar 14, 2018, at 6:11 AM, Peter Levart wrote: > > Pattern.compile(string) > > Now if 'string' above is a constant, '~ string' could be a constant too. Combined with raw string literals, Pattern constants could be very compact. > > > What do you think? There's no need to introduce syntax in order to gain constant folding. It's enough to ensure that Pattern.compiler(constant) reduces to the ldc of a dynamic constant. We are experimenting on such ideas here: http://hg.openjdk.java.net/amber/amber/shortlog/condy-folding (This is very vaguely similar to constexpr in C++, but less static. It's early days, but enough to show that syntax isn't necessary.) ? John From brian.goetz at oracle.com Wed Mar 14 15:26:30 2018 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 14 Mar 2018 11:26:30 -0400 Subject: Raw String Literal Library Support In-Reply-To: <89ff8fa6-21d1-cd6d-e007-0af036fdfebf@gmail.com> References: <9E820F71-D68B-4002-951A-23DB59EF29F5@oracle.com> <5AA87C46.1070403@oracle.com> <89ff8fa6-21d1-cd6d-e007-0af036fdfebf@gmail.com> Message-ID: Perhaps we can "split" this discussion on splitting into a separate thread.? What's happened here is what always happens, which is: ?- Jim spent a lot of time and effort writing a comprehensive and clear proposal; ?- Someone made a tangential comment on one aspect of it; ?- Flood of deep-dive responses on that aspect; ?- Everyone chimes in designing their favorite method not proposed; ?- No one ever comes back to the substance of the proposal. Hitting the reset button... On 3/14/2018 9:11 AM, Peter Levart wrote: > I think that: > > String delim = ...; > String r = > s.splits(Pattern.quote(delim)).collect(Collectors.joining(delim)); > > ... should always produce a result such that r.equals(s); > > > Otherwise, is it wise to add methods that take a regex as a String? It > is rarely needed for a regex parameter to be dynamic. Usually a > constant is specified. Are there any plans for Java to support Pattern > constants? With constant dynamic support they would be trivial to > implement in bytecode. If there are any such plans, then the methods > should perhaps take a Pattern instead. > > syntax suggestion: > > '~' is an unary operator for bit-wise negation of integer values. It > could be overloaded for String(s) such that the following two were > equivalent: > > ~ string > Pattern.compile(string) > > Now if 'string' above is a constant, '~ string' could be a constant > too. Combined with raw string literals, Pattern constants could be > very compact. > > > What do you think? > > Regards, Peter > > On 03/14/2018 02:35 AM, Xueming Shen wrote: >> On 3/13/18, 5:12 PM, Jonathan Bluett-Duncan wrote: >>> Paul, >>> >>> AFAICT, one sort of behaviour which String.split() allows which >>> Pattern.splitAsStream() and the proposed String.splits() don't is >>> allowing >>> a negative limit, e.g. String.split(string, -1). >>> >>> Over at http://errorprone.info/bugpattern/StringSplitter, they argue >>> that a >>> limit of -1 has less surprising behaviour than the default of 0, >>> because >>> e.g. "".split(":") produces [] (empty array), whereas ":".split(":") >>> produces [""] (array with an empty string), which IMO is not >>> consistent. >>> >>> This compares with ":".split(":", -1) and "".split(":", -1) which >>> produce >>> ["", ""] (array with two empty strings, each representing ends of >>> `:`) and >>> [] (empty array) respectively - more consistent IMO. >>> >>> Should String.splits(`\n|\r\n?`) follow the behaviour of >>> String.split(..., >>> 0) or String.split(..., -1)?? I'd personally argue for the latter. >> >> While these look really confusing, but ":".split(":", n) and >> "".split(":", n) are really two >> different scenario. One is for a matched delimiter and the other is a >> split with no >> matched delimiter, in which the spec specifies clearly that it >> returns the original string, >> in this case the empty string "". Arguably these two don't have to be >> "consistent". >> >> Personally I think the returned list/array from string.split(regex, >> -1) might be kinda of >> "surprising" for end user, in which it has a "trailing" empty string, >> as it appears to be >> useless in most use scenario and you probably have to do some special >> deal with it. >> >> -Sherman >> >> >> >>> >>> Cheers, >>> Jonathan >>> >>> On 13 March 2018 at 23:22, Paul Sandoz? wrote: >>> >>>> >>>>> On Mar 13, 2018, at 3:49 PM, John Rose? >>>>> wrote: >>>>> >>>>> On Mar 13, 2018, at 6:47 AM, Jim Laskey? >>>>> wrote: >>>>>> ? >>>>>> A. Line support. >>>>>> >>>>>> public Stream? lines() >>>>>> >>>>> Suggest factoring this as: >>>>> >>>>> public Stream? splits(String regex) { } >>>> +1 >>>> >>>> This is a natural companion to the existing array returning method >>>> (as it >>>> was the case on Pattern when we added splitAsStream), where one can >>>> use a >>>> limit() operation to achieve the same effect as the limit parameter >>>> on the >>>> array returning method. >>>> >>>> >>>>> public Stream? lines() { return splits(`\n|\r\n?`); } >>>>> >>>> See also Files/BufferedReader.lines. (Without going into details >>>> Files.lines has some interesting optimizations.) >>>> >>>> Paul. >> > From paul.sandoz at oracle.com Wed Mar 14 15:29:43 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 14 Mar 2018 08:29:43 -0700 Subject: RFR: 8199471: Enable generation of callSiteForms at link time In-Reply-To: <4728d996-cd1e-1e25-3466-e5bf03d1fd1a@oracle.com> References: <47b2682d-141e-5124-554a-f8e3a3199242@oracle.com> <0324C583-E209-4692-9518-0788C2E76697@oracle.com> <4728d996-cd1e-1e25-3466-e5bf03d1fd1a@oracle.com> Message-ID: > On Mar 14, 2018, at 7:09 AM, Claes Redestad wrote: > > Hi Paul, > > On 2018-03-13 20:32, Paul Sandoz wrote: >> Invokers.java >> ? >> >> Looks good. > > Thanks! > >> >> Minor comment: >> >> 664 /* Placeholder class for Invokers generated ahead of time */ >> 665 final class Holder {} >> 666 >> 667 /* Placeholder class for callSiteForms generated ahead of time */ >> 668 final class CSHolder {} >> >> is it easy for you to change, for clarity, Holder to InvokersHolder and CSHolder to CallSiteHolder? > > I instead took a stab at consolidating these two holder classes into one, > and instead of unnecessarily complicating the code (as I had feared), it > actually reduced duplicated code, only slightly complicated one of > the helper methods and made the patch smaller overall: > > http://cr.openjdk.java.net/~redestad/8199471/open.01/ > Better! Paul. From brian.burkhalter at oracle.com Wed Mar 14 15:31:32 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 14 Mar 2018 08:31:32 -0700 Subject: RFR of 8180451: ByteArrayInputStream should override readAllBytes, readNBytes, and transferTo In-Reply-To: <37818C83-0741-42EE-AD95-6259695E2DF9@oracle.com> References: <09F39E3A-76B0-4D36-98F3-78AD246B91A7@oracle.com> <37818C83-0741-42EE-AD95-6259695E2DF9@oracle.com> Message-ID: <50B3A2D3-82B0-48DB-95D9-6318F1491725@oracle.com> Reprising this thread from three months ago [1]. A patch including the changes suggested below is at http://cr.openjdk.java.net/~bpb/8180451/webrev.01/ with the differences between this and the prior version at http://cr.openjdk.java.net/~bpb/8180451/webrev.00-01/ Thanks, Brian [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-December/050550.html On Dec 12, 2017, at 11:42 AM, Paul Sandoz wrote: > 208 public synchronized long transferTo(OutputStream out) throws IOException { > 209 int pos0 = pos; > 210 out.write(buf, pos, count - pos); > 211 pos = count; > 212 return count - pos0; > 213 } > > int len = count - pos > out.write(but, pos, len); > pos = count; > return len; On Dec 12, 2017, at 12:23 PM, Brent Christian wrote: > The changes look fine to me. > I would have found the test case a little easier to follow if "off"/"len" weren't named so similarly to "offset"/"length", but it's not a big deal. From forax at univ-mlv.fr Wed Mar 14 15:40:20 2018 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 14 Mar 2018 16:40:20 +0100 (CET) Subject: Raw String Literal Library Support In-Reply-To: References: <9E820F71-D68B-4002-951A-23DB59EF29F5@oracle.com> <5AA87C46.1070403@oracle.com> <89ff8fa6-21d1-cd6d-e007-0af036fdfebf@gmail.com> Message-ID: <1818593354.1217034.1521042020150.JavaMail.zimbra@u-pem.fr> doh, sorry for the tangential comment, it was the only comment i had, all other methods are fine. R?mi ----- Mail original ----- > De: "Brian Goetz" > ?: "Peter Levart" , "Xueming Shen" , "core-libs-dev" > > Envoy?: Mercredi 14 Mars 2018 16:26:30 > Objet: Re: Raw String Literal Library Support > Perhaps we can "split" this discussion on splitting into a separate > thread.? What's happened here is what always happens, which is: > > ?- Jim spent a lot of time and effort writing a comprehensive and clear > proposal; > ?- Someone made a tangential comment on one aspect of it; > ?- Flood of deep-dive responses on that aspect; > ?- Everyone chimes in designing their favorite method not proposed; > ?- No one ever comes back to the substance of the proposal. > > Hitting the reset button... > > > On 3/14/2018 9:11 AM, Peter Levart wrote: >> I think that: >> >> String delim = ...; >> String r = >> s.splits(Pattern.quote(delim)).collect(Collectors.joining(delim)); >> >> ... should always produce a result such that r.equals(s); >> >> >> Otherwise, is it wise to add methods that take a regex as a String? It >> is rarely needed for a regex parameter to be dynamic. Usually a >> constant is specified. Are there any plans for Java to support Pattern >> constants? With constant dynamic support they would be trivial to >> implement in bytecode. If there are any such plans, then the methods >> should perhaps take a Pattern instead. >> >> syntax suggestion: >> >> '~' is an unary operator for bit-wise negation of integer values. It >> could be overloaded for String(s) such that the following two were >> equivalent: >> >> ~ string >> Pattern.compile(string) >> >> Now if 'string' above is a constant, '~ string' could be a constant >> too. Combined with raw string literals, Pattern constants could be >> very compact. >> >> >> What do you think? >> >> Regards, Peter >> >> On 03/14/2018 02:35 AM, Xueming Shen wrote: >>> On 3/13/18, 5:12 PM, Jonathan Bluett-Duncan wrote: >>>> Paul, >>>> >>>> AFAICT, one sort of behaviour which String.split() allows which >>>> Pattern.splitAsStream() and the proposed String.splits() don't is >>>> allowing >>>> a negative limit, e.g. String.split(string, -1). >>>> >>>> Over at http://errorprone.info/bugpattern/StringSplitter, they argue >>>> that a >>>> limit of -1 has less surprising behaviour than the default of 0, >>>> because >>>> e.g. "".split(":") produces [] (empty array), whereas ":".split(":") >>>> produces [""] (array with an empty string), which IMO is not >>>> consistent. >>>> >>>> This compares with ":".split(":", -1) and "".split(":", -1) which >>>> produce >>>> ["", ""] (array with two empty strings, each representing ends of >>>> `:`) and >>>> [] (empty array) respectively - more consistent IMO. >>>> >>>> Should String.splits(`\n|\r\n?`) follow the behaviour of >>>> String.split(..., >>>> 0) or String.split(..., -1)?? I'd personally argue for the latter. >>> >>> While these look really confusing, but ":".split(":", n) and >>> "".split(":", n) are really two >>> different scenario. One is for a matched delimiter and the other is a >>> split with no >>> matched delimiter, in which the spec specifies clearly that it >>> returns the original string, >>> in this case the empty string "". Arguably these two don't have to be >>> "consistent". >>> >>> Personally I think the returned list/array from string.split(regex, >>> -1) might be kinda of >>> "surprising" for end user, in which it has a "trailing" empty string, >>> as it appears to be >>> useless in most use scenario and you probably have to do some special >>> deal with it. >>> >>> -Sherman >>> >>> >>> >>>> >>>> Cheers, >>>> Jonathan >>>> >>>> On 13 March 2018 at 23:22, Paul Sandoz? wrote: >>>> >>>>> >>>>>> On Mar 13, 2018, at 3:49 PM, John Rose >>>>>> wrote: >>>>>> >>>>>> On Mar 13, 2018, at 6:47 AM, Jim Laskey >>>>>> wrote: >>>>>>> ? >>>>>>> A. Line support. >>>>>>> >>>>>>> public Stream? lines() >>>>>>> >>>>>> Suggest factoring this as: >>>>>> >>>>>> public Stream? splits(String regex) { } >>>>> +1 >>>>> >>>>> This is a natural companion to the existing array returning method >>>>> (as it >>>>> was the case on Pattern when we added splitAsStream), where one can >>>>> use a >>>>> limit() operation to achieve the same effect as the limit parameter >>>>> on the >>>>> array returning method. >>>>> >>>>> >>>>>> public Stream? lines() { return splits(`\n|\r\n?`); } >>>>>> >>>>> See also Files/BufferedReader.lines. (Without going into details >>>>> Files.lines has some interesting optimizations.) >>>>> >>>>> Paul. >>> From mandy.chung at oracle.com Wed Mar 14 15:48:28 2018 From: mandy.chung at oracle.com (mandy chung) Date: Wed, 14 Mar 2018 08:48:28 -0700 Subject: RFR 8199464 [11] Remove remaining vestiges of Java_sun_reflect_Reflection_getCallerClass In-Reply-To: <55f25b38-f5c6-041a-ce18-29e28b164923@oracle.com> References: <55f25b38-f5c6-041a-ce18-29e28b164923@oracle.com> Message-ID: Looks okay. Mandy On 3/14/18 5:56 AM, Chris Hegarty wrote: > This is a review request to remove remaining vestiges of > Java_sun_reflect_Reflection_getCallerClass. > > JDK-8179424 removed terminally deprecated > jdk.unsupported/sun.reflect.Reflection.getCallerClass(int), these > references are to the no-args getCallerClass that was removed a long > time ago. These should be cleaned up anyway. > > > diff --git a/make/mapfiles/libjava/reorder-sparc > b/make/mapfiles/libjava/reorder-sparc > --- a/make/mapfiles/libjava/reorder-sparc > +++ b/make/mapfiles/libjava/reorder-sparc > @@ -26,7 +26,6 @@ > ?text: .text%Java_java_io_FileDescriptor_initIDs; > ?text: .text%Java_java_io_FileOutputStream_initIDs; > ?text: .text%Java_java_lang_System_setIn0; > -text: .text%Java_sun_reflect_Reflection_getCallerClass__; > ?text: .text%Java_java_lang_Class_forName0; > ?text: .text%Java_java_lang_Object_getClass; > ?text: .text%Java_sun_reflect_Reflection_getClassAccessFlags; > diff --git a/make/mapfiles/libjava/reorder-sparcv9 > b/make/mapfiles/libjava/reorder-sparcv9 > --- a/make/mapfiles/libjava/reorder-sparcv9 > +++ b/make/mapfiles/libjava/reorder-sparcv9 > @@ -25,7 +25,6 @@ > ?text: .text%Java_java_io_FileDescriptor_initIDs; > ?text: .text%Java_java_io_FileOutputStream_initIDs; > ?text: .text%Java_java_lang_System_setIn0; > -text: .text%Java_sun_reflect_Reflection_getCallerClass__; > ?text: .text%Java_java_lang_Class_forName0; > ?text: .text%Java_java_lang_String_intern; > ?text: .text%Java_java_lang_StringUTF16_isBigEndian; > diff --git a/make/mapfiles/libjava/reorder-x86 > b/make/mapfiles/libjava/reorder-x86 > --- a/make/mapfiles/libjava/reorder-x86 > +++ b/make/mapfiles/libjava/reorder-x86 > @@ -26,7 +26,6 @@ > ?text: .text%Java_java_io_FileDescriptor_initIDs; > ?text: .text%Java_java_io_FileOutputStream_initIDs; > ?text: .text%Java_java_lang_System_setIn0; > -text: .text%Java_sun_reflect_Reflection_getCallerClass__; > ?text: .text%Java_java_lang_Class_forName0; > ?text: .text%Java_java_lang_String_intern; > ?text: .text%Java_java_lang_StringUTF16_isBigEndian; > > > -Chris. From mandy.chung at oracle.com Wed Mar 14 15:55:41 2018 From: mandy.chung at oracle.com (mandy chung) Date: Wed, 14 Mar 2018 08:55:41 -0700 Subject: RFR: 8199471: Enable generation of callSiteForms at link time In-Reply-To: <4728d996-cd1e-1e25-3466-e5bf03d1fd1a@oracle.com> References: <47b2682d-141e-5124-554a-f8e3a3199242@oracle.com> <0324C583-E209-4692-9518-0788C2E76697@oracle.com> <4728d996-cd1e-1e25-3466-e5bf03d1fd1a@oracle.com> Message-ID: <80cb2b1b-6a37-9901-39fc-c1dbaad2ecca@oracle.com> On 3/14/18 7:09 AM, Claes Redestad wrote: > > http://cr.openjdk.java.net/~redestad/8199471/open.01/ > This looks fine.? The following comment needs update before you push. src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java ?101????? * Returns a {@code byte[]} representation of a class implementing ?102????? * the invoker forms for the set of supplied {@code methodTypes}. ?103????? */ ?104???? byte[] generateInvokersHolderClassBytes(String className, ?105???????????? MethodType[] invokerMethodTypes, ?106???????????? MethodType[] callSiteFormsMethodTypes); Mandy From claes.redestad at oracle.com Wed Mar 14 16:10:05 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Wed, 14 Mar 2018 17:10:05 +0100 Subject: RFR: 8199471: Enable generation of callSiteForms at link time In-Reply-To: <80cb2b1b-6a37-9901-39fc-c1dbaad2ecca@oracle.com> References: <47b2682d-141e-5124-554a-f8e3a3199242@oracle.com> <0324C583-E209-4692-9518-0788C2E76697@oracle.com> <4728d996-cd1e-1e25-3466-e5bf03d1fd1a@oracle.com> <80cb2b1b-6a37-9901-39fc-c1dbaad2ecca@oracle.com> Message-ID: <1995955d-e857-48e6-0875-0b157acd88f1@oracle.com> On 2018-03-14 16:55, mandy chung wrote: > > > On 3/14/18 7:09 AM, Claes Redestad wrote: >> >> http://cr.openjdk.java.net/~redestad/8199471/open.01/ >> > > This looks fine. Thanks! > ? The following comment needs update before you push. > > src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java > > ?101????? * Returns a {@code byte[]} representation of a class > implementing > ?102????? * the invoker forms for the set of supplied {@code methodTypes}. > ?103????? */ > ?104???? byte[] generateInvokersHolderClassBytes(String className, > ?105???????????? MethodType[] invokerMethodTypes, > ?106???????????? MethodType[] callSiteFormsMethodTypes); Will do! /Claes From david.lloyd at redhat.com Wed Mar 14 16:27:53 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 14 Mar 2018 11:27:53 -0500 Subject: RFR of 8180451: ByteArrayInputStream should override readAllBytes, readNBytes, and transferTo In-Reply-To: <50B3A2D3-82B0-48DB-95D9-6318F1491725@oracle.com> References: <09F39E3A-76B0-4D36-98F3-78AD246B91A7@oracle.com> <37818C83-0741-42EE-AD95-6259695E2DF9@oracle.com> <50B3A2D3-82B0-48DB-95D9-6318F1491725@oracle.com> Message-ID: In: @@ -196,14 +194,32 @@ return len; } + public synchronized byte[] readAllBytes() { + byte[] result = Arrays.copyOfRange(buf, pos, count); + pos = count; + return result; + } + + public synchronized int readNBytes(byte[] b, int off, int len) { + int n = read(b, off, len); + return n == -1 ? 0 : n; + } This probably doesn't need to be synchronized, though I imagine the difference would be minimal. + public synchronized long transferTo(OutputStream out) throws IOException { + int len = count - pos + out.write(but, pos, len); s/but/buf/ I guess? + pos = count; + return len; + } + On Wed, Mar 14, 2018 at 10:31 AM, Brian Burkhalter wrote: > Reprising this thread from three months ago [1]. > > A patch including the changes suggested below is at > > http://cr.openjdk.java.net/~bpb/8180451/webrev.01/ > > with the differences between this and the prior version at > > http://cr.openjdk.java.net/~bpb/8180451/webrev.00-01/ > > Thanks, > > Brian > > [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-December/050550.html > > On Dec 12, 2017, at 11:42 AM, Paul Sandoz wrote: > >> 208 public synchronized long transferTo(OutputStream out) throws IOException { >> 209 int pos0 = pos; >> 210 out.write(buf, pos, count - pos); >> 211 pos = count; >> 212 return count - pos0; >> 213 } >> >> int len = count - pos >> out.write(but, pos, len); >> pos = count; >> return len; > > On Dec 12, 2017, at 12:23 PM, Brent Christian wrote: > >> The changes look fine to me. >> I would have found the test case a little easier to follow if "off"/"len" weren't named so similarly to "offset"/"length", but it's not a big deal. > > -- - DML From brian.burkhalter at oracle.com Wed Mar 14 16:39:06 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 14 Mar 2018 09:39:06 -0700 Subject: RFR of 8180451: ByteArrayInputStream should override readAllBytes, readNBytes, and transferTo In-Reply-To: References: <09F39E3A-76B0-4D36-98F3-78AD246B91A7@oracle.com> <37818C83-0741-42EE-AD95-6259695E2DF9@oracle.com> <50B3A2D3-82B0-48DB-95D9-6318F1491725@oracle.com> Message-ID: <5344CEEE-E93E-439A-9B6D-78EBABD6630E@oracle.com> On Mar 14, 2018, at 9:27 AM, David Lloyd wrote: > + public synchronized long transferTo(OutputStream out) throws IOException { > + int len = count - pos > + out.write(but, pos, len); > > s/but/buf/ I guess? Yes, I already caught that myself. I think I generated the webrev before running tests, i.e., out of sequence. Thanks, Brian > > + pos = count; > + return len; > + } > + From brian.burkhalter at oracle.com Wed Mar 14 17:50:40 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 14 Mar 2018 10:50:40 -0700 Subject: RFR of 8180451: ByteArrayInputStream should override readAllBytes, readNBytes, and transferTo In-Reply-To: References: <09F39E3A-76B0-4D36-98F3-78AD246B91A7@oracle.com> <37818C83-0741-42EE-AD95-6259695E2DF9@oracle.com> <50B3A2D3-82B0-48DB-95D9-6318F1491725@oracle.com> Message-ID: On Mar 14, 2018, at 9:27 AM, David Lloyd wrote: > @@ -196,14 +194,32 @@ > return len; > } > > + public synchronized byte[] readAllBytes() { > + byte[] result = Arrays.copyOfRange(buf, pos, count); > + pos = count; > + return result; > + } > + > + public synchronized int readNBytes(byte[] b, int off, int len) { > + int n = read(b, off, len); > + return n == -1 ? 0 : n; > + } > > This probably doesn't need to be synchronized, though I imagine the > difference would be minimal. You are correct, it does not. > + public synchronized long transferTo(OutputStream out) throws IOException { > + int len = count - pos > + out.write(but, pos, len); > > s/but/buf/ I guess? Webrevs corrected in place: http://cr.openjdk.java.net/~bpb/8180451/webrev.00-01/ http://cr.openjdk.java.net/~bpb/8180451/webrev.01/ Thanks, Brian From mandy.chung at oracle.com Wed Mar 14 18:00:05 2018 From: mandy.chung at oracle.com (mandy chung) Date: Wed, 14 Mar 2018 11:00:05 -0700 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> Message-ID: <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> On 3/13/18 5:16 PM, David Lloyd wrote: > OK, done. It's a little bigger now so I'm attaching it. Thanks for adding the new test.?? Looks okay and some minor comment. + try { : + } catch (Throwable e) { + System.err.println("\nTEST FAILED:"); + e.printStackTrace(); + throw new RuntimeException("TEST FAILED: " + e.toString()); + } You can take out this try-catch (Basic1.java isn't be the best example to reference that is old and needs update). I assume your colleague at Red Hat will sponsor it for you? Mandy From david.lloyd at redhat.com Wed Mar 14 18:09:29 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 14 Mar 2018 13:09:29 -0500 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: On Wed, Mar 14, 2018 at 1:00 PM, mandy chung wrote: > Thanks for adding the new test. Looks okay and some minor comment. > > + try { > : > + } catch (Throwable e) { > + System.err.println("\nTEST FAILED:"); > + e.printStackTrace(); > + throw new RuntimeException("TEST FAILED: " + e.toString()); > + } > > > You can take out this try-catch (Basic1.java isn't be the best example to > reference that is old and needs update). Fixed & attached. > I assume your colleague at Red Hat will sponsor it for you? I will find out. -- - DML -------------- next part -------------- diff --git a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java index cc8dbbfffab..465a5b938e3 100644 --- a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java +++ b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java @@ -449,7 +449,9 @@ class ProxyGenerator { */ for (Class intf : interfaces) { for (Method m : intf.getMethods()) { - addProxyMethod(m, intf); + if (! Modifier.isStatic(m.getModifiers())) { + addProxyMethod(m, intf); + } } } diff --git a/test/jdk/java/lang/reflect/Proxy/ProxyClashTest.java b/test/jdk/java/lang/reflect/Proxy/ProxyClashTest.java new file mode 100644 index 00000000000..604ddf6a930 --- /dev/null +++ b/test/jdk/java/lang/reflect/Proxy/ProxyClashTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8188240 + * @summary This is a test to ensure that proxies do not inherit static methods. + * + * @build ProxyClashTest + * @run main ProxyClashTest + */ + +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Observer; + +public class ProxyClashTest { + + public interface ClashWithRunnable { + static int run() { return 123; } + + static void foo() {} + } + + public static void main(String[] args) { + System.err.println( + "\nDynamic proxy API static method clash test\n"); + + Class[] interfaces = + new Class[] { ClashWithRunnable.class, Runnable.class, Observer.class }; + + ClassLoader loader = ClassLoader.getSystemClassLoader(); + + /* + * Generate a proxy class. + */ + Class proxyClass = Proxy.getProxyClass(loader, interfaces); + System.err.println("+ generated proxy class: " + proxyClass); + + for (Method method : proxyClass.getDeclaredMethods()) { + if (method.getName().equals("run") && method.getReturnType() == int.class) { + throw new RuntimeException("proxy inherited a static method"); + } + if (method.getName().equals("foo")) { + throw new RuntimeException("proxy inherited a static method"); + } + } + + System.err.println("\nTEST PASSED"); + } +} From mandy.chung at oracle.com Wed Mar 14 18:25:08 2018 From: mandy.chung at oracle.com (mandy chung) Date: Wed, 14 Mar 2018 11:25:08 -0700 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: <0b101645-2b94-55f1-a758-89adf721e944@oracle.com> On 3/14/18 11:09 AM, David Lloyd wrote: > On Wed, Mar 14, 2018 at 1:00 PM, mandy chung wrote: >> Thanks for adding the new test. Looks okay and some minor comment. >> >> + try { >> : >> + } catch (Throwable e) { >> + System.err.println("\nTEST FAILED:"); >> + e.printStackTrace(); >> + throw new RuntimeException("TEST FAILED: " + e.toString()); >> + } >> >> >> You can take out this try-catch (Basic1.java isn't be the best example to >> reference that is old and needs update). > Fixed & attached. +1 Mandy From shade at redhat.com Wed Mar 14 18:37:52 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Wed, 14 Mar 2018 19:37:52 +0100 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: On 03/14/2018 07:09 PM, David Lloyd wrote: > On Wed, Mar 14, 2018 at 1:00 PM, mandy chung wrote: >> Thanks for adding the new test. Looks okay and some minor comment. >> >> + try { >> : >> + } catch (Throwable e) { >> + System.err.println("\nTEST FAILED:"); >> + e.printStackTrace(); >> + throw new RuntimeException("TEST FAILED: " + e.toString()); >> + } >> >> >> You can take out this try-catch (Basic1.java isn't be the best example to >> reference that is old and needs update). > > Fixed & attached. > >> I assume your colleague at Red Hat will sponsor it for you? > > I will find out. I can do it, but I need to get updated on two things: a) Are we pushing JDK changes directly to jdk/jdk now? b) Do we need to run it through JDK Submit first, or that is optional for this change? Thanks, -Aleksey From mandy.chung at oracle.com Wed Mar 14 18:44:52 2018 From: mandy.chung at oracle.com (mandy chung) Date: Wed, 14 Mar 2018 11:44:52 -0700 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: On 3/14/18 11:37 AM, Aleksey Shipilev wrote: > On 03/14/2018 07:09 PM, David Lloyd wrote: >> On Wed, Mar 14, 2018 at 1:00 PM, mandy chung wrote: >>> Thanks for adding the new test. Looks okay and some minor comment. >>> >>> + try { >>> : >>> + } catch (Throwable e) { >>> + System.err.println("\nTEST FAILED:"); >>> + e.printStackTrace(); >>> + throw new RuntimeException("TEST FAILED: " + e.toString()); >>> + } >>> >>> >>> You can take out this try-catch (Basic1.java isn't be the best example to >>> reference that is old and needs update). >> Fixed & attached. >> >>> I assume your colleague at Red Hat will sponsor it for you? >> I will find out. > I can do it, but I need to get updated on two things: > a) Are we pushing JDK changes directly to jdk/jdk now? > b) Do we need to run it through JDK Submit first, or that is optional for this change? While this patch is trivial, I recommend to run through JDK submit since proxies are used by other areas.? I did find surprises in the past via testing on trivial proxy class changes. Mandy From shade at redhat.com Wed Mar 14 18:55:36 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Wed, 14 Mar 2018 19:55:36 +0100 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: On 03/14/2018 07:44 PM, mandy chung wrote: >>>> I assume your colleague at Red Hat will sponsor it for you? >>> I will find out. >> I can do it, but I need to get updated on two things: >> a) Are we pushing JDK changes directly to jdk/jdk now? >> b) Do we need to run it through JDK Submit first, or that is optional for this change? > > While this patch is trivial, I recommend to run through JDK submit since proxies are used by other > areas.? I did find surprises in the past via testing on trivial proxy class changes. Makes sense, submitted for testing. -Aleksey From andrej.golovnin at gmail.com Wed Mar 14 18:59:37 2018 From: andrej.golovnin at gmail.com (Andrej Golovnin) Date: Wed, 14 Mar 2018 19:59:37 +0100 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: Hi David, + if (! Modifier.isStatic(m.getModifiers())) { I think the whitespace after the ?!?-sign should be removed. Best regards, Andrej Golovnin > On 14. Mar 2018, at 19:09, David Lloyd wrote: > > On Wed, Mar 14, 2018 at 1:00 PM, mandy chung wrote: >> Thanks for adding the new test. Looks okay and some minor comment. >> >> + try { >> : >> + } catch (Throwable e) { >> + System.err.println("\nTEST FAILED:"); >> + e.printStackTrace(); >> + throw new RuntimeException("TEST FAILED: " + e.toString()); >> + } >> >> >> You can take out this try-catch (Basic1.java isn't be the best example to >> reference that is old and needs update). > > Fixed & attached. > >> I assume your colleague at Red Hat will sponsor it for you? > > I will find out. > > -- > - DML -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: patch-8188240.txt URL: -------------- next part -------------- > From shade at redhat.com Wed Mar 14 19:01:28 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Wed, 14 Mar 2018 20:01:28 +0100 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: <8ac0df60-8324-2982-90b2-8a371ebfb38c@redhat.com> On 03/14/2018 07:59 PM, Andrej Golovnin wrote: > Hi David, > > + if (! Modifier.isStatic(m.getModifiers())) { > > I think the whitespace after the ?!?-sign should be removed. I agree. No problem, I will remove this space in my patch queue. -Aleksey From shade at redhat.com Wed Mar 14 21:31:34 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Wed, 14 Mar 2018 22:31:34 +0100 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: On 03/14/2018 07:09 PM, David Lloyd wrote: > On Wed, Mar 14, 2018 at 1:00 PM, mandy chung wrote: >> Thanks for adding the new test. Looks okay and some minor comment. >> >> + try { >> : >> + } catch (Throwable e) { >> + System.err.println("\nTEST FAILED:"); >> + e.printStackTrace(); >> + throw new RuntimeException("TEST FAILED: " + e.toString()); >> + } >> >> >> You can take out this try-catch (Basic1.java isn't be the best example to >> reference that is old and needs update). > > Fixed & attached. Have you tried to run the test? Because it fails: $ make images run-test TEST=jdk/java/lang/reflect/Proxy/ProxyClashTest.java Dynamic proxy API static method clash test java.lang.IllegalArgumentException: ProxyClashTest$ClashWithRunnable referenced from a method is not visible from class loader at java.base/java.lang.reflect.Proxy$ProxyBuilder.ensureVisible(Proxy.java:851) at java.base/java.lang.reflect.Proxy$ProxyBuilder.validateProxyInterfaces(Proxy.java:682) at java.base/java.lang.reflect.Proxy$ProxyBuilder.(Proxy.java:628) at java.base/java.lang.reflect.Proxy.lambda$getProxyConstructor$1(Proxy.java:426) at java.base/jdk.internal.loader.AbstractClassLoaderValue$Memoizer.get(AbstractClassLoaderValue.java:329) at java.base/jdk.internal.loader.AbstractClassLoaderValue.computeIfAbsent(AbstractClassLoaderValue.java:205) at java.base/java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:424) at java.base/java.lang.reflect.Proxy.getProxyClass(Proxy.java:384) at ProxyClashTest.main(ProxyClashTest.java:56) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at com.sun.javatest.regtest.agent.MainActionHelper$SameVMRunnable.run(MainActionHelper.java:229) at java.base/java.lang.Thread.run(Thread.java:841) JavaTest Message: Test threw exception: java.lang.IllegalArgumentException JavaTest Message: shutting down test Thanks, -Aleksey From david.lloyd at redhat.com Wed Mar 14 21:43:47 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 14 Mar 2018 16:43:47 -0500 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: On Wed, Mar 14, 2018 at 4:31 PM, Aleksey Shipilev wrote: > On 03/14/2018 07:09 PM, David Lloyd wrote: >> On Wed, Mar 14, 2018 at 1:00 PM, mandy chung wrote: >>> Thanks for adding the new test. Looks okay and some minor comment. >>> >>> + try { >>> : >>> + } catch (Throwable e) { >>> + System.err.println("\nTEST FAILED:"); >>> + e.printStackTrace(); >>> + throw new RuntimeException("TEST FAILED: " + e.toString()); >>> + } >>> >>> >>> You can take out this try-catch (Basic1.java isn't be the best example to >>> reference that is old and needs update). >> >> Fixed & attached. > > Have you tried to run the test? > > Because it fails: > > $ make images run-test TEST=jdk/java/lang/reflect/Proxy/ProxyClashTest.java > > Dynamic proxy API static method clash test > > java.lang.IllegalArgumentException: ProxyClashTest$ClashWithRunnable referenced from a method is not > visible from class loader > at java.base/java.lang.reflect.Proxy$ProxyBuilder.ensureVisible(Proxy.java:851) > at java.base/java.lang.reflect.Proxy$ProxyBuilder.validateProxyInterfaces(Proxy.java:682) > at java.base/java.lang.reflect.Proxy$ProxyBuilder.(Proxy.java:628) > at java.base/java.lang.reflect.Proxy.lambda$getProxyConstructor$1(Proxy.java:426) > at > java.base/jdk.internal.loader.AbstractClassLoaderValue$Memoizer.get(AbstractClassLoaderValue.java:329) > at > java.base/jdk.internal.loader.AbstractClassLoaderValue.computeIfAbsent(AbstractClassLoaderValue.java:205) > at java.base/java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:424) > at java.base/java.lang.reflect.Proxy.getProxyClass(Proxy.java:384) > at ProxyClashTest.main(ProxyClashTest.java:56) > at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.base/java.lang.reflect.Method.invoke(Method.java:564) > at com.sun.javatest.regtest.agent.MainActionHelper$SameVMRunnable.run(MainActionHelper.java:229) > at java.base/java.lang.Thread.run(Thread.java:841) > > JavaTest Message: Test threw exception: java.lang.IllegalArgumentException > JavaTest Message: shutting down test I did not run it with jtreg, just on the class path after compiling by hand. I guess it is failing because the nested class is not visible from the system class loader when running within JTReg; maybe the fix would be to use the class loader of the test class or the nested class? -- - DML From mandy.chung at oracle.com Wed Mar 14 21:44:43 2018 From: mandy.chung at oracle.com (mandy chung) Date: Wed, 14 Mar 2018 14:44:43 -0700 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: David - I think the test fails even in your first version. It should use ProxyClashTest.class.getClassLoader() to define the proxy class as the test is running in agent vm mode. Mandy On 3/14/18 2:31 PM, Aleksey Shipilev wrote: > Have you tried to run the test > Because it fails: > > $ make images run-test TEST=jdk/java/lang/reflect/Proxy/ProxyClashTest.java > > Dynamic proxy API static method clash test > > java.lang.IllegalArgumentException: ProxyClashTest$ClashWithRunnable referenced from a method is not > visible from class loader > at java.base/java.lang.reflect.Proxy$ProxyBuilder.ensureVisible(Proxy.java:851) > at java.base/java.lang.reflect.Proxy$ProxyBuilder.validateProxyInterfaces(Proxy.java:682) > at java.base/java.lang.reflect.Proxy$ProxyBuilder.(Proxy.java:628) > at java.base/java.lang.reflect.Proxy.lambda$getProxyConstructor$1(Proxy.java:426) > at > java.base/jdk.internal.loader.AbstractClassLoaderValue$Memoizer.get(AbstractClassLoaderValue.java:329) > at > java.base/jdk.internal.loader.AbstractClassLoaderValue.computeIfAbsent(AbstractClassLoaderValue.java:205) > at java.base/java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:424) > at java.base/java.lang.reflect.Proxy.getProxyClass(Proxy.java:384) > at ProxyClashTest.main(ProxyClashTest.java:56) > at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.base/java.lang.reflect.Method.invoke(Method.java:564) > at com.sun.javatest.regtest.agent.MainActionHelper$SameVMRunnable.run(MainActionHelper.java:229) > at java.base/java.lang.Thread.run(Thread.java:841) > > JavaTest Message: Test threw exception: java.lang.IllegalArgumentException > JavaTest Message: shutting down test > > > Thanks, > -Aleksey > From shade at redhat.com Wed Mar 14 22:04:02 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Wed, 14 Mar 2018 23:04:02 +0100 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: On 03/14/2018 10:44 PM, mandy chung wrote: > David - I think the test fails even in your first version. > > It should use ProxyClashTest.class.getClassLoader() to define the proxy class as the test is running > in agent vm mode. Right. This passes local testing: http://cr.openjdk.java.net/~shade/8188240/webrev.02/ ...and I am going to redo jdk/submit. -Aleksey From michael.hixson at gmail.com Wed Mar 14 23:05:01 2018 From: michael.hixson at gmail.com (Michael Hixson) Date: Wed, 14 Mar 2018 16:05:01 -0700 Subject: Raw String Literal Library Support In-Reply-To: References: Message-ID: Hi Jim, Does string.lines() agree with new BufferedReader(new StringReader(string)).lines() on what the lines are for all inputs? For example, does ``.lines() produce an empty stream? -Michael On Tue, Mar 13, 2018 at 6:47 AM, Jim Laskey wrote: > With the announcement of JEP 326 Raw String Literals, we would like to open up a discussion with regards to RSL library support. Below are several implemented String methods that are believed to be appropriate. Please comment on those mentioned below including recommending alternate names or signatures. Additional methods can be considered if warranted, but as always, the bar for inclusion in String is high. > > You should keep a couple things in mind when reviewing these methods. > > Methods should be applicable to all strings, not just Raw String Literals. > > The number of additional methods should be minimized, not adding every possible method. > > Don't put any emphasis on performance. That is a separate discussion. > > Cheers, > > -- Jim > > A. Line support. > > public Stream lines() > Returns a stream of substrings extracted from this string partitioned by line terminators. Internally, the stream is implemented using a Spliteratorthat extracts one line at a time. The line terminators recognized are \n, \r\n and \r. This method provides versatility for the developer working with multi-line strings. > Example: > > String string = "abc\ndef\nghi"; > Stream stream = string.lines(); > List list = stream.collect(Collectors.toList()); > > Result: > > [abc, def, ghi] > > > Example: > > String string = "abc\ndef\nghi"; > String[] array = string.lines().toArray(String[]::new); > > Result: > > [Ljava.lang.String;@33e5ccce // [abc, def, ghi] > > > Example: > > String string = "abc\ndef\r\nghi\rjkl"; > String platformString = > string.lines().collect(joining(System.lineSeparator())); > > Result: > > abc > def > ghi > jkl > > > Example: > > String string = " abc \n def \n ghi "; > String trimmedString = > string.lines().map(s -> s.trim()).collect(joining("\n")); > > Result: > > abc > def > ghi > > > Example: > > String table = `First Name Surname Phone > Al Albert 555-1111 > Bob Roberts 555-2222 > Cal Calvin 555-3333 > `; > > // Extract headers > String firstLine = table.lines().findFirst().orElse(""); > List headings = List.of(firstLine.trim().split(`\s{2,}`)); > > // Build stream of maps > Stream> stream = > table.lines().skip(1) > .map(line -> line.trim()) > .filter(line -> !line.isEmpty()) > .map(line -> line.split(`\s{2,}`)) > .map(columns -> { > List values = List.of(columns); > return IntStream.range(0, headings.size()).boxed() > .collect(toMap(headings::get, values::get)); > }); > > // print all "First Name" > stream.map(row -> row.get("First Name")) > .forEach(name -> System.out.println(name)); > > Result: > > Al > Bob > Cal > B. Additions to basic trim methods. In addition to margin methods trimIndent and trimMarkers described below in Section C, it would be worth introducing trimLeft and trimRight to augment the longstanding trim method. A key question is how trimLeft and trimRight should detect whitespace, because different definitions of whitespace exist in the library. > > trim itself uses the simple test less than or equal to the space character, a fast test but not Unicode friendly. > > Character.isWhitespace(codepoint) returns true if codepoint one of the following; > > SPACE_SEPARATOR. > LINE_SEPARATOR. > PARAGRAPH_SEPARATOR. > '\t', U+0009 HORIZONTAL TABULATION. > '\n', U+000A LINE FEED. > '\u000B', U+000B VERTICAL TABULATION. > '\f', U+000C FORM FEED. > '\r', U+000D CARRIAGE RETURN. > '\u001C', U+001C FILE SEPARATOR. > '\u001D', U+001D GROUP SEPARATOR. > '\u001E', U+001E RECORD SEPARATOR. > '\u001F', U+001F UNIT SEPARATOR. > ' ', U+0020 SPACE. > (Note: that non-breaking space (\u00A0) is excluded) > > Character.isSpaceChar(codepoint) returns true if codepoint one of the following; > > SPACE_SEPARATOR. > LINE_SEPARATOR. > PARAGRAPH_SEPARATOR. > ' ', U+0020 SPACE. > '\u00A0', U+00A0 NON-BREAKING SPACE. > That sets up several kinds of whitespace; trim's whitespace (TWS), Character whitespace (CWS) and the union of the two (UWS). TWS is a fast test. CWS is a slow test. UWS is fast for Latin1 and slow-ish for UTF-16. > > We are recommending that trimLeft and trimRight use UWS, leave trim alone to avoid breaking the world and then possibly introduce trimWhitespace that uses UWS. > > public String trim() > Removes characters less than equal to space from the beginning and end of the string. No, change except spec clarification and links to the new trim methods. > Examples: > "".trim(); // "" > " ".trim(); // "" > " abc ".trim(); // "abc" > " \u2028abc ".trim(); // "\u2028abc" > public String trimWhitespace() > Removes whitespace from the beginning and end of the string. > Examples: > > "".trimWhitespace(); // "" > " ".trimWhitespace(); // "" > " abc ".trimWhitespace(); // "abc" > " \u2028abc ".trimWhitespace(); // "abc" > public String trimLeft() > Removes whitespace from the beginning of the string. > Examples: > > "".trimLeft(); // "" > " ".trimLeft(); // "" > " abc ".trimLeft(); // "abc " > public String trimRight() > Removes whitespace from the end of the string. > Examples: > > "".trimRight(); // "" > " ".trimRight(); // "" > " abc ".trimRight(); // " abc" > C. Margin management. With introduction of multi-line Raw String Literals, developers will have to deal with the extraneous spacing introduced by indenting and formatting string bodies. > > Note that for all the methods in this group, if the first line is empty then it is removed and if the last is empty then it is removed. This removal provides a means for developers that use delimiters on separate lines to bracket string bodies. Also note, that all line separators are replaced with \n. > > public String trimIndent() > This method determines a representative line in the string body that has a non-whitespace character closest to the left margin. Once that line has been determined, the number of leading whitespaces is tallied to produce a minimal indent amount. Consequently, the result of the method is a string with the minimal indent amount removed from each line. The first line is unaffected since it is preceded by the open delimiter. The type of whitespace used (spaces or tabs) does not affect the result as long as the developer is consistent with the whitespace used. > Example: > > String x = ` > This is a line > This is a line > This is a line > This is a line > This is a line > `.trimIndent(); > > Result: > > This is a line > This is a line > This is a line > This is a line > This is a line > public String trimMarkers(String leftMarker, String rightMarker) > Each line of the multi-line string is first trimmed. If the trimmed line contains the leftMarker at the beginning of the string then it is removed. Finally, if the line contains the rightMarker at the end of line, it is removed. > Example: > > String x = `|This is a line| > |This is a line| > |This is a line|`.trimMarkers("|", "|"); > Result: > > This is a line > This is a line > This is a line > > Example: > > String x = `>> This is a line > >> This is a line > >> This is a line`.trimMarkers(">> ", ""); > Result: > > This is a line > This is a line > This is a line > D. Escape management. Since Raw String Literals do not interpret Unicode escapes (\unnnn) or escape sequences (\n, \b, etc), we need to provide a scheme for developers who just want multi-line strings but still have escape sequences interpreted. > > public String unescape() throws MalformedEscapeException > Translates each Unicode escape or escape sequence in the string into the character represented by the escape. @jls 3.3, 3.10.6 > Example: > > `abc\u2022def\nghi`.unescape(); > > Result: > > abc?def > ghi > public String unescape(EscapeType... escape) throws MalformedEscapeException > Selectively translates Unicode escape or escape sequence based on the escape type flags provided. > public enum EscapeType { > /** Backslash escape sequences based on section 3.10.6 of the > * The Java™ Language Specification. > * This includes sequences for backspace, horizontal tab, > * line feed, form feed, carriage return, double quote, > * single quote, backslash and octal escape sequences. > */ > BACKSLASH, // > > /** Unicode sequences based on section 3.3 of the > * The Java™ Language Specification. > * This includes sequences in the form {@code \u005Cunnnn}. > */ > UNICODE > } > > > Example: > > `abc\u2022def\nghi`.unescape(EscapeType.BACKSLASH); > > Result: > > abc\u2022def > ghi > > > Example: > > `abc\u2022def\nghi`.unescape(EscapeType.UNICODE); > > Result: > > abc?def\nghi > Conversely, there are circumstances where the inverse is required > > public String escape() > Translates each quote, backslash, non-graphic character or non-ASCII character into an Unicode escape or escape sequence. The method is equivalent to escape(BACKSLASH, UNICODE) . > Example: > > `abc?def > ghi`.escape(); > > Result: > > abc\u2022def\nghi > public String escape(EscapeType... escape) > Selectively translates each quote, backslash, non-graphic character or non-ASCII character into an Unicode escape or escape sequence based on the escape type flags provided. > Example: > > `abc?def > ghi`.escape(EscapeType.BACKSLASH); > > Result: > > abc?def\nghi > > > Example: > > `abc?def > ghi`.escape(EscapeType.UNICODE); > > Result: > > abc\u2022def > ghi > From stuart.marks at oracle.com Wed Mar 14 23:55:01 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Wed, 14 Mar 2018 16:55:01 -0700 Subject: Raw String Literal Library Support In-Reply-To: References: Message-ID: <8d451533-73c9-7c3e-da4a-e18af7f4274c@oracle.com> Hi Jim, Some comments (really, mainly just quibbles) about string trimming. First, * String.trim trims characters <= \u0020 from each end of a string. I agree that String.trim should be preserved unchanged for compatibility purposes. * The trimLeft, trimRight, and trimWhitespace (which trims both ends) methods make sense. These three should all use the same definition of whitespace. * My issue concerns what definition of whitespace they use. What you outlined in the quoted section below doesn't line up with the definitions in the API spec. The existing methods Character.isSpaceChar(codepoint) and Character.isWhitespace(codepoint) are well-defined but somewhat different notions of whitespace. ** The Character.isSpaceChar method returns true if the code point is a member of any of these categories: SPACE_SEPARATOR LINE_SEPARATOR PARAGRAPH_SEPARATOR In JDK 10, which conforms to Unicode 8.0.0, the SPACE_SEPARATOR category includes the following characters: U+0020 SPACE U+00A0 NO-BREAK SPACE U+1680 OGHAM SPACE MARK U+2000 EN QUAD U+2001 EM QUAD U+2002 EN SPACE U+2003 EM SPACE U+2004 THREE-PER-EM SPACE U+2005 FOUR-PER-EM SPACE U+2006 SIX-PER-EM SPACE U+2007 FIGURE SPACE U+2008 PUNCTUATION SPACE U+2009 THIN SPACE U+200A HAIR SPACE U+202F NARROW NO-BREAK SPACE U+205F MEDIUM MATHEMATICAL SPACE U+3000 IDEOGRAPHIC SPACE The LINE_SEPARATOR category contains this one character: U+2028 LINE SEPARATOR And the PARAGRAPH_SEPARATOR category contains just this one character: U+2029 PARAGRAPH SEPARATOR ** Meanwhile, the Character.isWhitespace method returns true if the code point is in one of these categories: SPACE_SEPARATOR, excluding U+00A0 NO-BREAK SPACE U+2007 FIGURE SPACE U+202F NARROW NO-BREAK SPACE LINE_SEPARATOR PARAGRAPH_SEPARATOR or if it is one of these characters: U+0009 HORIZONTAL TABULATION. U+000A LINE FEED. U+000B VERTICAL TABULATION. U+000C FORM FEED. U+000D CARRIAGE RETURN. U+001C FILE SEPARATOR. U+001D GROUP SEPARATOR. U+001E RECORD SEPARATOR. U+001F UNIT SEPARATOR. ** You mentioned several different definitions of whitespace: - trim's whitespace (TWS): chars <= U+0020 - Character's whitespace (CWS): I'm not sure what you meant by this - union whitespace (UWS): union of TWS and CWS I don't think we should be creating a new definition of whitespace, such as UWS, if at all possible. TWS is strange in that it contains a bunch of control characters that aren't necessarily whitespace, and it omits Unicode whitespace. Character.isSpaceChar includes various no-break spaces, which I don't think should be trimmed away, and it also omits various ASCII white space characters, which I think most programmers would find surprising. Finally, Character.isWhitespace includes the ASCII whitespace characters and Unicode space separators, but excludes no-break spaces. This makes the most sense to me. So, how about we define trimLeft, trimRight, and trimWhitespace all in terms of Character.isWhitespace? s'marks On 3/13/18 6:47 AM, Jim Laskey wrote: > B. Additions to basic trim methods. In addition to margin methods trimIndent and trimMarkers described below in Section C, it would be worth introducing trimLeft and trimRight to augment the longstanding trim method. A key question is how trimLeft and trimRight should detect whitespace, because different definitions of whitespace exist in the library. > > trim itself uses the simple test less than or equal to the space character, a fast test but not Unicode friendly. > > Character.isWhitespace(codepoint) returns true if codepoint one of the following; > > SPACE_SEPARATOR. > LINE_SEPARATOR. > PARAGRAPH_SEPARATOR. > '\t', U+0009 HORIZONTAL TABULATION. > '\n', U+000A LINE FEED. > '\u000B', U+000B VERTICAL TABULATION. > '\f', U+000C FORM FEED. > '\r', U+000D CARRIAGE RETURN. > '\u001C', U+001C FILE SEPARATOR. > '\u001D', U+001D GROUP SEPARATOR. > '\u001E', U+001E RECORD SEPARATOR. > '\u001F', U+001F UNIT SEPARATOR. > ' ', U+0020 SPACE. > (Note: that non-breaking space (\u00A0) is excluded) > > Character.isSpaceChar(codepoint) returns true if codepoint one of the following; > > SPACE_SEPARATOR. > LINE_SEPARATOR. > PARAGRAPH_SEPARATOR. > ' ', U+0020 SPACE. > '\u00A0', U+00A0 NON-BREAKING SPACE. > That sets up several kinds of whitespace; trim's whitespace (TWS), Character whitespace (CWS) and the union of the two (UWS). TWS is a fast test. CWS is a slow test. UWS is fast for Latin1 and slow-ish for UTF-16. > > We are recommending that trimLeft and trimRight use UWS, leave trim alone to avoid breaking the world and then possibly introduce trimWhitespace that uses UWS. > > public String trim() > Removes characters less than equal to space from the beginning and end of the string. No, change except spec clarification and links to the new trim methods. > Examples: > "".trim(); // "" > " ".trim(); // "" > " abc ".trim(); // "abc" > " \u2028abc ".trim(); // "\u2028abc" > public String trimWhitespace() > Removes whitespace from the beginning and end of the string. > Examples: > > "".trimWhitespace(); // "" > " ".trimWhitespace(); // "" > " abc ".trimWhitespace(); // "abc" > " \u2028abc ".trimWhitespace(); // "abc" > public String trimLeft() > Removes whitespace from the beginning of the string. > Examples: > > "".trimLeft(); // "" > " ".trimLeft(); // "" > " abc ".trimLeft(); // "abc " > public String trimRight() > Removes whitespace from the end of the string. > Examples: > > "".trimRight(); // "" > " ".trimRight(); // "" > " abc ".trimRight(); // " abc" From brian.burkhalter at oracle.com Thu Mar 15 00:48:20 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 14 Mar 2018 17:48:20 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions Message-ID: https://bugs.openjdk.java.net/browse/JDK-8180410 http://cr.openjdk.java.net/~bpb/8180410/webrev.00/ This proposed patch would make the following changes: 1. Add a new method writeBytes(byte[]) which writes all supplied bytes but does not throw IOE. 2. Document some previously undocumented exceptions which can be thrown by write(byte[],int,int) and writeTo(OutputStream). 3. s/@exception/@throws/. The test is renamed from WriteBounds to Write with the addition of a test of write() and writeBytes(). A CSR will be filed later. Thanks, Brian From irogers at google.com Thu Mar 15 01:00:13 2018 From: irogers at google.com (Ian Rogers) Date: Thu, 15 Mar 2018 01:00:13 +0000 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> <5A9D8F33.5060500@oracle.com> <5A9DAC84.906@oracle.com> <5A9DAE87.8020801@oracle.com> Message-ID: An old data point on how large a critical region should be comes from java.nio.Bits. In JDK 9 the code migrated into unsafe, but in JDK 8 the copies within a critical region were bound at most copying 1MB: http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/native/java/nio/Bits.c#l88 This is inconsistent with Deflater and ObjectOutputStream which both allow unlimited arrays and thereby critical region sizes. In JDK 9 the copies starve the garbage collector in nio Bits too as there is no 1MB limit to the copy sizes: http://hg.openjdk.java.net/jdk/jdk/rev/f70e100d3195 which came from: https://bugs.openjdk.java.net/browse/JDK-8149596 Perhaps this is a regression not demonstrated due to the testing challenge. There is a time to safepoint discussion thread related to this here: https://groups.google.com/d/msg/mechanical-sympathy/f3g8pry-o1A/x6NptTDslcIJ "silent killer" It doesn't seem unreasonable to have the loops for the copies occur in 1MB chunks but JDK-8149596 lost this and so I'm confused on what the HotSpot stand point is. In a way criticals are better than unsafe as they may pin the memory and not starve GC, which shenandoah does. Thanks, Ian On Wed, Mar 7, 2018 at 10:16 AM Ian Rogers wrote: > Thanks Martin! Profiling shows most of the time spent in this code is in > the call to libz's deflate. I worry that increasing the buffer size > increases that work and holds the critical lock for longer. Profiling > likely won't show this issue as there's needs to be contention on the GC > locker. > > In HotSpot: > > http://hg.openjdk.java.net/jdk/jdk/file/2854589fd853/src/hotspot/share/gc/shared/gcLocker.hpp#l34 > "Avoid calling these if at all possible" could be taken to suggest that > JNI critical regions should also be avoided if at all possible. I think > HotSpot and the JDK are out of step if this is the case and there could be > work done to remove JNI critical regions from the JDK and replace either > with Java code (JITs are better now) or with Get/Set...ArrayRegion. This > does appear to be a O(1) to O(n) transition so perhaps the HotSpot folks > could speak to it. > > Thanks, > Ian > > > On Tue, Mar 6, 2018 at 6:44 PM Martin Buchholz > wrote: > >> Thanks Ian and Sherman for the excellent presentation and memories of >> ancient efforts. >> >> Yes, Sherman, I still have vague memory that attempts to touch any >> implementation detail in this area was asking for trouble and someone would >> complain. I was happy to let you deal with those problems! >> >> There's a continual struggle in the industry to enable more checking at >> test time, and -Xcheck:jni does look like it should be possible to >> routinely turn on for running all tests. (Google tests run with a time >> limit, and so any low-level performance regression immediately causes test >> failures, for better or worse) >> >> Our problem reduces to accessing a primitive array slice from native >> code. The only way to get O(1) access is via GetPrimitiveArrayCritical, >> BUT when it fails you have to pay for a copy of the entire array. An >> obvious solution is to introduce a slice variant GetPrimitiveArrayRegionCritical >> that would only degrade to a copy of the slice. Offhand that seems >> relatively easy to implement though we would hold our noses at adding yet >> more *Critical* functions to the JNI spec. In spirit though it's a >> straightforward generalization. >> >> Implementing Deflater in pure Java seems very reasonable and we've had >> good success with "nearby" code, but we likely cannot reuse the GNU >> Classpath code. >> >> Thanks for pointing out >> JDK-6311046: -Xcheck:jni should support checking of >> GetPrimitiveArrayCritical >> which went into jdk8 in u40. >> >> We can probably be smarter about choosing a better buffer size, e.g. in >> ZipOutputStream. >> >> Here's an idea: In code like this >> try (DeflaterOutputStream dout = new DeflaterOutputStream(deflated)) { >> dout.write(inflated, 0, inflated.length); >> } >> when the DeflaterOutputStream is given an input that is clearly too large >> for the current buffer size, reorganize internals dynamically to use a much >> bigger buffer size. >> >> It's possible (but hard work!) to adjust algorithms based on whether >> critical array access is available. It would be nice if we could get the >> JVM to tell us (but it might depend, e.g. on the size of the array). >> > From james at lightbend.com Thu Mar 15 01:24:41 2018 From: james at lightbend.com (James Roper) Date: Thu, 15 Mar 2018 12:24:41 +1100 Subject: Reactive Streams utility API In-Reply-To: References: Message-ID: Hi all, An update on this. We've now filled out the API with feature parity with the JDK8 Streams API - for operators that make sense in Reactive Streams. We've provided example implementations of the API backed by both Akka Streams and rxjava, showing that it can be widely implemented. The TCK still needs some work, but covers the major features, and comprehensively covers all publishers/subscribers with the Reactive Streams TCK (so comprehensive that we actually found two Reactive Streams TCK violations in Akka Streams with this, and a couple in rxjava too). There are two major areas of work left to get something that would be ready to be a candidate for a final API. The first is to produce a zero dependency reference implementation of the API. This is what I plan on starting on next. The second is to decide what additional operators and generators the API should provide. So far, the scope has been mostly limited to a subset of the JDK8 Streams scope, only a few additional API pieces have been created, such as a few variations on flatMap (one that supports CompletionStage, and one that supports Iterable). There are a number of other features for consideration to provide basic necessary functionality for this API, here's some examples off the top of my head (some of these can already be implemented in terms of other stages already provided): * A cancelled subscriber (useful for cleaning up hot publishers) * An ignoring subscriber (useful when you do the actual work in a previous stage of the graph, such as mapping to completion stages) * Error handling subscribers and/or processors * Termination listening subscribers and/or processors * A processor that wraps a subscriber and publisher * The ability to merge streams - so far only concat is provided, and all flatMaps are essentially concatenations, merge variants may be useful (though introduce a lot of complexity, such as specifying breadth) * The ability to split streams into sub streams - a use case for this is in parsing a stream that contains potentially large sub streams, like parsing a multipart/form-data body * Batching of elements in a stream, based on predicate, influenced by backpressure or based on a scheduled tick * Scheduled features such as emitting ticks, rate limiting, etc * The ability to control buffering and asynchronous boundaries within a graph * Naming of stages for debug/error reporting/monitoring purposes Not all of the above may be absolutely necessary, but should be considered, and there may be other features as well that would be useful to consider. Please visit the repo and any feedback would be much appreciated: https://github.com/lightbend/reactive-streams-utils Regards, James On 8 March 2018 at 03:59, Brian Goetz wrote: > To answer the questions at the bottom: the next step is to start working > on this and get folks excited about contributing. There's plenty of time > for process later, but filing a JEP or creating a project shouldn't be a > barrier to innovating. > > > On 2/28/2018 10:33 PM, James Roper wrote: > >> Hi all, >> >> We've put together a simple proposal for this. Please read the README for >> an introduction to this proposal. >> >> https://github.com/lightbend/reactive-streams-utils >> >> Regards, >> >> James >> >> On 22 February 2018 at 11:47, James Roper wrote: >> >> Hi all, >>> >>> This is an email to give people a heads up that we'd like to look at >>> creating an API, in the same vein as the JDK8 Streams API, for building >>> reactive streams (a la JDK9 juc.Flow). Our goals for this are: >>> >>> * To fill a gap in the JDK where if a developer wants to do even the >>> simplest of things with a JDK9 juc.Flow, such as map or filter, they need >>> to bring in a third party library that implements that. >>> * To produce an API that can build Publishers, Subscribers, Processors, >>> and complete graphs, for the purposes of consuming APIs that use reactive >>> streams (for example, JDK9 Http Client). >>> * To produce an API that aligns closely with ju.stream.Stream, using it >>> for inspiration for naming, scope, general API shape, and other aspects. >>> The purpose of this goal is to ensure familiarity of Java developers with >>> the new API, and to limit the number of concepts Java developers need to >>> understand to do the different types of streaming offered by the JDK. >>> * To produce an API that can be implemented by multiple providers >>> (including an RI in the JDK itself), using the ServiceLoader mechanism to >>> provide and load a default implementation (while allowing custom >>> implementations to be manually provided). There are a lot of concerns >>> that >>> each different streams implementation provides and implements, beyond >>> streaming, for example monitoring/tracing, concurrency modelling, >>> buffering >>> strategies, performance aspects of the streams handling including fusing, >>> and context (eg thread local) propagation. This will allow libraries to >>> use >>> and provide contracts based on this API without depending on a particular >>> implementation, and allows developers to select the implementation that >>> meets their needs. >>> >>> Non goals: >>> >>> * To produce a kitchen sink of utilities for working with reactive >>> streams. There already exist a number of reactive streams implementations >>> that seek to meet this goal (eg, Akka Streams, Reactor, RxJava), and once >>> you go past the basics (map, filter, collect), and start dealing with >>> things like fan in/out, cycles, restarting, etc, the different approaches >>> to solving this start to vary greatly. The JDK should provide enough to >>> be >>> useful for typical every day streaming use cases, with developers being >>> able to select a third party library for anything more advanced. >>> >>> We will update this list when we have something ready for public review. >>> This probably won't be far off. Our hope is that we can propose this as a >>> JEP. >>> >>> Regards, >>> >>> James >>> >>> -- >>> *James Roper* >>> *Senior Octonaut* >>> >>> Lightbend ? Build reactive apps! >>> Twitter: @jroper >>> >>> >> >> > -- *James Roper* *Senior Octonaut* Lightbend ? Build reactive apps! Twitter: @jroper From xueming.shen at oracle.com Thu Mar 15 01:53:44 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Wed, 14 Mar 2018 18:53:44 -0700 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: <5A999CAF.3030905@oracle.com> Message-ID: <5AA9D228.8070407@oracle.com> Hi David, https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v12 Should we start to review the changes included in above link, or we should wait ? It appears the API is being updated but some implementation have not been updated to follow the spec yet, especially the piece that deals with the output buffer/byteWritten when DataFormatException is raised, for example (1) the "outputConsumedID" is defined but never used to update the corresponding java field in Inflater.c and (2) the "outputConsumed" is used to update the output ByteBuffer when DFE raised (in Java), but the corresponding "byteWritten" is not being updated before the exception is thrown. -Sherman On 3/13/18, 10:46 AM, David Lloyd wrote: > Sorry all, it looks like GMail doesn't know how to keep replies with > the thread when you change the subject line. The follow-up to this > thread is http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-March/051960.html > with only a few small changes as discussed above. > > On Fri, Mar 2, 2018 at 2:36 PM, David Lloyd wrote: >> On Fri, Mar 2, 2018 at 2:34 PM, David Lloyd wrote: >>> On Fri, Mar 2, 2018 at 12:49 PM, Xueming Shen wrote: >>>> Hi David, >>>> >>>> (1) Deflater.deflate(Bytebuffer) >>>> the api doc regarding "no_flush" appears to be the copy/paste of the >>>> byte[] version >>>> without being updated to the corresponding ByteBuffer? >>> You're right, I missed that one. I've incorporated this fix locally: >> Oops, this should have been: >> >> --- 8< --- cut here --- 8< --- >> >> diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java >> b/src/java.base/share/classes/java/util/zip/Deflater.java >> index 524125787a8..40f0d9736e2 100644 >> --- a/src/java.base/share/classes/java/util/zip/Deflater.java >> +++ b/src/java.base/share/classes/java/util/zip/Deflater.java >> @@ -481,9 +481,9 @@ public class Deflater { >> * in order to determine if more input data is required. >> * >> *

This method uses {@link #NO_FLUSH} as its compression flush mode. >> - * An invocation of this method of the form {@code deflater.deflate(b)} >> + * An invocation of this method of the form {@code >> deflater.deflate(output)} >> * yields the same result as the invocation of >> - * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. >> + * {@code deflater.deflate(output, Deflater.NO_FLUSH)}. >> * >> * @param output the buffer for the compressed data >> * @return the actual number of bytes of compressed data written to the >> >> --- 8< --- cut here --- 8< --- >> >> -- >> - DML > > From peter.levart at gmail.com Thu Mar 15 07:56:31 2018 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 15 Mar 2018 08:56:31 +0100 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: Hi Aleksey, In test, the following comment: ? 26? * @summary This is a test to ensure that proxies do not inherit static methods. I think the word "inherit" is not correct here. Interface static methods can not be inherited. VM already ensures that. Perhaps the comment should be: ??? "This is a test to ensure that proxies do not try to override interface static methods." Nothing can actually override an interface static method even if it tries to (in the sense class static methods may be overridden). So I think this test checks that proxy class doesn't try to do this, right? Regards, Peter On 03/14/2018 11:04 PM, Aleksey Shipilev wrote: > On 03/14/2018 10:44 PM, mandy chung wrote: >> David - I think the test fails even in your first version. >> >> It should use ProxyClashTest.class.getClassLoader() to define the proxy class as the test is running >> in agent vm mode. > Right. This passes local testing: > http://cr.openjdk.java.net/~shade/8188240/webrev.02/ > > ...and I am going to redo jdk/submit. > > -Aleksey > From thomas.schatzl at oracle.com Thu Mar 15 08:25:48 2018 From: thomas.schatzl at oracle.com (Thomas Schatzl) Date: Thu, 15 Mar 2018 09:25:48 +0100 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> <5A9D8F33.5060500@oracle.com> <5A9DAC84.906@oracle.com> <5A9DAE87.8020801@oracle.com> Message-ID: <1521102348.2448.25.camel@oracle.com> Hi, On Thu, 2018-03-15 at 01:00 +0000, Ian Rogers wrote: > An old data point on how large a critical region should be comes from > java.nio.Bits. In JDK 9 the code migrated into unsafe, but in JDK 8 > the copies within a critical region were bound at most copying 1MB: > http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/ > native/java/nio/Bits.c#l88 This is inconsistent with Deflater and > ObjectOutputStream which both allow unlimited arrays and thereby > critical region sizes. > > In JDK 9 the copies starve the garbage collector in nio Bits too as > there is no 1MB limit to the copy sizes: > http://hg.openjdk.java.net/jdk/jdk/rev/f70e100d3195 > which came from: > https://bugs.openjdk.java.net/browse/JDK-8149596 > > Perhaps this is a regression not demonstrated due to the testing > challenge. > [...] > It doesn't seem unreasonable to have the loops for the copies occur > in 1MB chunks but JDK-8149596 lost this and so I'm confused on what > the HotSpot stand point is. Please file a bug (seems to be a core-libs/java.nio regression?), preferably with some kind of regression test. Also file enhancements (I would guess) for the other cases allowing unlimited arrays. Long TTSP is a performance bug as any other. > In a way criticals are better than unsafe as they may > pin the memory and not starve GC, which shenandoah does. (Region based) Object pinning has its own share of problems: - only (relatively) easily implemented in region based collectors - may slow down pause a bit in presence of pinned regions/objects (for non-concurrent copying collectors) - excessive use of pinning may cause OOME and VM exit probably earlier than the gc locker. GC locker seems to provide a more gradual degradation. E.g. pinning regions typically makes these regions unavailable for allocation. I.e. you still should not use it for many, very long living objects. Of course this somewhat depends on the sophistication of the implementation. I think region based pinning would be a good addition to other collectors than Shenandoah too. It has been on our minds for a long time, but there are so many other more important issues :), so of course we are eager to see contributions in this area. ;) If you are interested on working on this, please ping us on hotspot-gc- dev for implementation ideas to get you jump-started. Thanks, Thomas From scolebourne at joda.org Thu Mar 15 08:52:12 2018 From: scolebourne at joda.org (Stephen Colebourne) Date: Thu, 15 Mar 2018 08:52:12 +0000 Subject: Raw String Literal Library Support In-Reply-To: <8d451533-73c9-7c3e-da4a-e18af7f4274c@oracle.com> References: <8d451533-73c9-7c3e-da4a-e18af7f4274c@oracle.com> Message-ID: On 14 March 2018 at 23:55, Stuart Marks wrote: > So, how about we define trimLeft, trimRight, and trimWhitespace > all in terms of Character.isWhitespace? This seems like a reasonable approach. I'd expect tab to be trimmed for example. Commons-Lang is a good source to consider when looking at naming. https://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/StringUtils.html Rather than re-using "trim", commons-lang uses "strip". So you have strip(), stripLeft() and stripRight(). If you want to stick with "trim", how about trimAll() instead of trimWhitespace(). Shorter and more obvious I think. Otherwise, I think you'd need trimWhitespaceLeft() and trimWhitespaceRight() to match. In line with these whitespace methods, I'd like to see isBlank() added, could also be named isWhitespace(). The existing isEmpty() method is fine, but a lot of the time user input validation routines want to base their decision on "empty once trimmed". str.isBlank() would be the same as str.trimAll().isEmpty() but without the object creation. Finally, a constant for EMPTY has always been missing from java.lang.String. It would be great to add it. Stephen From shade at redhat.com Thu Mar 15 08:57:12 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Thu, 15 Mar 2018 09:57:12 +0100 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: On 03/15/2018 08:56 AM, Peter Levart wrote: > Hi Aleksey, > > In test, the following comment: > > ? 26? * @summary This is a test to ensure that proxies do not inherit static methods. > > I think the word "inherit" is not correct here. Interface static methods can not be inherited. VM > already ensures that. Perhaps the comment should be: > > ??? "This is a test to ensure that proxies do not try to override interface static methods." I think word "inherited" there is in "proxy-inherited" sense. "Override" does not seems fitting either: proxy does not override. Maybe this: This is a test to ensure that proxies do not try to capture interface static methods. -Aleksey From david.holmes at oracle.com Thu Mar 15 09:38:28 2018 From: david.holmes at oracle.com (David Holmes) Date: Thu, 15 Mar 2018 19:38:28 +1000 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: On 15/03/2018 5:56 PM, Peter Levart wrote: > Hi Aleksey, > > In test, the following comment: > > ? 26? * @summary This is a test to ensure that proxies do not inherit > static methods. > > I think the word "inherit" is not correct here. Interface static methods > can not be inherited. VM already ensures that. Perhaps the comment > should be: > > ??? "This is a test to ensure that proxies do not try to override > interface static methods." > > Nothing can actually override an interface static method even if it > tries to (in the sense class static methods may be overridden). So I > think this test checks that proxy class doesn't try to do this, right? To be pedantic, talking about "overriding static methods" is as wrong as talking about "inheriting static methods. They can't be inherited and so can't be overridden. In this context perhaps "intercept" would be a better choice? Or even "proxy"? David > Regards, Peter > > On 03/14/2018 11:04 PM, Aleksey Shipilev wrote: >> On 03/14/2018 10:44 PM, mandy chung wrote: >>> David - I think the test fails even in your first version. >>> >>> It should use ProxyClashTest.class.getClassLoader() to define the >>> proxy class as the test is running >>> in agent vm mode. >> Right. This passes local testing: >> ? http://cr.openjdk.java.net/~shade/8188240/webrev.02/ >> >> ...and I am going to redo jdk/submit. >> >> -Aleksey >> > From shade at redhat.com Thu Mar 15 10:58:13 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Thu, 15 Mar 2018 11:58:13 +0100 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: <6ae1619f-bdad-3158-7cdf-4c835ace3677@redhat.com> On 03/15/2018 10:38 AM, David Holmes wrote: > On 15/03/2018 5:56 PM, Peter Levart wrote: >> Hi Aleksey, >> >> In test, the following comment: >> >> ?? 26? * @summary This is a test to ensure that proxies do not inherit static methods. >> >> I think the word "inherit" is not correct here. Interface static methods can not be inherited. VM >> already ensures that. Perhaps the comment should be: >> >> ???? "This is a test to ensure that proxies do not try to override interface static methods." >> >> Nothing can actually override an interface static method even if it tries to (in the sense class >> static methods may be overridden). So I think this test checks that proxy class doesn't try to do >> this, right? > > To be pedantic, talking about "overriding static methods" is as wrong as talking about "inheriting > static methods. They can't be inherited and so can't be overridden. > > In this context perhaps "intercept" would be a better choice? Or even "proxy"? All right, I made it "intercept". Submit-jdk tests returned fine. I am pushing, unless there other pedantic remarks :) -Aleksey From peter.levart at gmail.com Thu Mar 15 12:40:21 2018 From: peter.levart at gmail.com (Peter Levart) Date: Thu, 15 Mar 2018 13:40:21 +0100 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> Message-ID: <10a06d18-c17b-5b2c-cdad-3e3a42af3839@gmail.com> On 03/15/2018 09:57 AM, Aleksey Shipilev wrote: > On 03/15/2018 08:56 AM, Peter Levart wrote: >> Hi Aleksey, >> >> In test, the following comment: >> >> ? 26? * @summary This is a test to ensure that proxies do not inherit static methods. >> >> I think the word "inherit" is not correct here. Interface static methods can not be inherited. VM >> already ensures that. Perhaps the comment should be: >> >> ??? "This is a test to ensure that proxies do not try to override interface static methods." > I think word "inherited" there is in "proxy-inherited" sense. "Override" does not seems fitting > either: proxy does not override. It does some of them: - the default interface methods are overridden and their implementation wired to InvocationHandler. - the abstract interface methods are implemented and their implementation wired to InvocationHandler. Static interface methods can't be overridden. That's why I wrote that test checks that proxies do not "try to override" and not "override". But maybe "trying an impossible thing" is not the right way to express something. David Holmes might have better words for it. Regards, Peter > Maybe this: > > This is a test to ensure that proxies do not try to capture interface static methods. > > -Aleksey > From Roger.Riggs at Oracle.com Thu Mar 15 14:33:45 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 15 Mar 2018 10:33:45 -0400 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: References: Message-ID: Hi Brian, BAOS.java: line 163: ok but I don't think I would keep using the expanded 'byte array output stream" phrase instead of the proper noun: ByteArrayOutputStream. (except for consistency) In the Write.java test: line 60:? Probably "-" in the message should be "--" for consistency line 68:? Add the "e" Throwable to the thrown RuntimeException so it gets printed in a stack trace/message Line 100:..? If this was a testng test, the Assert.assertEquals messages would conveniently print expected and actual values.? I'd suggest converting it to use @run testng. (Though I expect after these are debugged, they will never fail). 73: some formatting cleanup of the old code might be useful. (spaces around "=") Regards, Roger On 3/14/2018 8:48 PM, Brian Burkhalter wrote: > https://bugs.openjdk.java.net/browse/JDK-8180410 > http://cr.openjdk.java.net/~bpb/8180410/webrev.00/ > > This proposed patch would make the following changes: > > 1. Add a new method writeBytes(byte[]) which writes all supplied bytes but does not throw IOE. > 2. Document some previously undocumented exceptions which can be thrown by write(byte[],int,int) and writeTo(OutputStream). > 3. s/@exception/@throws/. > > The test is renamed from WriteBounds to Write with the addition of a test of write() and writeBytes(). > > A CSR will be filed later. > > Thanks, > > Brian From Alan.Bateman at oracle.com Thu Mar 15 15:42:09 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 15 Mar 2018 15:42:09 +0000 Subject: Raw String Literal Library Support In-Reply-To: References: Message-ID: <995c9b7a-cfaa-cc49-4865-e24d5c6611f8@oracle.com> On 13/03/2018 13:47, Jim Laskey wrote: > : > > We are recommending that trimLeft and trimRight use UWS, leave trim alone to avoid breaking the world and then possibly introduce trimWhitespace that uses UWS. Right, it would too risky to change rim() as it goes all the way back to JDK 1.0. If you introduce a method named "trimWhitespace" then I think it would be a surprising if were not aligned with "isWhitespace". I also share Stuart's concerns about the handling of control characters in legacy trim (or TWS in the proposal). Can you expand a bit on why UWS was recommended? -Alan From brian.burkhalter at oracle.com Thu Mar 15 15:56:52 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Thu, 15 Mar 2018 08:56:52 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: References: Message-ID: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> Hi Roger, On Mar 15, 2018, at 7:33 AM, Roger Riggs wrote: > BAOS.java: > > line 163: ok but I don't think I would keep using the expanded 'byte array output stream" phrase > instead of the proper noun: ByteArrayOutputStream. (except for consistency) I don?t like it either: I was just maintaining consistency (as you observed the other usages). > In the Write.java test: > > line 60: Probably "-" in the message should be "--" for consistency > > line 68: Add the "e" Throwable to the thrown RuntimeException so it gets printed in a stack trace/message > > Line 100:.. If this was a testng test, the Assert.assertEquals messages would conveniently > print expected and actual values. I'd suggest converting it to use @run testng. > > (Though I expect after these are debugged, they will never fail). > > 73: some formatting cleanup of the old code might be useful. (spaces around "=") Will update. Thanks, Brian From mandy.chung at oracle.com Thu Mar 15 16:26:43 2018 From: mandy.chung at oracle.com (mandy chung) Date: Thu, 15 Mar 2018 09:26:43 -0700 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: <6ae1619f-bdad-3158-7cdf-4c835ace3677@redhat.com> References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> <6ae1619f-bdad-3158-7cdf-4c835ace3677@redhat.com> Message-ID: On 3/15/18 3:58 AM, Aleksey Shipilev wrote: > On 03/15/2018 10:38 AM, David Holmes wrote: >> To be pedantic, talking about "overriding static methods" is as wrong as talking about "inheriting >> static methods. They can't be inherited and so can't be overridden. >> >> In this context perhaps "intercept" would be a better choice? Or even "proxy"? > All right, I made it "intercept". Submit-jdk tests returned fine. > I am pushing, unless there other pedantic remarks :) "intercept" is a better choice.?? Good to go. Mandy From shade at redhat.com Thu Mar 15 16:28:11 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Thu, 15 Mar 2018 17:28:11 +0100 Subject: [PATCH] 8188240: Reflection Proxy should skip static methods In-Reply-To: References: <9ab6b265-af4a-c250-e986-ffbc15ca207d@oracle.com> <6de1d4b5-71e6-ba66-636d-dc7c18ba0c34@oracle.com> <6ae1619f-bdad-3158-7cdf-4c835ace3677@redhat.com> Message-ID: <98973706-b66e-0e9d-a975-8723935d0617@redhat.com> On 03/15/2018 05:26 PM, mandy chung wrote: > On 3/15/18 3:58 AM, Aleksey Shipilev wrote: >> On 03/15/2018 10:38 AM, David Holmes wrote: >>> To be pedantic, talking about "overriding static methods" is as wrong as talking about "inheriting >>> static methods. They can't be inherited and so can't be overridden. >>> >>> In this context perhaps "intercept" would be a better choice? Or even "proxy"? >> All right, I made it "intercept". Submit-jdk tests returned fine. >> I am pushing, unless there other pedantic remarks :) > > "intercept" is a better choice.?? Good to go. Already in, thanks everyone! -Aleksey From paul.sandoz at oracle.com Thu Mar 15 17:06:41 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 15 Mar 2018 10:06:41 -0700 Subject: RFR 8193033 remove terminally deprecated sun.misc.Unsafe.defineClass Message-ID: <5E842D0A-B7F3-44BF-94EA-2CD7B8DA9057@oracle.com> Hi, Please review this patch to remove sun.misc.Unsafe.defineClass in 11. There has been much outreach, by Alan and the Jigsaw team, about its public replacement MethodHandles.Lookup.defineClass. CSR is here: https://bugs.openjdk.java.net/browse/JDK-8199699 Thanks, Paul. diff -r 3c0a12972165 src/jdk.unsupported/share/classes/sun/misc/Unsafe.java --- a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java Thu Mar 15 08:11:01 2018 -0700 +++ b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java Thu Mar 15 09:51:00 2018 -0700 @@ -811,25 +811,6 @@ /// random trusted operations from JNI: /** - * Tells the VM to define a class, without security checks. By default, the - * class loader and protection domain come from the caller's class. - * - * @deprecated Use {@link java.lang.invoke.MethodHandles.Lookup#defineClass MethodHandles.Lookup#defineClass} - * to define a class to the same class loader and in the same runtime package - * and {@linkplain java.security.ProtectionDomain protection domain} of a - * given {@code Lookup}'s {@linkplain java.lang.invoke.MethodHandles.Lookup#lookupClass() lookup class}. - * - * @see java.lang.invoke.MethodHandles.Lookup#defineClass(byte[]) - */ - @Deprecated(since="9", forRemoval=true) - @ForceInline - public Class defineClass(String name, byte[] b, int off, int len, - ClassLoader loader, - ProtectionDomain protectionDomain) { - return theInternalUnsafe.defineClass(name, b, off, len, loader, protectionDomain); - } - - /** * Defines a class but does not make it known to the class loader or system dictionary. *

* For each CP entry, the corresponding CP patch must either be null or have From chris.hegarty at oracle.com Thu Mar 15 17:16:47 2018 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Thu, 15 Mar 2018 17:16:47 +0000 Subject: RFR 8193033 remove terminally deprecated sun.misc.Unsafe.defineClass In-Reply-To: <5E842D0A-B7F3-44BF-94EA-2CD7B8DA9057@oracle.com> References: <5E842D0A-B7F3-44BF-94EA-2CD7B8DA9057@oracle.com> Message-ID: <24D7FB4D-291D-41FB-BF10-F52A5E45CD09@oracle.com> > On 15 Mar 2018, at 17:06, Paul Sandoz wrote: > > Hi, > > Please review this patch to remove sun.misc.Unsafe.defineClass in 11. > > There has been much outreach, by Alan and the Jigsaw team, about its public replacement MethodHandles.Lookup.defineClass. > > CSR is here: > > https://bugs.openjdk.java.net/browse/JDK-8199699 Looks good Paul. I don?t think that a CSR is strictly needed, but does no harm. -Chris. > Thanks, > Paul. > > > diff -r 3c0a12972165 src/jdk.unsupported/share/classes/sun/misc/Unsafe.java > --- a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java Thu Mar 15 08:11:01 2018 -0700 > +++ b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java Thu Mar 15 09:51:00 2018 -0700 > @@ -811,25 +811,6 @@ > /// random trusted operations from JNI: > > /** > - * Tells the VM to define a class, without security checks. By default, the > - * class loader and protection domain come from the caller's class. > - * > - * @deprecated Use {@link java.lang.invoke.MethodHandles.Lookup#defineClass MethodHandles.Lookup#defineClass} > - * to define a class to the same class loader and in the same runtime package > - * and {@linkplain java.security.ProtectionDomain protection domain} of a > - * given {@code Lookup}'s {@linkplain java.lang.invoke.MethodHandles.Lookup#lookupClass() lookup class}. > - * > - * @see java.lang.invoke.MethodHandles.Lookup#defineClass(byte[]) > - */ > - @Deprecated(since="9", forRemoval=true) > - @ForceInline > - public Class defineClass(String name, byte[] b, int off, int len, > - ClassLoader loader, > - ProtectionDomain protectionDomain) { > - return theInternalUnsafe.defineClass(name, b, off, len, loader, protectionDomain); > - } > - > - /** > * Defines a class but does not make it known to the class loader or system dictionary. > *

> * For each CP entry, the corresponding CP patch must either be null or have From mandy.chung at oracle.com Thu Mar 15 17:36:00 2018 From: mandy.chung at oracle.com (mandy chung) Date: Thu, 15 Mar 2018 10:36:00 -0700 Subject: RFR 8193033 remove terminally deprecated sun.misc.Unsafe.defineClass In-Reply-To: <5E842D0A-B7F3-44BF-94EA-2CD7B8DA9057@oracle.com> References: <5E842D0A-B7F3-44BF-94EA-2CD7B8DA9057@oracle.com> Message-ID: +1 Mandy On 3/15/18 10:06 AM, Paul Sandoz wrote: > Hi, > > Please review this patch to remove sun.misc.Unsafe.defineClass in 11. > > There has been much outreach, by Alan and the Jigsaw team, about its public replacement MethodHandles.Lookup.defineClass. > > CSR is here: > > https://bugs.openjdk.java.net/browse/JDK-8199699 > > Thanks, > Paul. > > > diff -r 3c0a12972165 src/jdk.unsupported/share/classes/sun/misc/Unsafe.java > --- a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java Thu Mar 15 08:11:01 2018 -0700 > +++ b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java Thu Mar 15 09:51:00 2018 -0700 > @@ -811,25 +811,6 @@ > /// random trusted operations from JNI: > > /** > - * Tells the VM to define a class, without security checks. By default, the > - * class loader and protection domain come from the caller's class. > - * > - * @deprecated Use {@link java.lang.invoke.MethodHandles.Lookup#defineClass MethodHandles.Lookup#defineClass} > - * to define a class to the same class loader and in the same runtime package > - * and {@linkplain java.security.ProtectionDomain protection domain} of a > - * given {@code Lookup}'s {@linkplain java.lang.invoke.MethodHandles.Lookup#lookupClass() lookup class}. > - * > - * @see java.lang.invoke.MethodHandles.Lookup#defineClass(byte[]) > - */ > - @Deprecated(since="9", forRemoval=true) > - @ForceInline > - public Class defineClass(String name, byte[] b, int off, int len, > - ClassLoader loader, > - ProtectionDomain protectionDomain) { > - return theInternalUnsafe.defineClass(name, b, off, len, loader, protectionDomain); > - } > - > - /** > * Defines a class but does not make it known to the class loader or system dictionary. > *

> * For each CP entry, the corresponding CP patch must either be null or have From Alan.Bateman at oracle.com Thu Mar 15 17:39:50 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 15 Mar 2018 17:39:50 +0000 Subject: RFR 8193033 remove terminally deprecated sun.misc.Unsafe.defineClass In-Reply-To: <5E842D0A-B7F3-44BF-94EA-2CD7B8DA9057@oracle.com> References: <5E842D0A-B7F3-44BF-94EA-2CD7B8DA9057@oracle.com> Message-ID: <2224e377-de1e-2dfb-f70c-026ba8eac4ce@oracle.com> On 15/03/2018 17:06, Paul Sandoz wrote: > Hi, > > Please review this patch to remove sun.misc.Unsafe.defineClass in 11. > > There has been much outreach, by Alan and the Jigsaw team, about its public replacement MethodHandles.Lookup.defineClass. > > CSR is here: > > https://bugs.openjdk.java.net/browse/JDK-8199699 > Looks good, I assume the import of java.security.ProtectionDomain can be removed too. -Alan From irogers at google.com Thu Mar 15 17:49:53 2018 From: irogers at google.com (Ian Rogers) Date: Thu, 15 Mar 2018 17:49:53 +0000 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: <1521102348.2448.25.camel@oracle.com> References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> <5A9D8F33.5060500@oracle.com> <5A9DAC84.906@oracle.com> <5A9DAE87.8020801@oracle.com> <1521102348.2448.25.camel@oracle.com> Message-ID: +hotspot-gc-dev On Thu, Mar 15, 2018 at 1:25 AM Thomas Schatzl wrote: > Hi, > > On Thu, 2018-03-15 at 01:00 +0000, Ian Rogers wrote: > > An old data point on how large a critical region should be comes from > > java.nio.Bits. In JDK 9 the code migrated into unsafe, but in JDK 8 > > the copies within a critical region were bound at most copying 1MB: > > http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/ > > native/java/nio/Bits.c#l88 This is inconsistent with Deflater and > > ObjectOutputStream which both allow unlimited arrays and thereby > > critical region sizes. > > > > In JDK 9 the copies starve the garbage collector in nio Bits too as > > there is no 1MB limit to the copy sizes: > > http://hg.openjdk.java.net/jdk/jdk/rev/f70e100d3195 > > which came from: > > https://bugs.openjdk.java.net/browse/JDK-8149596 > > > > Perhaps this is a regression not demonstrated due to the testing > > challenge. > > [...] > > It doesn't seem unreasonable to have the loops for the copies occur > > in 1MB chunks but JDK-8149596 lost this and so I'm confused on what > > the HotSpot stand point is. > > Please file a bug (seems to be a core-libs/java.nio regression?), > preferably with some kind of regression test. Also file enhancements (I > would guess) for the other cases allowing unlimited arrays. > I don't have perms to file bugs there's some catch-22 scenario in getting the permissions. Happy to have a bug filed or to file were that not an issue. Happy to create a test case but can't see any others for TTSP issues. This feels like a potential use case for jmh, perhaps run the benchmark well having a separate thread run GC bench. Should there be a bug to add, in debug mode, a TTSP watcher thread whose job it is to bring "random" threads into safepoints and report on tardy ones? Should there be a bug to warn on being in a JNI critical for more than just a short period? Seems like there should be a bug on Unsafe.copyMemory and Unsafe.copySwapMemory having TTSP issues. Seems like there should be a bug on all uses of critical that don't chunk their critical region work based on some bound (like 1MB chunks for nio Bits)? How are these bounds set? A past reference that I've lost is in having the bound be the equivalent of 65535 bytecodes due to the expectation of GC work at least once in a method or on a loop backedge - I thought this was in a spec somewhere but now I can't find it. The bytecode size feels as arbitrary as 1MB, a time period would be better but that can depend on the kind of GC you want as delays with concurrent GC mean more than non-concurrent. Clearly the chunk size shouldn't just be 0, but this appears to currently be the norm in the JDK. The original reason for coming here was a 140x slow down in -Xcheck:jni in Deflater.deflate There are a few options there that its useful to enumerate: 1) rewrite in Java but there are correctness and open source related issues 2) remove underflow/overflow protection from critical arrays (revert JDK-6311046 or perhaps bound protection to arrays of a particular small size) - this removes checking and doesn't deal with TTSP 3) add a critical array slice API to JNI so that copies with -Xcheck:jni aren't unbounded (martinrb@ proposed this) - keeps checking but doesn't deal with TTSP 4) rewrite primitive array criticals with GetArrayRegion as O(n) beats the "silent killer" TTSP (effectively deprecate the critical APIs) In general (ie not just the deflate case) I think (1) is the most preferable. (2) and (3) both have TTSP issues. (4) isn't great performance wise, which motivates more use of approach (1), but I think deprecating criticals may just be the easiest and sanest way forward. I think that discussion is worth having on an e-mail thread rather than a bug. > Long TTSP is a performance bug as any other. > > > In a way criticals are better than unsafe as they may > > pin the memory and not starve GC, which shenandoah does. > > (Region based) Object pinning has its own share of problems: > > - only (relatively) easily implemented in region based collectors > > - may slow down pause a bit in presence of pinned regions/objects (for > non-concurrent copying collectors) > > - excessive use of pinning may cause OOME and VM exit probably earlier > than the gc locker. GC locker seems to provide a more gradual > degradation. E.g. pinning regions typically makes these regions > unavailable for allocation. > I.e. you still should not use it for many, very long living objects. > Of course this somewhat depends on the sophistication of the > implementation. > > I think region based pinning would be a good addition to other > collectors than Shenandoah too. It has been on our minds for a long > time, but there are so many other more important issues :), so of > course we are eager to see contributions in this area. ;) > > If you are interested on working on this, please ping us on hotspot-gc- > dev for implementation ideas to get you jump-started. > > Thanks, > Thomas > I'd rather deprecate criticals than build upon the complexity, but I'm very glad this is a concern. Thanks, Ian From paul.sandoz at oracle.com Thu Mar 15 18:06:17 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 15 Mar 2018 11:06:17 -0700 Subject: RFR 8193033 remove terminally deprecated sun.misc.Unsafe.defineClass In-Reply-To: <2224e377-de1e-2dfb-f70c-026ba8eac4ce@oracle.com> References: <5E842D0A-B7F3-44BF-94EA-2CD7B8DA9057@oracle.com> <2224e377-de1e-2dfb-f70c-026ba8eac4ce@oracle.com> Message-ID: > On Mar 15, 2018, at 10:39 AM, Alan Bateman wrote: > > On 15/03/2018 17:06, Paul Sandoz wrote: >> Hi, >> >> Please review this patch to remove sun.misc.Unsafe.defineClass in 11. >> >> There has been much outreach, by Alan and the Jigsaw team, about its public replacement MethodHandles.Lookup.defineClass. >> >> CSR is here: >> >> https://bugs.openjdk.java.net/browse/JDK-8199699 >> > Looks good, I assume the import of java.security.ProtectionDomain can be removed too. > Yes, thanks, Paul. From brian.burkhalter at oracle.com Thu Mar 15 21:52:50 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Thu, 15 Mar 2018 14:52:50 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> Message-ID: <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> On Mar 15, 2018, at 8:56 AM, Brian Burkhalter wrote: > On Mar 15, 2018, at 7:33 AM, Roger Riggs wrote: > >> BAOS.java: >> >> line 163: ok but I don't think I would keep using the expanded 'byte array output stream" phrase >> instead of the proper noun: ByteArrayOutputStream. (except for consistency) > > I don?t like it either: I was just maintaining consistency (as you observed the other usages). Changed ?byte array output stream? globally to {@code ByteArratOutputStream}." >> In the Write.java test: >> >> line 60: Probably "-" in the message should be "--" for consistency >> >> line 68: Add the "e" Throwable to the thrown RuntimeException so it gets printed in a stack trace/message >> >> Line 100:.. If this was a testng test, the Assert.assertEquals messages would conveniently >> print expected and actual values. I'd suggest converting it to use @run testng. >> >> (Though I expect after these are debugged, they will never fail). >> >> 73: some formatting cleanup of the old code might be useful. (spaces around "=") > > Will update. Converted to TestNG and fixed all the above. Also replaced initialization of the local Random variable to use RandomFactory. Updated patch: http://cr.openjdk.java.net/~bpb/8180410/webrev.01/. Thanks, Brian From alexandre.iline at oracle.com Thu Mar 15 22:40:14 2018 From: alexandre.iline at oracle.com (Alexandre (Shura) Iline) Date: Thu, 15 Mar 2018 15:40:14 -0700 Subject: RFR 8199616: Fix @module declarations in tier1 tests Message-ID: Hi, Please take a quick look on fix adding missing module dependencies to tests in :tier1 jdk tests. Webrev: http://cr.openjdk.java.net/~shurailine/8199616/webrev.00 Shura. From mandy.chung at oracle.com Thu Mar 15 23:15:31 2018 From: mandy.chung at oracle.com (mandy chung) Date: Thu, 15 Mar 2018 16:15:31 -0700 Subject: RFR 8199616: Fix @module declarations in tier1 tests In-Reply-To: References: Message-ID: On 3/15/18 3:40 PM, Alexandre (Shura) Iline wrote: > Hi, > > Please take a quick look on fix adding missing module dependencies to tests in :tier1 jdk tests. > > Webrev: http://cr.openjdk.java.net/~shurailine/8199616/webrev.00 Looks okay.?? But I'm surprised that test/jdk/java/lang/ProcessHandle/OnExitTest.java requires ?? 44? * @modules jdk.management Looks like jdk.management get pulled by the test library.? If so, we should file JBS issue to fix the test library to eliminate such dependency. Mandy From martinrb at google.com Thu Mar 15 23:30:52 2018 From: martinrb at google.com (Martin Buchholz) Date: Thu, 15 Mar 2018 23:30:52 +0000 Subject: RFR 8199616: Fix @module declarations in tier1 tests In-Reply-To: References: Message-ID: How did you find the missing module dependencies? Why was it only noticed now? Can we automatically prevent backsliding? On Thu, Mar 15, 2018 at 3:40 PM Alexandre (Shura) Iline < alexandre.iline at oracle.com> wrote: > Hi, > > Please take a quick look on fix adding missing module dependencies to > tests in :tier1 jdk tests. > > Webrev: http://cr.openjdk.java.net/~shurailine/8199616/webrev.00 > > Shura. > > From alexandre.iline at oracle.com Thu Mar 15 23:35:04 2018 From: alexandre.iline at oracle.com (Alexandre (Shura) Iline) Date: Thu, 15 Mar 2018 16:35:04 -0700 Subject: RFR 8199616: Fix @module declarations in tier1 tests In-Reply-To: References: Message-ID: <8B718BA9-B7C3-494A-B4AF-57AD628F10C0@oracle.com> > On Mar 15, 2018, at 4:15 PM, mandy chung wrote: > > > > On 3/15/18 3:40 PM, Alexandre (Shura) Iline wrote: >> Hi, >> >> Please take a quick look on fix adding missing module dependencies to tests in :tier1 jdk tests. >> >> Webrev: >> http://cr.openjdk.java.net/~shurailine/8199616/webrev.00 > > Looks okay. But I'm surprised that test/jdk/java/lang/ProcessHandle/OnExitTest.java requires > 44 * @modules jdk.management > > Looks like jdk.management get pulled by the test library. Actually java/lang/ProcessHandle/JavaChild.java has a dependency on com.sun.management.OperatingSystemMXBean. Shura > If so, we should file JBS issue to fix the test library to eliminate such dependency. > > Mandy From alexandre.iline at oracle.com Fri Mar 16 00:11:43 2018 From: alexandre.iline at oracle.com (Alexandre (Shura) Iline) Date: Thu, 15 Mar 2018 17:11:43 -0700 Subject: RFR 8199616: Fix @module declarations in tier1 tests In-Reply-To: References: Message-ID: Martin, > On Mar 15, 2018, at 4:30 PM, Martin Buchholz wrote: > > How did you find the missing module dependencies? I have a tool which runs tests one by one like this (I am simplifying): - run test with -javaoptions:??limit-modules ?? with only the modules listed through @modules - if fails, run test with no ?limit-modules - if passes, that is a potential problem. We are thinking about making the tool open-source in code-tools project in one form or another. Tool aside, everybody is free to use ?limit-modules on a newly created test. > Why was it only noticed now? It was not - I have just gotten around fixing it. There are more known @module deficiencies right now. > Can we automatically prevent backsliding? That would be a job for a continuous integration system, I imagine. Shura > > > On Thu, Mar 15, 2018 at 3:40 PM Alexandre (Shura) Iline > wrote: > Hi, > > Please take a quick look on fix adding missing module dependencies to tests in :tier1 jdk tests. > > Webrev: http://cr.openjdk.java.net/~shurailine/8199616/webrev.00 > > Shura. > From martinrb at google.com Fri Mar 16 02:14:29 2018 From: martinrb at google.com (Martin Buchholz) Date: Fri, 16 Mar 2018 02:14:29 +0000 Subject: RFR 8199616: Fix @module declarations in tier1 tests In-Reply-To: References: Message-ID: Interesting. Is the end goal to have jtreg itself validate the @modules tag or to execute each test as its own module? It seems like the sort of checking your tool is doing belongs in jtreg itself. On Thu, Mar 15, 2018 at 5:12 PM Alexandre (Shura) Iline < alexandre.iline at oracle.com> wrote: > Martin, > > > On Mar 15, 2018, at 4:30 PM, Martin Buchholz wrote: > > How did you find the missing module dependencies? > > > I have a tool which runs tests one by one like this (I am simplifying): > - run test with -javaoptions:??limit-modules ?? with only the modules > listed through @modules > - if fails, run test with no ?limit-modules > - if passes, that is a potential problem. > We are thinking about making the tool open-source in code-tools project in > one form or another. > > Tool aside, everybody is free to use ?limit-modules on a newly created > test. > > Why was it only noticed now? > > > It was not - I have just gotten around fixing it. There are more known > @module deficiencies right now. > > Can we automatically prevent backsliding? > > > That would be a job for a continuous integration system, I imagine. > > Shura > > > > > On Thu, Mar 15, 2018 at 3:40 PM Alexandre (Shura) Iline < > alexandre.iline at oracle.com> wrote: > >> Hi, >> >> Please take a quick look on fix adding missing module dependencies to >> tests in :tier1 jdk tests. >> >> Webrev: http://cr.openjdk.java.net/~shurailine/8199616/webrev.00 >> >> Shura. >> >> > From mandy.chung at oracle.com Fri Mar 16 02:24:42 2018 From: mandy.chung at oracle.com (mandy chung) Date: Thu, 15 Mar 2018 19:24:42 -0700 Subject: RFR 8199616: Fix @module declarations in tier1 tests In-Reply-To: <8B718BA9-B7C3-494A-B4AF-57AD628F10C0@oracle.com> References: <8B718BA9-B7C3-494A-B4AF-57AD628F10C0@oracle.com> Message-ID: <9996b2c5-cfb9-5466-d705-fd5b84b94229@oracle.com> On 3/15/18 4:35 PM, Alexandre (Shura) Iline wrote: > > Actually java/lang/ProcessHandle/JavaChild.java has a dependency on com.sun.management.OperatingSystemMXBean. > I see.? Thanks Mandy From alexandre.iline at oracle.com Fri Mar 16 02:25:08 2018 From: alexandre.iline at oracle.com (Alexandre (Shura) Iline) Date: Thu, 15 Mar 2018 19:25:08 -0700 Subject: RFR 8199616: Fix @module declarations in tier1 tests In-Reply-To: References: Message-ID: <17238A0D-A757-4E1D-AEB5-A7C9CFC0AD86@oracle.com> > On Mar 15, 2018, at 7:14 PM, Martin Buchholz wrote: > > Interesting. > > Is the end goal to have jtreg itself validate the @modules tag or to execute each test as its own module? It seems like the sort of checking your tool is doing belongs in jtreg itself. That is indeed one of the options we are discussing. Shura > > > On Thu, Mar 15, 2018 at 5:12 PM Alexandre (Shura) Iline > wrote: > Martin, > > >> On Mar 15, 2018, at 4:30 PM, Martin Buchholz > wrote: >> >> How did you find the missing module dependencies? > > I have a tool which runs tests one by one like this (I am simplifying): > - run test with -javaoptions:??limit-modules ?? with only the modules listed through @modules > - if fails, run test with no ?limit-modules > - if passes, that is a potential problem. > We are thinking about making the tool open-source in code-tools project in one form or another. > > Tool aside, everybody is free to use ?limit-modules on a newly created test. > >> Why was it only noticed now? > > It was not - I have just gotten around fixing it. There are more known @module deficiencies right now. > >> Can we automatically prevent backsliding? > > That would be a job for a continuous integration system, I imagine. > > Shura > > >> >> >> On Thu, Mar 15, 2018 at 3:40 PM Alexandre (Shura) Iline > wrote: >> Hi, >> >> Please take a quick look on fix adding missing module dependencies to tests in :tier1 jdk tests. >> >> Webrev: http://cr.openjdk.java.net/~shurailine/8199616/webrev.00 >> >> Shura. >> > From patrick at reini.net Fri Mar 16 06:10:46 2018 From: patrick at reini.net (Patrick Reinhart) Date: Fri, 16 Mar 2018 07:10:46 +0100 Subject: RFR 8196298 Add null Reader and Writer with latest changes In-Reply-To: <21DAB782-B121-4117-BBC4-CEA983DC523D@reini.net> References: <6AF3DEA9-5572-47B1-804E-AD7B0E46D833@reini.net> <3ebd00ec-aa2d-65b9-9f68-0d693628ef2b@oracle.com> <5a9ef0dc.77b0df0a.bb39.cc95@mx.google.com> <5D587382-6466-4854-8C70-68CBC8C7332E@oracle.com> <21DAB782-B121-4117-BBC4-CEA983DC523D@reini.net> Message-ID: <2EA55A50-797E-4BE1-9A1C-E41B5FB3C199@reini.net> Just coming back on my webrev [1]. Are there any more feedbacks implementation wise to that latest version? If no I would need a commit sponsor for this change as the CSR [2] is reviewed and closed. -Patrick [1] http://cr.openjdk.java.net/~reinhapa/reviews/8196298/webrev.02 [2] https://bugs.openjdk.java.net/browse/JDK-8196350 > Am 07.03.2018 um 11:41 schrieb Patrick Reinhart : > > I applied those changes here: > > http://cr.openjdk.java.net/~reinhapa/reviews/8196298/webrev.02 > > -Patrick > > >> Am 06.03.2018 um 23:12 schrieb Brian Burkhalter : >> >> Yes, I think so and and also the parameter ?csq' is allowed to be null so Objects.requireNonNull(csq) should be removed at lines 100 and 107 as no NPE is specified for these methods [1, 2]. >> >> Thanks, >> >> Brian >> >> [1] https://download.java.net/java/jdk10/docs/api/java/io/Writer.html#append(java.lang.CharSequence) >> [2] https://download.java.net/java/jdk10/docs/api/java/io/Writer.html#append(java.lang.CharSequence,int,int) >> >> On Mar 6, 2018, at 11:49 AM, Bernd Eckenfels wrote: >> >>> Just a nit, Should append(CharSequence,int,int) also use checkFromIndexSize? >> > From amaembo at gmail.com Fri Mar 16 06:18:13 2018 From: amaembo at gmail.com (Tagir Valeev) Date: Fri, 16 Mar 2018 13:18:13 +0700 Subject: Always false expressions in ConcurrentHashMap source Message-ID: Hello! Experimenting with code static analysis I found several always false expressions in ConcurrentHashMap source. See addCount method: http://hg.openjdk.java.net/jdk/jdk/file/422615764e12/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java#l2352 if (sc < 0) { if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 || sc == rs + MAX_RESIZERS || ... RESIZE_STAMP_SHIFT is 16, MAX_RESIZERS is 65535 While sc is a negative inside if, "(sc >>> RESIZE_STAMP_SHIFT)" is a positive number (more precisely, in {32768..65535} range). So if the "(sc >>> RESIZE_STAMP_SHIFT) != rs" is false, then rs is equal to "(sc >>> RESIZE_STAMP_SHIFT)", thus it's also in the same range. This makes the condition "sc == rs + 1" always false when reached (rs+1 is {32769..65536}, but sc is negative here). Also "sc == rs + MAX_RESIZERS" is always false when reached (rs+MAX_RESIZERS is {98303..131070}). Similar code also appears in helpTransfer method below (line 2378) and also contains two always false conditions. I don't know whether something else was meant here, or these checks are redundant. Just wanted to draw your attention. With best regards, Tagir Valeev. From Alan.Bateman at oracle.com Fri Mar 16 07:29:52 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 16 Mar 2018 07:29:52 +0000 Subject: RFR 8199616: Fix @module declarations in tier1 tests In-Reply-To: References: Message-ID: <893c9cfa-9ab7-24f4-4819-c94ce732fada@oracle.com> On 15/03/2018 22:40, Alexandre (Shura) Iline wrote: > Hi, > > Please take a quick look on fix adding missing module dependencies to tests in :tier1 jdk tests. > > Webrev: http://cr.openjdk.java.net/~shurailine/8199616/webrev.00 > Some of these dependences weren't obvious until I skimmed more of the test. In any case, what you have is correct and looks good to me. -Alan. From dl at cs.oswego.edu Fri Mar 16 10:09:09 2018 From: dl at cs.oswego.edu (Doug Lea) Date: Fri, 16 Mar 2018 06:09:09 -0400 Subject: Always false expressions in ConcurrentHashMap source In-Reply-To: References: Message-ID: On 03/16/2018 02:18 AM, Tagir Valeev wrote: > Hello! > > Experimenting with code static analysis I found several always false > expressions in ConcurrentHashMap source. See addCount method: > > http://hg.openjdk.java.net/jdk/jdk/file/422615764e12/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java#l2352 > > if (sc < 0) { > if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 || > sc == rs + MAX_RESIZERS || ... > > RESIZE_STAMP_SHIFT is 16, MAX_RESIZERS is 65535 Right. The code was initially designed to work with any values for these constants. But upon experimentation, the current values were chosen in part so that this case would not trigger. Still, it is cheap enough to keep the check here. -Doug > > While sc is a negative inside if, "(sc >>> RESIZE_STAMP_SHIFT)" is a > positive number (more precisely, in {32768..65535} range). So if the "(sc >>>> RESIZE_STAMP_SHIFT) != rs" is false, then > rs is equal to "(sc >>> RESIZE_STAMP_SHIFT)", thus it's also in the same > range. This makes the condition "sc == rs + 1" always false when reached > (rs+1 is {32769..65536}, but sc is negative here). Also "sc == rs + > MAX_RESIZERS" is always false when reached (rs+MAX_RESIZERS is > {98303..131070}). > > Similar code also appears in helpTransfer method below (line 2378) and also > contains two always false conditions. > > I don't know whether something else was meant here, or these checks are > redundant. Just wanted to draw your attention. > > With best regards, > Tagir Valeev. > From david.lloyd at redhat.com Fri Mar 16 13:25:51 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Fri, 16 Mar 2018 08:25:51 -0500 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: <5AA9D228.8070407@oracle.com> References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> Message-ID: Sorry, that was an error on my part, caused by too much context switching. I've posted an update at https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v13 which is also attached. On Wed, Mar 14, 2018 at 8:53 PM, Xueming Shen wrote: > Hi David, > > https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v12 > > Should we start to review the changes included in above link, or we should > wait ? It appears > the API is being updated but some implementation have not been updated to > follow the spec > yet, especially the piece that deals with the output buffer/byteWritten when > DataFormatException > is raised, for example > > (1) the "outputConsumedID" is defined but never used to update the > corresponding java field > in Inflater.c and > > (2) the "outputConsumed" is used to update the output ByteBuffer when DFE > raised (in Java), but > the corresponding "byteWritten" is not being updated before the > exception is thrown. > > -Sherman > > > > > On 3/13/18, 10:46 AM, David Lloyd wrote: >> >> Sorry all, it looks like GMail doesn't know how to keep replies with >> the thread when you change the subject line. The follow-up to this >> thread is >> http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-March/051960.html >> with only a few small changes as discussed above. >> >> On Fri, Mar 2, 2018 at 2:36 PM, David Lloyd >> wrote: >>> >>> On Fri, Mar 2, 2018 at 2:34 PM, David Lloyd >>> wrote: >>>> >>>> On Fri, Mar 2, 2018 at 12:49 PM, Xueming Shen >>>> wrote: >>>>> >>>>> Hi David, >>>>> >>>>> (1) Deflater.deflate(Bytebuffer) >>>>> the api doc regarding "no_flush" appears to be the copy/paste of >>>>> the >>>>> byte[] version >>>>> without being updated to the corresponding ByteBuffer? >>>> >>>> You're right, I missed that one. I've incorporated this fix locally: >>> >>> Oops, this should have been: >>> >>> --- 8< --- cut here --- 8< --- >>> >>> diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java >>> b/src/java.base/share/classes/java/util/zip/Deflater.java >>> index 524125787a8..40f0d9736e2 100644 >>> --- a/src/java.base/share/classes/java/util/zip/Deflater.java >>> +++ b/src/java.base/share/classes/java/util/zip/Deflater.java >>> @@ -481,9 +481,9 @@ public class Deflater { >>> * in order to determine if more input data is required. >>> * >>> *

This method uses {@link #NO_FLUSH} as its compression flush >>> mode. >>> - * An invocation of this method of the form {@code >>> deflater.deflate(b)} >>> + * An invocation of this method of the form {@code >>> deflater.deflate(output)} >>> * yields the same result as the invocation of >>> - * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. >>> + * {@code deflater.deflate(output, Deflater.NO_FLUSH)}. >>> * >>> * @param output the buffer for the compressed data >>> * @return the actual number of bytes of compressed data written to >>> the >>> >>> --- 8< --- cut here --- 8< --- >>> >>> -- >>> - DML >> >> >> > -- - DML -------------- next part -------------- commit ee5f766eeb64d5afa1f3ec1153b3184de35ff198 Author: David M. Lloyd Date: Fri Feb 16 11:00:10 2018 -0600 [JDK-6341887] Update Inflater/Deflater to handle ByteBuffer diff --git a/make/mapfiles/libzip/mapfile-vers b/make/mapfiles/libzip/mapfile-vers index d711d8e17f4..11ccc2d6ecb 100644 --- a/make/mapfiles/libzip/mapfile-vers +++ b/make/mapfiles/libzip/mapfile-vers @@ -33,20 +33,28 @@ SUNWprivate_1.1 { Java_java_util_zip_CRC32_update; Java_java_util_zip_CRC32_updateBytes0; Java_java_util_zip_CRC32_updateByteBuffer0; - Java_java_util_zip_Deflater_deflateBytes; + Java_java_util_zip_Deflater_deflateBytesBytes; + Java_java_util_zip_Deflater_deflateBytesBuffer; + Java_java_util_zip_Deflater_deflateBufferBytes; + Java_java_util_zip_Deflater_deflateBufferBuffer; Java_java_util_zip_Deflater_end; Java_java_util_zip_Deflater_getAdler; Java_java_util_zip_Deflater_init; Java_java_util_zip_Deflater_initIDs; Java_java_util_zip_Deflater_reset; Java_java_util_zip_Deflater_setDictionary; + Java_java_util_zip_Deflater_setDictionaryBuffer; Java_java_util_zip_Inflater_end; Java_java_util_zip_Inflater_getAdler; - Java_java_util_zip_Inflater_inflateBytes; + Java_java_util_zip_Inflater_inflateBytesBytes; + Java_java_util_zip_Inflater_inflateBytesBuffer; + Java_java_util_zip_Inflater_inflateBufferBytes; + Java_java_util_zip_Inflater_inflateBufferBuffer; Java_java_util_zip_Inflater_init; Java_java_util_zip_Inflater_initIDs; Java_java_util_zip_Inflater_reset; Java_java_util_zip_Inflater_setDictionary; + Java_java_util_zip_Inflater_setDictionaryBuffer; ZIP_Close; ZIP_CRC32; ZIP_FreeEntry; diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java b/src/java.base/share/classes/java/util/zip/Deflater.java index c75dd4a33f0..40f0d9736e2 100644 --- a/src/java.base/share/classes/java/util/zip/Deflater.java +++ b/src/java.base/share/classes/java/util/zip/Deflater.java @@ -26,7 +26,13 @@ package java.util.zip; import java.lang.ref.Cleaner.Cleanable; +import java.lang.ref.Reference; +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; +import java.util.Objects; + import jdk.internal.ref.CleanerFactory; +import sun.nio.ch.DirectBuffer; /** * This class provides support for general purpose compression using the @@ -92,8 +98,9 @@ import jdk.internal.ref.CleanerFactory; public class Deflater { private final DeflaterZStreamRef zsRef; - private byte[] buf = new byte[0]; - private int off, len; + private ByteBuffer input = ZipUtils.defaultBuf; + private byte[] inputArray; + private int inputPos, inputLim; private int level, strategy; private boolean setParams; private boolean finish, finished; @@ -170,9 +177,14 @@ public class Deflater { */ public static final int FULL_FLUSH = 3; + /** + * Flush mode to use at the end of output. Can only be provided by the + * user by way of {@link #finish()}. + */ + private static final int FINISH = 4; + static { ZipUtils.loadLibrary(); - initIDs(); } /** @@ -216,16 +228,14 @@ public class Deflater { * @see Deflater#needsInput */ public void setInput(byte[] b, int off, int len) { - if (b== null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { - this.buf = b; - this.off = off; - this.len = len; + this.input = null; + this.inputArray = b; + this.inputPos = off; + this.inputLim = off + len; } } @@ -239,6 +249,31 @@ public class Deflater { setInput(b, 0, b.length); } + /** + * Sets input data for compression. This should be called whenever + * needsInput() returns true indicating that more input data is required. + *

+ * The given buffer's position will be updated as deflate operations are + * performed. The input buffer may be modified (refilled) between deflate + * operations; doing so is equivalent to creating a new buffer and setting + * it with this method. + *

+ * Modifying the input buffer's contents, position, or limit concurrently with + * a deflate operation will result in undefined behavior, which may include + * incorrect operation results or operation failure. + * + * @param byteBuffer the input data bytes + * @see Deflater#needsInput + * @since 11 + */ + public void setInput(ByteBuffer byteBuffer) { + Objects.requireNonNull(byteBuffer); + synchronized (zsRef) { + this.input = byteBuffer; + this.inputArray = null; + } + } + /** * Sets preset dictionary for compression. A preset dictionary is used * when the history buffer can be predetermined. When the data is later @@ -252,9 +287,6 @@ public class Deflater { * @see Inflater#getAdler */ public void setDictionary(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } @@ -278,6 +310,41 @@ public class Deflater { setDictionary(b, 0, b.length); } + /** + * Sets preset dictionary for compression. A preset dictionary is used + * when the history buffer can be predetermined. When the data is later + * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called + * in order to get the Adler-32 value of the dictionary required for + * decompression. + *

+ * The bytes in given byte buffer will be fully consumed by this method. On + * return, its position will equal its limit. + * + * @param byteBuffer the dictionary data bytes + * @see Inflater#inflate + * @see Inflater#getAdler + */ + public void setDictionary(ByteBuffer byteBuffer) { + synchronized (zsRef) { + final int position = byteBuffer.position(); + final int remaining = Math.max(byteBuffer.limit() - position, 0); + ensureOpen(); + if (byteBuffer.isDirect()) { + final long address = ((DirectBuffer) byteBuffer).address(); + try { + setDictionaryBuffer(zsRef.address(), address + position, remaining); + } finally { + Reference.reachabilityFence(byteBuffer); + } + } else { + final byte[] array = ZipUtils.getBufferArray(byteBuffer); + final int offset = ZipUtils.getBufferOffset(byteBuffer); + setDictionary(zsRef.address(), array, offset + position, remaining); + } + byteBuffer.position(position + remaining); + } + } + /** * Sets the compression strategy to the specified value. * @@ -331,14 +398,17 @@ public class Deflater { } /** - * Returns true if the input data buffer is empty and setInput() - * should be called in order to provide more input. + * Returns true if no data remains in the input buffer. This can + * be used to determine if one of the {@code setInput()} methods should be + * called in order to provide more input. + * * @return true if the input data buffer is empty and setInput() * should be called in order to provide more input */ public boolean needsInput() { synchronized (zsRef) { - return len <= 0; + final ByteBuffer input = this.input; + return input == null ? inputLim == inputPos : ! input.hasRemaining(); } } @@ -404,6 +474,26 @@ public class Deflater { return deflate(b, 0, b.length, NO_FLUSH); } + /** + * Compresses the input data and fills specified buffer with compressed + * data. Returns actual number of bytes of compressed data. A return value + * of 0 indicates that {@link #needsInput() needsInput} should be called + * in order to determine if more input data is required. + * + *

This method uses {@link #NO_FLUSH} as its compression flush mode. + * An invocation of this method of the form {@code deflater.deflate(output)} + * yields the same result as the invocation of + * {@code deflater.deflate(output, Deflater.NO_FLUSH)}. + * + * @param output the buffer for the compressed data + * @return the actual number of bytes of compressed data written to the + * output buffer + * @since 11 + */ + public int deflate(ByteBuffer output) { + return deflate(output, NO_FLUSH); + } + /** * Compresses the input data and fills the specified buffer with compressed * data. Returns actual number of bytes of data compressed. @@ -441,6 +531,10 @@ public class Deflater { * repeatedly output to the output buffer every time this method is * invoked. * + *

If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation. + * * @param b the buffer for the compressed data * @param off the start offset of the data * @param len the maximum number of bytes of compressed data @@ -452,24 +546,247 @@ public class Deflater { * @since 1.7 */ public int deflate(byte[] b, int off, int len, int flush) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } + if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) { + throw new IllegalArgumentException(); + } synchronized (zsRef) { ensureOpen(); - if (flush == NO_FLUSH || flush == SYNC_FLUSH || - flush == FULL_FLUSH) { - int thisLen = this.len; - int n = deflateBytes(zsRef.address(), b, off, len, flush); - bytesWritten += n; - bytesRead += (thisLen - this.len); - return n; + + final ByteBuffer input = this.input; + if (finish) { + // disregard given flush mode in this case + flush = FINISH; + } + final int params; + if (setParams) { + // bit 0: true to set params + // bit 1-2: strategy (0, 1, or 2) + // bit 3-31: level (0..9 or -1) + params = 1 | strategy << 1 | level << 3; + } else { + params = 0; + } + final int inputPos; + final long result; + if (input == null) { + inputPos = this.inputPos; + result = deflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + b, off, len, + flush, params); + } else { + inputPos = input.position(); + final int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + try { + final long inputAddress = ((DirectBuffer) input).address(); + result = deflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + b, off, len, + flush, params); + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + b, off, len, + flush, params); + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if (params != 0 && (result >>> 63 & 1) == 0) { + setParams = false; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; } + bytesWritten += written; + bytesRead += read; + return written; + } + } + + /** + * Compresses the input data and fills the specified buffer with compressed + * data. Returns actual number of bytes of data compressed. + * + *

Compression flush mode is one of the following three modes: + * + *

    + *
  • {@link #NO_FLUSH}: allows the deflater to decide how much data + * to accumulate, before producing output, in order to achieve the best + * compression (should be used in normal use scenario). A return value + * of 0 in this flush mode indicates that {@link #needsInput()} should + * be called in order to determine if more input data is required. + * + *
  • {@link #SYNC_FLUSH}: all pending output in the deflater is flushed, + * to the specified output buffer, so that an inflater that works on + * compressed data can get all input data available so far (In particular + * the {@link #needsInput()} returns {@code true} after this invocation + * if enough output space is provided). Flushing with {@link #SYNC_FLUSH} + * may degrade compression for some compression algorithms and so it + * should be used only when necessary. + * + *
  • {@link #FULL_FLUSH}: all pending output is flushed out as with + * {@link #SYNC_FLUSH}. The compression state is reset so that the inflater + * that works on the compressed output data can restart from this point + * if previous compressed data has been damaged or if random access is + * desired. Using {@link #FULL_FLUSH} too often can seriously degrade + * compression. + *
+ * + *

In the case of {@link #FULL_FLUSH} or {@link #SYNC_FLUSH}, if + * the return value is {@code len}, the space available in output + * buffer {@code output}, this method should be invoked again with the same + * {@code flush} parameter and more output space. Make sure that + * {@code len} is greater than 6 to avoid flush marker (5 bytes) being + * repeatedly output to the output buffer every time this method is + * invoked. + * + *

On success, the position of the given {@code output} byte buffer will be + * advanced by as many bytes as were produced by the operation, which is equal + * to the number returned by this method. + * + *

If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation. + * + * @param output the buffer for the compressed data + * @param flush the compression flush mode + * @return the actual number of bytes of compressed data written to + * the output buffer + * + * @throws IllegalArgumentException if the flush mode is invalid + * @since 11 + */ + public int deflate(ByteBuffer output, int flush) { + if (output.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) { throw new IllegalArgumentException(); } + synchronized (zsRef) { + ensureOpen(); + + final ByteBuffer input = this.input; + if (finish) { + // disregard given flush mode in this case + flush = FINISH; + } + final int params; + if (setParams) { + // bit 0: true to set params + // bit 1-2: strategy (0, 1, or 2) + // bit 3-31: level (0..9 or -1) + params = 1 | strategy << 1 | level << 3; + } else { + params = 0; + } + final int outputPos = output.position(); + final int outputRem = Math.max(output.limit() - outputPos, 0); + final int inputPos; + final long result; + if (input == null) { + inputPos = this.inputPos; + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = deflateBytesBuffer(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputAddress + outputPos, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } else { + inputPos = input.position(); + final int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + final long inputAddress = ((DirectBuffer) input).address(); + try { + if (output.isDirect()) { + final long outputAddress = outputPos + ((DirectBuffer) output).address(); + try { + result = deflateBufferBuffer(zsRef.address(), + inputAddress + inputPos, inputRem, + outputAddress, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = deflateBytesBuffer(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputAddress + outputPos, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if (params != 0 && (result >>> 63 & 1) == 0) { + setParams = false; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + output.position(outputPos + written); + bytesWritten += written; + bytesRead += read; + return written; + } } /** @@ -545,7 +862,8 @@ public class Deflater { reset(zsRef.address()); finish = false; finished = false; - off = len = 0; + input = ZipUtils.defaultBuf; + inputArray = null; bytesRead = bytesWritten = 0; } } @@ -560,7 +878,7 @@ public class Deflater { public void end() { synchronized (zsRef) { zsRef.clean(); - buf = null; + input = ZipUtils.defaultBuf; } } @@ -585,11 +903,26 @@ public class Deflater { throw new NullPointerException("Deflater has been closed"); } - private static native void initIDs(); private static native long init(int level, int strategy, boolean nowrap); - private static native void setDictionary(long addr, byte[] b, int off, int len); - private native int deflateBytes(long addr, byte[] b, int off, int len, - int flush); + private static native void setDictionary(long addr, byte[] b, int off, + int len); + private static native void setDictionaryBuffer(long addr, long bufAddress, int len); + private native long deflateBytesBytes(long addr, + byte[] inputArray, int inputOff, int inputLen, + byte[] outputArray, int outputOff, int outputLen, + int flush, int params); + private native long deflateBytesBuffer(long addr, + byte[] inputArray, int inputOff, int inputLen, + long outputAddress, int outputLen, + int flush, int params); + private native long deflateBufferBytes(long addr, + long inputAddress, int inputLen, + byte[] outputArray, int outputOff, int outputLen, + int flush, int params); + private native long deflateBufferBuffer(long addr, + long inputAddress, int inputLen, + long outputAddress, int outputLen, + int flush, int params); private static native int getAdler(long addr); private static native void reset(long addr); private static native void end(long addr); diff --git a/src/java.base/share/classes/java/util/zip/Inflater.java b/src/java.base/share/classes/java/util/zip/Inflater.java index 9c6d8aa3d83..13375341df6 100644 --- a/src/java.base/share/classes/java/util/zip/Inflater.java +++ b/src/java.base/share/classes/java/util/zip/Inflater.java @@ -26,7 +26,13 @@ package java.util.zip; import java.lang.ref.Cleaner.Cleanable; +import java.lang.ref.Reference; +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; +import java.util.Objects; + import jdk.internal.ref.CleanerFactory; +import sun.nio.ch.DirectBuffer; /** * This class provides support for general purpose decompression using the @@ -92,14 +98,20 @@ import jdk.internal.ref.CleanerFactory; public class Inflater { private final InflaterZStreamRef zsRef; - private byte[] buf = defaultBuf; - private int off, len; + private ByteBuffer input = ZipUtils.defaultBuf; + private byte[] inputArray; + private int inputPos, inputLim; private boolean finished; private boolean needDict; private long bytesRead; private long bytesWritten; - private static final byte[] defaultBuf = new byte[0]; + /* + * These fields are used as an "out" parameter from JNI when a + * DataFormatException is thrown during the inflate operation. + */ + private int inputConsumed; + private int outputConsumed; static { ZipUtils.loadLibrary(); @@ -138,16 +150,14 @@ public class Inflater { * @see Inflater#needsInput */ public void setInput(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { - this.buf = b; - this.off = off; - this.len = len; + this.input = null; + this.inputArray = b; + this.inputPos = off; + this.inputLim = off + len; } } @@ -162,6 +172,32 @@ public class Inflater { setInput(b, 0, b.length); } + /** + * Sets input data for decompression. Should be called whenever + * needsInput() returns true indicating that more input data is + * required. + *

+ * The given buffer's position will be updated as inflate operations are + * performed. The input buffer may be modified (refilled) between inflate + * operations; doing so is equivalent to creating a new buffer and setting + * it with this method. + *

+ * Modifying the input buffer's contents, position, or limit concurrently with + * an inflate operation will result in undefined behavior, which may include + * incorrect operation results or operation failure. + * + * @param byteBuffer the input data bytes + * @see Inflater#needsInput + * @since 11 + */ + public void setInput(ByteBuffer byteBuffer) { + Objects.requireNonNull(byteBuffer); + synchronized (zsRef) { + this.input = byteBuffer; + this.inputArray = null; + } + } + /** * Sets the preset dictionary to the given array of bytes. Should be * called when inflate() returns 0 and needsDictionary() returns true @@ -174,9 +210,6 @@ public class Inflater { * @see Inflater#getAdler */ public void setDictionary(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } @@ -200,6 +233,42 @@ public class Inflater { setDictionary(b, 0, b.length); } + /** + * Sets the preset dictionary to the given array of bytes. Should be + * called when inflate() returns 0 and needsDictionary() returns true + * indicating that a preset dictionary is required. The method getAdler() + * can be used to get the Adler-32 value of the dictionary needed. + *

+ * The bytes in given byte buffer will be fully consumed by this method. On + * return, its position will equal its limit. + * + * @param byteBuffer the dictionary data bytes + * @see Inflater#needsDictionary + * @see Inflater#getAdler + * @since 11 + */ + public void setDictionary(ByteBuffer byteBuffer) { + synchronized (zsRef) { + final int position = byteBuffer.position(); + final int remaining = Math.max(byteBuffer.limit() - position, 0); + ensureOpen(); + if (byteBuffer.isDirect()) { + final long address = ((DirectBuffer) byteBuffer).address(); + try { + setDictionaryBuffer(zsRef.address(), address + position, remaining); + } finally { + Reference.reachabilityFence(byteBuffer); + } + } else { + final byte[] array = ZipUtils.getBufferArray(byteBuffer); + final int offset = ZipUtils.getBufferOffset(byteBuffer); + setDictionary(zsRef.address(), array, offset + position, remaining); + } + byteBuffer.position(position + remaining); + needDict = false; + } + } + /** * Returns the total number of bytes remaining in the input buffer. * This can be used to find out what bytes still remain in the input @@ -208,19 +277,22 @@ public class Inflater { */ public int getRemaining() { synchronized (zsRef) { - return len; + final ByteBuffer input = this.input; + return input == null ? inputLim - inputPos : input.remaining(); } } /** * Returns true if no data remains in the input buffer. This can - * be used to determine if #setInput should be called in order - * to provide more input. + * be used to determine if one of the {@code setInput()} methods should be + * called in order to provide more input. + * * @return true if no data remains in the input buffer */ public boolean needsInput() { synchronized (zsRef) { - return len <= 0; + final ByteBuffer input = this.input; + return input == null ? inputLim == inputPos : ! input.hasRemaining(); } } @@ -254,30 +326,106 @@ public class Inflater { * determine if more input data or a preset dictionary is required. * In the latter case, getAdler() can be used to get the Adler-32 * value of the dictionary required. + *

+ * If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation, even in the event that a {@link DataFormatException} + * is thrown. + *

+ * The {@linkplain #getRemaining() remaining byte count} will be reduced by + * the number of consumed input bytes. If the {@link #setInput(ByteBuffer)} + * method was called to provide a buffer for input, the input buffer's position + * will be advanced the number of consumed bytes. + *

+ * These byte totals, as well as + * the {@linkplain #getBytesRead() total bytes read} + * and the {@linkplain #getBytesWritten() total bytes written} + * values, will be updated even in the event that a {@link DataFormatException} + * is thrown to reflect the amount of data consumed and produced before the + * exception occurred. + * * @param b the buffer for the uncompressed data * @param off the start offset of the data * @param len the maximum number of uncompressed bytes * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid + * @throws DataFormatException if the compressed data format is invalid * @see Inflater#needsInput * @see Inflater#needsDictionary */ public int inflate(byte[] b, int off, int len) throws DataFormatException { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { ensureOpen(); - int thisLen = this.len; - int n = inflateBytes(zsRef.address(), b, off, len); - bytesWritten += n; - bytesRead += (thisLen - this.len); - return n; + final ByteBuffer input = this.input; + final long result; + final int inputPos; + if (input == null) { + inputPos = this.inputPos; + try { + result = inflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + b, off, len); + } catch (DataFormatException e) { + int read = inputConsumed; + this.inputPos = inputPos + read; + bytesRead += read; + inputConsumed = 0; + int written = outputConsumed; + bytesWritten += written; + outputConsumed = 0; + throw e; + } + } else { + inputPos = input.position(); + try { + final int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + try { + final long inputAddress = ((DirectBuffer) input).address(); + result = inflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + b, off, len); + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + b, off, len); + } + } catch (DataFormatException e) { + int read = inputConsumed; + input.position(inputPos + read); + bytesRead += read; + inputConsumed = 0; + int written = outputConsumed; + bytesWritten += written; + outputConsumed = 0; + throw e; + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if ((result >>> 63 & 1) != 0) { + needDict = true; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + bytesWritten += written; + bytesRead += read; + return written; } } @@ -288,9 +436,22 @@ public class Inflater { * determine if more input data or a preset dictionary is required. * In the latter case, getAdler() can be used to get the Adler-32 * value of the dictionary required. + *

+ * The {@linkplain #getRemaining() remaining byte count} will be reduced by + * the number of consumed input bytes. If the {@link #setInput(ByteBuffer)} + * method was called to provide a buffer for input, the input buffer's position + * will be advanced the number of consumed bytes. + *

+ * These byte totals, as well as + * the {@linkplain #getBytesRead() total bytes read} + * and the {@linkplain #getBytesWritten() total bytes written} + * values, will be updated even in the event that a {@link DataFormatException} + * is thrown to reflect the amount of data consumed and produced before the + * exception occurred. + * * @param b the buffer for the uncompressed data * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid + * @throws DataFormatException if the compressed data format is invalid * @see Inflater#needsInput * @see Inflater#needsDictionary */ @@ -298,6 +459,160 @@ public class Inflater { return inflate(b, 0, b.length); } + /** + * Uncompresses bytes into specified buffer. Returns actual number + * of bytes uncompressed. A return value of 0 indicates that + * needsInput() or needsDictionary() should be called in order to + * determine if more input data or a preset dictionary is required. + * In the latter case, getAdler() can be used to get the Adler-32 + * value of the dictionary required. + *

+ * On success, the position of the given {@code output} byte buffer will be + * advanced by as many bytes as were produced by the operation, which is equal + * to the number returned by this method. Note that the position of the + * {@code output} buffer will be advanced even in the event that a + * {@link DataFormatException} is thrown. + *

+ * The {@linkplain #getRemaining() remaining byte count} will be reduced by + * the number of consumed input bytes. If the {@link #setInput(ByteBuffer)} + * method was called to provide a buffer for input, the input buffer's position + * will be advanced the number of consumed bytes. + *

+ * These byte totals, as well as + * the {@linkplain #getBytesRead() total bytes read} + * and the {@linkplain #getBytesWritten() total bytes written} + * values, will be updated even in the event that a {@link DataFormatException} + * is thrown to reflect the amount of data consumed and produced before the + * exception occurred. + * + * @param output the buffer for the uncompressed data + * @return the actual number of uncompressed bytes + * @throws DataFormatException if the compressed data format is invalid + * @throws ReadOnlyBufferException if the given output buffer is read-only + * @see Inflater#needsInput + * @see Inflater#needsDictionary + * @since 11 + */ + public int inflate(ByteBuffer output) throws DataFormatException { + if (output.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + synchronized (zsRef) { + ensureOpen(); + final ByteBuffer input = this.input; + final long result; + final int inputPos; + final int outputPos = output.position(); + final int outputRem = Math.max(output.limit() - outputPos, 0); + if (input == null) { + inputPos = this.inputPos; + try { + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBytesBuffer(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputArray, outputOffset + outputPos, outputRem); + } + } catch (DataFormatException e) { + int read = inputConsumed; + this.inputPos = inputPos + read; + bytesRead += read; + inputConsumed = 0; + int written = outputConsumed; + output.position(outputPos + written); + bytesWritten += written; + outputConsumed = 0; + throw e; + } + } else { + inputPos = input.position(); + final int inputRem = Math.max(input.limit() - inputPos, 0); + try { + if (input.isDirect()) { + final long inputAddress = ((DirectBuffer) input).address(); + try { + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBufferBuffer(zsRef.address(), + inputAddress + inputPos, inputRem, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem); + } + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBytesBuffer(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem); + } + } + } catch (DataFormatException e) { + int read = inputConsumed; + input.position(inputPos + read); + bytesRead += read; + inputConsumed = 0; + int written = outputConsumed; + output.position(outputPos + written); + bytesWritten += written; + outputConsumed = 0; + throw e; + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if ((result >>> 63 & 1) != 0) { + needDict = true; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + // Note: this method call also serves to keep the byteBuffer ref alive + output.position(outputPos + written); + bytesWritten += written; + bytesRead += read; + return written; + } + } + /** * Returns the ADLER-32 value of the uncompressed data. * @return the ADLER-32 value of the uncompressed data @@ -368,10 +683,10 @@ public class Inflater { synchronized (zsRef) { ensureOpen(); reset(zsRef.address()); - buf = defaultBuf; + input = ZipUtils.defaultBuf; + inputArray = null; finished = false; needDict = false; - off = len = 0; bytesRead = bytesWritten = 0; } } @@ -386,7 +701,8 @@ public class Inflater { public void end() { synchronized (zsRef) { zsRef.clean(); - buf = null; + input = ZipUtils.defaultBuf; + inputArray = null; } } @@ -416,18 +732,23 @@ public class Inflater { throw new NullPointerException("Inflater has been closed"); } - boolean ended() { - synchronized (zsRef) { - return zsRef.address() == 0; - } - } - private static native void initIDs(); private static native long init(boolean nowrap); private static native void setDictionary(long addr, byte[] b, int off, int len); - private native int inflateBytes(long addr, byte[] b, int off, int len) - throws DataFormatException; + private static native void setDictionaryBuffer(long addr, long bufAddress, int len); + private native long inflateBytesBytes(long addr, + byte[] inputArray, int inputOff, int inputLen, + byte[] outputArray, int outputOff, int outputLen) throws DataFormatException; + private native long inflateBytesBuffer(long addr, + byte[] inputArray, int inputOff, int inputLen, + long outputAddress, int outputLen) throws DataFormatException; + private native long inflateBufferBytes(long addr, + long inputAddress, int inputLen, + byte[] outputArray, int outputOff, int outputLen) throws DataFormatException; + private native long inflateBufferBuffer(long addr, + long inputAddress, int inputLen, + long outputAddress, int outputLen) throws DataFormatException; private static native int getAdler(long addr); private static native void reset(long addr); private static native void end(long addr); diff --git a/src/java.base/share/classes/java/util/zip/ZipUtils.java b/src/java.base/share/classes/java/util/zip/ZipUtils.java index 45c5d8dbb67..07e64e4fa92 100644 --- a/src/java.base/share/classes/java/util/zip/ZipUtils.java +++ b/src/java.base/share/classes/java/util/zip/ZipUtils.java @@ -25,6 +25,8 @@ package java.util.zip; +import java.nio.Buffer; +import java.nio.ByteBuffer; import java.nio.file.attribute.FileTime; import java.security.AccessController; import java.security.PrivilegedAction; @@ -37,6 +39,9 @@ import java.util.concurrent.TimeUnit; import static java.util.zip.ZipConstants.ENDHDR; +import jdk.internal.misc.Unsafe; +import sun.nio.ch.DirectBuffer; + class ZipUtils { // used to adjust values between Windows and java epoch @@ -45,6 +50,8 @@ class ZipUtils { // used to indicate the corresponding windows time is not available public static final long WINDOWS_TIME_NOT_AVAILABLE = Long.MIN_VALUE; + static final ByteBuffer defaultBuf = ByteBuffer.allocateDirect(0); + /** * Converts Windows time (in microseconds, UTC/GMT) time to FileTime. */ @@ -281,4 +288,17 @@ class ZipUtils { AccessController.doPrivileged(pa); } } + + private static final Unsafe unsafe = Unsafe.getUnsafe(); + + private static final long byteBufferArrayOffset = unsafe.objectFieldOffset(ByteBuffer.class, "hb"); + private static final long byteBufferOffsetOffset = unsafe.objectFieldOffset(ByteBuffer.class, "offset"); + + static byte[] getBufferArray(ByteBuffer byteBuffer) { + return (byte[]) unsafe.getObject(byteBuffer, byteBufferArrayOffset); + } + + static int getBufferOffset(ByteBuffer byteBuffer) { + return unsafe.getInt(byteBuffer, byteBufferOffsetOffset); + } } diff --git a/src/java.base/share/native/libzip/Deflater.c b/src/java.base/share/native/libzip/Deflater.c index b666a16145a..b56df5ecc1b 100644 --- a/src/java.base/share/native/libzip/Deflater.c +++ b/src/java.base/share/native/libzip/Deflater.c @@ -38,34 +38,6 @@ #define DEF_MEM_LEVEL 8 -static jfieldID levelID; -static jfieldID strategyID; -static jfieldID setParamsID; -static jfieldID finishID; -static jfieldID finishedID; -static jfieldID bufID, offID, lenID; - -JNIEXPORT void JNICALL -Java_java_util_zip_Deflater_initIDs(JNIEnv *env, jclass cls) -{ - levelID = (*env)->GetFieldID(env, cls, "level", "I"); - CHECK_NULL(levelID); - strategyID = (*env)->GetFieldID(env, cls, "strategy", "I"); - CHECK_NULL(strategyID); - setParamsID = (*env)->GetFieldID(env, cls, "setParams", "Z"); - CHECK_NULL(setParamsID); - finishID = (*env)->GetFieldID(env, cls, "finish", "Z"); - CHECK_NULL(finishID); - finishedID = (*env)->GetFieldID(env, cls, "finished", "Z"); - CHECK_NULL(finishedID); - bufID = (*env)->GetFieldID(env, cls, "buf", "[B"); - CHECK_NULL(bufID); - offID = (*env)->GetFieldID(env, cls, "off", "I"); - CHECK_NULL(offID); - lenID = (*env)->GetFieldID(env, cls, "len", "I"); - CHECK_NULL(lenID); -} - JNIEXPORT jlong JNICALL Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level, jint strategy, jboolean nowrap) @@ -104,17 +76,9 @@ Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level, } } -JNIEXPORT void JNICALL -Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, - jarray b, jint off, jint len) +static void doSetDictionary(JNIEnv *env, jlong addr, jbyte *buf, jint len) { - Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - int res; - if (buf == 0) {/* out of memory */ - return; - } - res = deflateSetDictionary((z_stream *)jlong_to_ptr(addr), buf + off, len); - (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); + int res = deflateSetDictionary(jlong_to_ptr(addr), (Bytef *) buf, len); switch (res) { case Z_OK: break; @@ -127,94 +91,169 @@ Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, } } -JNIEXPORT jint JNICALL -Java_java_util_zip_Deflater_deflateBytes(JNIEnv *env, jobject this, jlong addr, - jarray b, jint off, jint len, jint flush) +JNIEXPORT void JNICALL +Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, + jbyteArray b, jint off, jint len) +{ + jbyte *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); + if (buf == NULL) /* out of memory */ + return; + doSetDictionary(env, addr, buf + off, len); + (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); +} + +JNIEXPORT void JNICALL +Java_java_util_zip_Deflater_setDictionaryBuffer(JNIEnv *env, jclass cls, jlong addr, + jlong bufferAddr, jint len) +{ + jbyte *buf = jlong_to_ptr(bufferAddr); + doSetDictionary(env, addr, buf, len); +} + +static jlong doDeflate(JNIEnv *env, jobject this, jlong addr, + jbyte *input, jint inputLen, + jbyte *output, jint outputLen, + jint flush, jint params) { z_stream *strm = jlong_to_ptr(addr); + jint inputUsed = 0, outputUsed = 0; - jarray this_buf = (*env)->GetObjectField(env, this, bufID); - jint this_off = (*env)->GetIntField(env, this, offID); - jint this_len = (*env)->GetIntField(env, this, lenID); - jbyte *in_buf; - jbyte *out_buf; - int res; - if ((*env)->GetBooleanField(env, this, setParamsID)) { - int level = (*env)->GetIntField(env, this, levelID); - int strategy = (*env)->GetIntField(env, this, strategyID); - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - // Throw OOME only when length is not zero - if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } + strm->next_in = (Bytef *) input; + strm->next_out = (Bytef *) output; + strm->avail_in = inputLen; + strm->avail_out = outputLen; + + int finished = 0; + int setParams = params & 1; - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - res = deflateParams(strm, level, strategy); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + if (setParams) { + int strategy = (params >> 1) & 3; + int level = params >> 3; + int res = deflateParams(strm, level, strategy); switch (res) { case Z_OK: - (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE); + setParams = 0; + /* fall through */ case Z_BUF_ERROR: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return (jint) (len - strm->avail_out); + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; default: JNU_ThrowInternalError(env, strm->msg); return 0; } } else { - jboolean finish = (*env)->GetBooleanField(env, this, finishID); - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - if (this_len != 0) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0) - JNU_ThrowOutOfMemoryError(env, 0); - - return 0; - } - - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - res = deflate(strm, finish ? Z_FINISH : flush); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + int res = deflate(strm, flush); switch (res) { case Z_STREAM_END: - (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); + finished = 1; /* fall through */ case Z_OK: case Z_BUF_ERROR: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return len - strm->avail_out; + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; default: JNU_ThrowInternalError(env, strm->msg); return 0; } } + return ((jlong)inputUsed) | (((jlong)outputUsed) << 31) | (((jlong)finished) << 62) | (((jlong)setParams) << 63); +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBytesBytes(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen, + jint flush, jint params) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doDeflate(env, this, addr, + input + inputOff, inputLen, + output + outputOff, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0); + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBytesBuffer(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jlong outputBuffer, jint outputLen, + jint flush, jint params) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = jlong_to_ptr(outputBuffer); + + jlong retVal = doDeflate(env, this, addr, + input + inputOff, inputLen, + output, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBufferBytes(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen, + jint flush, jint params) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doDeflate(env, this, addr, + input, inputLen, + output + outputOff, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBufferBuffer(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jlong outputBuffer, jint outputLen, + jint flush, jint params) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = jlong_to_ptr(outputBuffer); + + return doDeflate(env, this, addr, + input, inputLen, + output, outputLen, + flush, params); } JNIEXPORT jint JNICALL diff --git a/src/java.base/share/native/libzip/Inflater.c b/src/java.base/share/native/libzip/Inflater.c index 2e21d084b39..465e2534e47 100644 --- a/src/java.base/share/native/libzip/Inflater.c +++ b/src/java.base/share/native/libzip/Inflater.c @@ -42,23 +42,16 @@ #define ThrowDataFormatException(env, msg) \ JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg) -static jfieldID needDictID; -static jfieldID finishedID; -static jfieldID bufID, offID, lenID; +static jfieldID inputConsumedID; +static jfieldID outputConsumedID; JNIEXPORT void JNICALL Java_java_util_zip_Inflater_initIDs(JNIEnv *env, jclass cls) { - needDictID = (*env)->GetFieldID(env, cls, "needDict", "Z"); - CHECK_NULL(needDictID); - finishedID = (*env)->GetFieldID(env, cls, "finished", "Z"); - CHECK_NULL(finishedID); - bufID = (*env)->GetFieldID(env, cls, "buf", "[B"); - CHECK_NULL(bufID); - offID = (*env)->GetFieldID(env, cls, "off", "I"); - CHECK_NULL(offID); - lenID = (*env)->GetFieldID(env, cls, "len", "I"); - CHECK_NULL(lenID); + inputConsumedID = (*env)->GetFieldID(env, cls, "inputConsumed", "I"); + outputConsumedID = (*env)->GetFieldID(env, cls, "outputConsumed", "I"); + CHECK_NULL(inputConsumedID); + CHECK_NULL(outputConsumedID); } JNIEXPORT jlong JNICALL @@ -94,16 +87,9 @@ Java_java_util_zip_Inflater_init(JNIEnv *env, jclass cls, jboolean nowrap) } } -JNIEXPORT void JNICALL -Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, - jarray b, jint off, jint len) +static void doSetDictionary(JNIEnv *env, jlong addr, jbyte *buf, jint len) { - Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - int res; - if (buf == 0) /* out of memory */ - return; - res = inflateSetDictionary(jlong_to_ptr(addr), buf + off, len); - (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); + int res = inflateSetDictionary(jlong_to_ptr(addr), (Bytef *) buf, len); switch (res) { case Z_OK: break; @@ -117,68 +103,159 @@ Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, } } -JNIEXPORT jint JNICALL -Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr, - jarray b, jint off, jint len) +JNIEXPORT void JNICALL +Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, + jbyteArray b, jint off, jint len) +{ + jbyte *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); + if (buf == NULL) /* out of memory */ + return; + doSetDictionary(env, addr, buf + off, len); + (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); +} + +JNIEXPORT void JNICALL +Java_java_util_zip_Inflater_setDictionaryBuffer(JNIEnv *env, jclass cls, jlong addr, + jlong bufferAddr, jint len) +{ + jbyte *buf = jlong_to_ptr(bufferAddr); + doSetDictionary(env, addr, buf, len); +} + +static jlong doInflate(JNIEnv *env, jobject this, jlong addr, + jbyte *input, jint inputLen, + jbyte *output, jint outputLen) { z_stream *strm = jlong_to_ptr(addr); - jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID); - jint this_off = (*env)->GetIntField(env, this, offID); - jint this_len = (*env)->GetIntField(env, this, lenID); + jint inputUsed = 0, outputUsed = 0; - jbyte *in_buf; - jbyte *out_buf; - int ret; + strm->next_in = (Bytef *) input; + strm->next_out = (Bytef *) output; + strm->avail_in = inputLen; + strm->avail_out = outputLen; - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - ret = inflate(strm, Z_PARTIAL_FLUSH); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + int ret = inflate(strm, Z_PARTIAL_FLUSH); + int finished = 0; + int needDict = 0; switch (ret) { case Z_STREAM_END: - (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); + finished = 1; /* fall through */ case Z_OK: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return (jint) (len - strm->avail_out); + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; case Z_NEED_DICT: - (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE); + needDict = 1; /* Might have consumed some input here! */ - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return 0; + inputUsed = inputLen - strm->avail_in; + /* zlib is unclear about whether output may be produced */ + outputUsed = outputLen - strm->avail_out; + break; case Z_BUF_ERROR: - return 0; + break; case Z_DATA_ERROR: + inputUsed = inputLen - strm->avail_in; + (*env)->SetIntField(env, this, inputConsumedID, inputUsed); + outputUsed = outputLen - strm->avail_out; + (*env)->SetIntField(env, this, outputConsumedID, outputUsed); ThrowDataFormatException(env, strm->msg); - return 0; + break; case Z_MEM_ERROR: JNU_ThrowOutOfMemoryError(env, 0); - return 0; + break; default: JNU_ThrowInternalError(env, strm->msg); - return 0; + break; + } + return ((jlong)inputUsed) | (((jlong)outputUsed) << 31) | (((jlong)finished) << 62) | (((jlong)needDict) << 63); +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBytesBytes(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doInflate(env, this, addr, + input + inputOff, inputLen, + output + outputOff, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0); + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBytesBuffer(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jlong outputBuffer, jint outputLen) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = jlong_to_ptr(outputBuffer); + + jlong retVal = doInflate(env, this, addr, + input + inputOff, inputLen, + output, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBufferBytes(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; } + + jlong retVal = doInflate(env, this, addr, + input, inputLen, + output + outputOff, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBufferBuffer(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jlong outputBuffer, jint outputLen) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = jlong_to_ptr(outputBuffer); + + return doInflate(env, this, addr, + input, inputLen, + output, outputLen); } JNIEXPORT jint JNICALL diff --git a/test/jdk/java/util/zip/FlaterTest.java b/test/jdk/java/util/zip/FlaterTest.java index 7245440d033..b5aff0319b3 100644 --- a/test/jdk/java/util/zip/FlaterTest.java +++ b/test/jdk/java/util/zip/FlaterTest.java @@ -29,7 +29,6 @@ * @key randomness */ -import java.io.*; import java.nio.*; import java.util.*; import java.util.zip.*; @@ -41,35 +40,37 @@ import java.util.zip.*; */ public class FlaterTest extends Thread { private static final int DATA_LEN = 1024 * 128; - private static byte[] data; + + private static ByteBuffer dataDirect; + private static ByteBuffer dataHeap; // If true, print extra info. private static final boolean debug = false; // Set of Flater threads running. - private static Set flaters = - Collections.synchronizedSet(new HashSet()); + private static Set flaters = + Collections.synchronizedSet(new HashSet<>()); /** Fill in {@code data} with random values. */ static void createData() { - ByteBuffer bb = ByteBuffer.allocate(8); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - for (int i = 0; i < DATA_LEN; i++) { - bb.putDouble(0, Math.random()); - baos.write(bb.array(), 0, 8); + ByteBuffer bb = ByteBuffer.allocateDirect(DATA_LEN * 8); + for (int i = 0; i < DATA_LEN * 8; i += 8) { + bb.putDouble(i, Math.random()); } - data = baos.toByteArray(); - if (debug) System.out.println("data length is " + data.length); + dataDirect = bb; + final ByteBuffer hb = ByteBuffer.allocate(bb.capacity()); + hb.duplicate().put(bb.duplicate()); + dataHeap = hb; + if (debug) System.out.println("data length is " + bb.capacity()); } /** @return the length of the deflated {@code data}. */ - private static int getDeflatedLength() throws Throwable { - int rc = 0; + private static int getDeflatedLength() { Deflater deflater = new Deflater(); - deflater.setInput(data); + deflater.setInput(dataDirect.duplicate()); deflater.finish(); - byte[] out = new byte[data.length]; - rc = deflater.deflate(out); + byte[] out = new byte[dataDirect.capacity()]; + int rc = deflater.deflate(out); deflater.end(); if (debug) System.out.println("deflatedLength is " + rc); return rc; @@ -78,70 +79,98 @@ public class FlaterTest extends Thread { /** Compares given bytes with those in {@code data}. * @throws Exception if given bytes don't match {@code data}. */ - private static void validate(byte[] buf, int offset, int len) throws Exception { + private static void validate(ByteBuffer buf, int offset, int len) throws Exception { for (int i = 0; i < len; i++ ) { - if (buf[i] != data[offset+i]) { + if (buf.get(i) != dataDirect.get(offset+i)) { throw new Exception("mismatch at " + (offset + i)); } } } - public static void realMain(String[] args) throws Throwable { - createData(); + public static void realMain(String[] args) { int numThreads = args.length > 0 ? Integer.parseInt(args[0]) : 5; - new FlaterTest().go(numThreads); + createData(); + for (int srcMode = 0; srcMode <= 2; srcMode ++) { + for (int dstMode = 0; dstMode <= 2; dstMode ++) { + new FlaterTest().go(numThreads, srcMode, dstMode); + } + } } - private synchronized void go(int numThreads) throws Throwable { + private synchronized void go(int numThreads, int srcMode, int dstMode) { int deflatedLength = getDeflatedLength(); long time = System.currentTimeMillis(); for (int i = 0; i < numThreads; i++) { - Flater f = new Flater(deflatedLength); + Flater f = new Flater(deflatedLength, srcMode, dstMode); flaters.add(f); f.start(); } - while (flaters.size() != 0) { - try { - Thread.currentThread().sleep(10); - } catch (InterruptedException ex) { - unexpected(ex); + synchronized (flaters) { + while (flaters.size() != 0) { + try { + flaters.wait(); + } catch (InterruptedException ex) { + unexpected(ex); + } } } time = System.currentTimeMillis() - time; System.out.println("Time needed for " + numThreads - + " threads to deflate/inflate: " + time + " ms."); + + " threads to deflate/inflate: " + time + " ms (srcMode="+srcMode+",dstMode="+dstMode+")"); } /** Deflates and inflates data. */ static class Flater extends Thread { private final int deflatedLength; + private final int srcMode, dstMode; - private Flater(int length) { + private Flater(int length, int srcMode, int dstMode) { this.deflatedLength = length; + this.srcMode = srcMode; + this.dstMode = dstMode; } /** Deflates and inflates {@code data}. */ public void run() { if (debug) System.out.println(getName() + " starting run()"); try { - byte[] deflated = DeflateData(deflatedLength); + ByteBuffer deflated = DeflateData(deflatedLength); InflateData(deflated); } catch (Throwable t) { t.printStackTrace(); fail(getName() + " failed"); } finally { - flaters.remove(this); + synchronized (flaters) { + flaters.remove(this); + if (flaters.isEmpty()) { + flaters.notifyAll(); + } + } } } /** Returns a copy of {@code data} in deflated form. */ - private byte[] DeflateData(int length) throws Throwable { + private ByteBuffer DeflateData(int length) { Deflater deflater = new Deflater(); - deflater.setInput(data); + if (srcMode == 0) { + deflater.setInput(dataHeap.array()); + } else if (srcMode == 1) { + deflater.setInput(dataHeap.duplicate()); + } else { + assert srcMode == 2; + deflater.setInput(dataDirect.duplicate()); + } deflater.finish(); - byte[] out = new byte[length]; - deflater.deflate(out); + ByteBuffer out = dstMode == 2 ? ByteBuffer.allocateDirect(length) : ByteBuffer.allocate(length); + int deflated; + if (dstMode == 0) { + deflated = deflater.deflate(out.array(), 0, length); + out.position(deflated); + } else { + deflater.deflate(out); + } + out.flip(); return out; } @@ -149,14 +178,30 @@ public class FlaterTest extends Thread { * inflation. * @throws Exception if inflated bytes don't match {@code data}. */ - private void InflateData(byte[] bytes) throws Throwable { + private void InflateData(ByteBuffer bytes) throws Throwable { Inflater inflater = new Inflater(); - inflater.setInput(bytes, 0, bytes.length); + if (dstMode == 0) { + inflater.setInput(bytes.array(), 0, bytes.remaining()); + } else { + inflater.setInput(bytes); + } + if (inflater.getRemaining() == 0) { + throw new Exception("Nothing to inflate (bytes=" + bytes + ")"); + } int len = 1024 * 8; int offset = 0; + ByteBuffer buf = srcMode == 2 ? ByteBuffer.allocateDirect(len) : ByteBuffer.allocate(len); while (inflater.getRemaining() > 0) { - byte[] buf = new byte[len]; - int inflated = inflater.inflate(buf, 0, len); + buf.clear(); + int inflated; + if (srcMode == 0) { + inflated = inflater.inflate(buf.array(), 0, buf.remaining()); + } else { + inflated = inflater.inflate(buf); + } + if (inflated == 0) { + throw new Exception("Nothing inflated (dst=" + buf + ",offset=" + offset + ",rem=" + inflater.getRemaining() + ",srcMode="+srcMode+",dstMode="+dstMode+")"); + } validate(buf, offset, inflated); offset += inflated; } From jonathan.gibbons at oracle.com Fri Mar 16 14:54:23 2018 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Fri, 16 Mar 2018 07:54:23 -0700 Subject: RFR 8199616: Fix @module declarations in tier1 tests In-Reply-To: References: Message-ID: Martin, I have been following this work that Shura is doing. The checks are fairly expensive, and we would not want to perform them during routine test execution. However, one option would be to include a separate binary in the jtreg family, that can be run separately. There are no plans at this stage to make any significant changes to the jtreg test execution model, such as executing each test in its own module. -- Jon On 3/15/18 7:14 PM, Martin Buchholz wrote: > Interesting. > > Is the end goal to have jtreg itself validate the @modules tag or to > execute each test as its own module? It seems like the sort of checking > your tool is doing belongs in jtreg itself. > > > On Thu, Mar 15, 2018 at 5:12 PM Alexandre (Shura) Iline < > alexandre.iline at oracle.com> wrote: > >> Martin, >> >> >> On Mar 15, 2018, at 4:30 PM, Martin Buchholz wrote: >> >> How did you find the missing module dependencies? >> >> >> I have a tool which runs tests one by one like this (I am simplifying): >> - run test with -javaoptions:??limit-modules ?? with only the modules >> listed through @modules >> - if fails, run test with no ?limit-modules >> - if passes, that is a potential problem. >> We are thinking about making the tool open-source in code-tools project in >> one form or another. >> >> Tool aside, everybody is free to use ?limit-modules on a newly created >> test. >> >> Why was it only noticed now? >> >> >> It was not - I have just gotten around fixing it. There are more known >> @module deficiencies right now. >> >> Can we automatically prevent backsliding? >> >> >> That would be a job for a continuous integration system, I imagine. >> >> Shura >> >> >> >> >> On Thu, Mar 15, 2018 at 3:40 PM Alexandre (Shura) Iline < >> alexandre.iline at oracle.com> wrote: >> >>> Hi, >>> >>> Please take a quick look on fix adding missing module dependencies to >>> tests in :tier1 jdk tests. >>> >>> Webrev: http://cr.openjdk.java.net/~shurailine/8199616/webrev.00 >>> >>> Shura. >>> >>> From roger.riggs at oracle.com Fri Mar 16 14:59:36 2018 From: roger.riggs at oracle.com (Roger Riggs) Date: Fri, 16 Mar 2018 10:59:36 -0400 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> Message-ID: <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> Hi Brian, ByteArrayOutputStream: 166:? Add spaces after "," in the code. Write: ?Thanks for converting to TestNG. ?There are probably some more testng'ish ways of coding the test but its fine as is. All set as far as I'm concerned. Thanks, Roger On 3/15/18 5:52 PM, Brian Burkhalter wrote: > On Mar 15, 2018, at 8:56 AM, Brian Burkhalter > > wrote: > >> On Mar 15, 2018, at 7:33 AM, Roger Riggs > > wrote: >> >>> BAOS.java: >>> >>> line 163: ok but I don't think I would keep using the expanded 'byte >>> array output stream" phrase >>> instead of the proper noun: ByteArrayOutputStream. (except for >>> consistency) >> >> I don?t like it either: I was just maintaining consistency (as you >> observed the other usages). > > Changed ?byte array output stream? globally to {@code > ByteArratOutputStream}." > >>> In the Write.java test: >>> >>> line 60:? Probably "-" in the message should be "--" for consistency >>> >>> line 68:? Add the "e" Throwable to the thrown RuntimeException so it >>> gets printed in a stack trace/message >>> >>> Line 100:..? If this was a testng test, the Assert.assertEquals >>> messages would conveniently >>> print expected and actual values.? I'd suggest converting it to use >>> @run testng. >>> >>> (Though I expect after these are debugged, they will never fail). >>> >>> 73: some formatting cleanup of the old code might be useful. (spaces >>> around "=") >> >> Will update. > > Converted to TestNG and fixed all the above. Also replaced > initialization of the local Random variable to use RandomFactory. > > Updated patch: http://cr.openjdk.java.net/~bpb/8180410/webrev.01/ > . > > Thanks, > > Brian From brian.burkhalter at oracle.com Fri Mar 16 15:04:50 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Fri, 16 Mar 2018 08:04:50 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> Message-ID: <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> Hi ROger, On Mar 16, 2018, at 7:59 AM, Roger Riggs wrote: > ByteArrayOutputStream: 166: Add spaces after "," in the code. Done: webrev.01 updated in place. > Write: > Thanks for converting to TestNG. > There are probably some more testng'ish ways of coding the test but its fine as is. > > All set as far as I'm concerned. Thanks, Brian From roger.riggs at oracle.com Fri Mar 16 15:21:43 2018 From: roger.riggs at oracle.com (Roger Riggs) Date: Fri, 16 Mar 2018 11:21:43 -0400 Subject: RFR 8196298 Add null Reader and Writer with latest changes In-Reply-To: <2EA55A50-797E-4BE1-9A1C-E41B5FB3C199@reini.net> References: <6AF3DEA9-5572-47B1-804E-AD7B0E46D833@reini.net> <3ebd00ec-aa2d-65b9-9f68-0d693628ef2b@oracle.com> <5a9ef0dc.77b0df0a.bb39.cc95@mx.google.com> <5D587382-6466-4854-8C70-68CBC8C7332E@oracle.com> <21DAB782-B121-4117-BBC4-CEA983DC523D@reini.net> <2EA55A50-797E-4BE1-9A1C-E41B5FB3C199@reini.net> Message-ID: <2bee222e-649b-14f6-baa7-11af737c16f8@oracle.com> Hi Patrick, Looks good, If there are no more comments, I can sponsor the commit. Thanks, Roger On 3/16/18 2:10 AM, Patrick Reinhart wrote: > Just coming back on my webrev [1]. Are there any more feedbacks implementation wise to that latest version? If no I would need a commit sponsor for this change as the CSR [2] is reviewed and closed. > > -Patrick > > [1] http://cr.openjdk.java.net/~reinhapa/reviews/8196298/webrev.02 > [2] https://bugs.openjdk.java.net/browse/JDK-8196350 > > >> Am 07.03.2018 um 11:41 schrieb Patrick Reinhart : >> >> I applied those changes here: >> >> http://cr.openjdk.java.net/~reinhapa/reviews/8196298/webrev.02 >> >> -Patrick >> >> >>> Am 06.03.2018 um 23:12 schrieb Brian Burkhalter : >>> >>> Yes, I think so and and also the parameter ?csq' is allowed to be null so Objects.requireNonNull(csq) should be removed at lines 100 and 107 as no NPE is specified for these methods [1, 2]. >>> >>> Thanks, >>> >>> Brian >>> >>> [1] https://download.java.net/java/jdk10/docs/api/java/io/Writer.html#append(java.lang.CharSequence) >>> [2] https://download.java.net/java/jdk10/docs/api/java/io/Writer.html#append(java.lang.CharSequence,int,int) >>> >>> On Mar 6, 2018, at 11:49 AM, Bernd Eckenfels wrote: >>> >>>> Just a nit, Should append(CharSequence,int,int) also use checkFromIndexSize? From scolebourne at joda.org Fri Mar 16 15:58:49 2018 From: scolebourne at joda.org (Stephen Colebourne) Date: Fri, 16 Mar 2018 15:58:49 +0000 Subject: Raw String Literal Library Support In-Reply-To: References: Message-ID: On 14 March 2018 at 23:05, Michael Hixson wrote: > For example, does ``.lines() produce an empty stream? I believe `` is a compile error. (A mistake IMO, but necessary if you have unlimited delimiters) Stephen From paul.sandoz at oracle.com Fri Mar 16 16:21:32 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 16 Mar 2018 09:21:32 -0700 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> <5A9D8F33.5060500@oracle.com> <5A9DAC84.906@oracle.com> <5A9DAE87.8020801@oracle.com> <1521102348.2448.25.camel@oracle.com> Message-ID: <23639144-5217-4A0F-930C-EF24B4976544@oracle.com> Hi Ian, Thomas, Some background on the bulk copying for byte buffers after talking with Mikael who worked on these changes a few years ago. Please correct the following if needed as our memory is hazy :-) IIRC at the time we felt this was a reasonable thing to do because C2 did not strip mine the loops for the bulk copying of large Java arrays i.e. the issue was there anyway for more common cases. However, i believe that may no longer be the so in some cases after Roland implemented loop strip mining in C2 [1]. So we should go back and revisit/check the current support in buffers and Java arrays (System.arraycopy etc). (This is also something we need to consider if we modify buffers to support capacities larger than Integer.MAX_VALUE. Also connects with Project Panama.) If Thomas has not done so or does not plan to i can log an issue for you. Paul. [1] https://bugs.openjdk.java.net/browse/JDK-8186027 > On Mar 15, 2018, at 10:49 AM, Ian Rogers wrote: > > +hotspot-gc-dev > > On Thu, Mar 15, 2018 at 1:25 AM Thomas Schatzl > wrote: > >> Hi, >> >> On Thu, 2018-03-15 at 01:00 +0000, Ian Rogers wrote: >>> An old data point on how large a critical region should be comes from >>> java.nio.Bits. In JDK 9 the code migrated into unsafe, but in JDK 8 >>> the copies within a critical region were bound at most copying 1MB: >>> http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/ >>> native/java/nio/Bits.c#l88 This is inconsistent with Deflater and >>> ObjectOutputStream which both allow unlimited arrays and thereby >>> critical region sizes. >>> >>> In JDK 9 the copies starve the garbage collector in nio Bits too as >>> there is no 1MB limit to the copy sizes: >>> http://hg.openjdk.java.net/jdk/jdk/rev/f70e100d3195 >>> which came from: >>> https://bugs.openjdk.java.net/browse/JDK-8149596 >>> >>> Perhaps this is a regression not demonstrated due to the testing >>> challenge. >>> [...] >>> It doesn't seem unreasonable to have the loops for the copies occur >>> in 1MB chunks but JDK-8149596 lost this and so I'm confused on what >>> the HotSpot stand point is. >> >> Please file a bug (seems to be a core-libs/java.nio regression?), >> preferably with some kind of regression test. Also file enhancements (I >> would guess) for the other cases allowing unlimited arrays. >> > > I don't have perms to file bugs there's some catch-22 scenario in getting > the permissions. Happy to have a bug filed or to file were that not an > issue. Happy to create a test case but can't see any others for TTSP > issues. This feels like a potential use case for jmh, perhaps run the > benchmark well having a separate thread run GC bench. > > Should there be a bug to add, in debug mode, a TTSP watcher thread whose > job it is to bring "random" threads into safepoints and report on tardy > ones? > Should there be a bug to warn on being in a JNI critical for more than just > a short period? > Seems like there should be a bug on Unsafe.copyMemory and > Unsafe.copySwapMemory having TTSP issues. > Seems like there should be a bug on all uses of critical that don't chunk > their critical region work based on some bound (like 1MB chunks for nio > Bits)? How are these bounds set? A past reference that I've lost is in > having the bound be the equivalent of 65535 bytecodes due to the > expectation of GC work at least once in a method or on a loop backedge - I > thought this was in a spec somewhere but now I can't find it. The bytecode > size feels as arbitrary as 1MB, a time period would be better but that can > depend on the kind of GC you want as delays with concurrent GC mean more > than non-concurrent. Clearly the chunk size shouldn't just be 0, but this > appears to currently be the norm in the JDK. > > The original reason for coming here was a 140x slow down in -Xcheck:jni in > Deflater.deflate There are a few options there that its useful to enumerate: > 1) rewrite in Java but there are correctness and open source related issues > 2) remove underflow/overflow protection from critical arrays (revert > JDK-6311046 > or perhaps bound protection to arrays of a particular small size) - this > removes checking and doesn't deal with TTSP > 3) add a critical array slice API to JNI so that copies with -Xcheck:jni > aren't unbounded (martinrb@ proposed this) - keeps checking but doesn't > deal with TTSP > 4) rewrite primitive array criticals with GetArrayRegion as O(n) beats the > "silent killer" TTSP (effectively deprecate the critical APIs) > > In general (ie not just the deflate case) I think (1) is the most > preferable. (2) and (3) both have TTSP issues. (4) isn't great performance > wise, which motivates more use of approach (1), but I think deprecating > criticals may just be the easiest and sanest way forward. I think that > discussion is worth having on an e-mail thread rather than a bug. > > >> Long TTSP is a performance bug as any other. >> >>> In a way criticals are better than unsafe as they may >>> pin the memory and not starve GC, which shenandoah does. >> >> (Region based) Object pinning has its own share of problems: >> >> - only (relatively) easily implemented in region based collectors >> >> - may slow down pause a bit in presence of pinned regions/objects (for >> non-concurrent copying collectors) >> >> - excessive use of pinning may cause OOME and VM exit probably earlier >> than the gc locker. GC locker seems to provide a more gradual >> degradation. E.g. pinning regions typically makes these regions >> unavailable for allocation. >> I.e. you still should not use it for many, very long living objects. >> Of course this somewhat depends on the sophistication of the >> implementation. >> >> I think region based pinning would be a good addition to other >> collectors than Shenandoah too. It has been on our minds for a long >> time, but there are so many other more important issues :), so of >> course we are eager to see contributions in this area. ;) >> >> If you are interested on working on this, please ping us on hotspot-gc- >> dev for implementation ideas to get you jump-started. >> >> Thanks, >> Thomas >> > > I'd rather deprecate criticals than build upon the complexity, but I'm very > glad this is a concern. > > Thanks, > Ian From irogers at google.com Fri Mar 16 17:19:58 2018 From: irogers at google.com (Ian Rogers) Date: Fri, 16 Mar 2018 17:19:58 +0000 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: <23639144-5217-4A0F-930C-EF24B4976544@oracle.com> References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> <5A9D8F33.5060500@oracle.com> <5A9DAC84.906@oracle.com> <5A9DAE87.8020801@oracle.com> <1521102348.2448.25.camel@oracle.com> <23639144-5217-4A0F-930C-EF24B4976544@oracle.com> Message-ID: Thanks Paul, very interesting. On Fri, Mar 16, 2018 at 9:21 AM Paul Sandoz wrote: > Hi Ian, Thomas, > > Some background on the bulk copying for byte buffers after talking with > Mikael who worked on these changes a few years ago. > > Please correct the following if needed as our memory is hazy :-) > > IIRC at the time we felt this was a reasonable thing to do because C2 did > not strip mine the loops for the bulk copying of large Java arrays i.e. the > issue was there anyway for more common cases. However, i believe that may > no longer be the so in some cases after Roland implemented loop strip > mining in C2 [1]. So we should go back and revisit/check the current > support in buffers and Java arrays (System.arraycopy etc). > The C2 issue is a well known TTSP issue :-) Its great that there is a strip mining optimization, revisiting the bulk copies would be great! > (This is also something we need to consider if we modify buffers to > support capacities larger than Integer.MAX_VALUE. Also connects with > Project Panama.) > > If Thomas has not done so or does not plan to i can log an issue for you. > That'd be great. I wonder if identifying more TTSP issues should also be a bug. Its interesting to observe that overlooking TTSP in C2 motivated the Unsafe.copyMemory change permitting a fresh TTSP issue. If TTSP is a 1st class issue then maybe we can deprecate JNI critical regions to support that effort :-) Thanks, Ian > Paul. > > > [1] https://bugs.openjdk.java.net/browse/JDK-8186027 > > On Mar 15, 2018, at 10:49 AM, Ian Rogers wrote: > > +hotspot-gc-dev > > On Thu, Mar 15, 2018 at 1:25 AM Thomas Schatzl > wrote: > > Hi, > > On Thu, 2018-03-15 at 01:00 +0000, Ian Rogers wrote: > > An old data point on how large a critical region should be comes from > java.nio.Bits. In JDK 9 the code migrated into unsafe, but in JDK 8 > the copies within a critical region were bound at most copying 1MB: > http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/ > native/java/nio/Bits.c#l88 This is inconsistent with Deflater and > ObjectOutputStream which both allow unlimited arrays and thereby > critical region sizes. > > In JDK 9 the copies starve the garbage collector in nio Bits too as > there is no 1MB limit to the copy sizes: > http://hg.openjdk.java.net/jdk/jdk/rev/f70e100d3195 > which came from: > https://bugs.openjdk.java.net/browse/JDK-8149596 > > Perhaps this is a regression not demonstrated due to the testing > challenge. > [...] > It doesn't seem unreasonable to have the loops for the copies occur > in 1MB chunks but JDK-8149596 lost this and so I'm confused on what > the HotSpot stand point is. > > > Please file a bug (seems to be a core-libs/java.nio regression?), > preferably with some kind of regression test. Also file enhancements (I > would guess) for the other cases allowing unlimited arrays. > > > I don't have perms to file bugs there's some catch-22 scenario in getting > the permissions. Happy to have a bug filed or to file were that not an > issue. Happy to create a test case but can't see any others for TTSP > issues. This feels like a potential use case for jmh, perhaps run the > benchmark well having a separate thread run GC bench. > > Should there be a bug to add, in debug mode, a TTSP watcher thread whose > job it is to bring "random" threads into safepoints and report on tardy > ones? > Should there be a bug to warn on being in a JNI critical for more than just > a short period? > Seems like there should be a bug on Unsafe.copyMemory and > Unsafe.copySwapMemory having TTSP issues. > Seems like there should be a bug on all uses of critical that don't chunk > their critical region work based on some bound (like 1MB chunks for nio > Bits)? How are these bounds set? A past reference that I've lost is in > having the bound be the equivalent of 65535 bytecodes due to the > expectation of GC work at least once in a method or on a loop backedge - I > thought this was in a spec somewhere but now I can't find it. The bytecode > size feels as arbitrary as 1MB, a time period would be better but that can > depend on the kind of GC you want as delays with concurrent GC mean more > than non-concurrent. Clearly the chunk size shouldn't just be 0, but this > appears to currently be the norm in the JDK. > > The original reason for coming here was a 140x slow down in -Xcheck:jni in > Deflater.deflate There are a few options there that its useful to > enumerate: > 1) rewrite in Java but there are correctness and open source related issues > 2) remove underflow/overflow protection from critical arrays (revert > JDK-6311046 > or perhaps bound protection to arrays of a particular small size) - this > removes checking and doesn't deal with TTSP > 3) add a critical array slice API to JNI so that copies with -Xcheck:jni > aren't unbounded (martinrb@ proposed this) - keeps checking but doesn't > deal with TTSP > 4) rewrite primitive array criticals with GetArrayRegion as O(n) beats the > "silent killer" TTSP (effectively deprecate the critical APIs) > > In general (ie not just the deflate case) I think (1) is the most > preferable. (2) and (3) both have TTSP issues. (4) isn't great performance > wise, which motivates more use of approach (1), but I think deprecating > criticals may just be the easiest and sanest way forward. I think that > discussion is worth having on an e-mail thread rather than a bug. > > > Long TTSP is a performance bug as any other. > > In a way criticals are better than unsafe as they may > pin the memory and not starve GC, which shenandoah does. > > > (Region based) Object pinning has its own share of problems: > > - only (relatively) easily implemented in region based collectors > > - may slow down pause a bit in presence of pinned regions/objects (for > non-concurrent copying collectors) > > - excessive use of pinning may cause OOME and VM exit probably earlier > than the gc locker. GC locker seems to provide a more gradual > degradation. E.g. pinning regions typically makes these regions > unavailable for allocation. > I.e. you still should not use it for many, very long living objects. > Of course this somewhat depends on the sophistication of the > implementation. > > I think region based pinning would be a good addition to other > collectors than Shenandoah too. It has been on our minds for a long > time, but there are so many other more important issues :), so of > course we are eager to see contributions in this area. ;) > > If you are interested on working on this, please ping us on hotspot-gc- > dev for implementation ideas to get you jump-started. > > Thanks, > Thomas > > > I'd rather deprecate criticals than build upon the complexity, but I'm very > glad this is a concern. > > Thanks, > Ian > > > From michael.hixson at gmail.com Fri Mar 16 18:00:31 2018 From: michael.hixson at gmail.com (Michael Hixson) Date: Fri, 16 Mar 2018 11:00:31 -0700 Subject: Raw String Literal Library Support In-Reply-To: References: Message-ID: On Fri, Mar 16, 2018 at 8:58 AM, Stephen Colebourne wrote: > On 14 March 2018 at 23:05, Michael Hixson wrote: >> For example, does ``.lines() produce an empty stream? > > I believe `` is a compile error. > (A mistake IMO, but necessary if you have unlimited delimiters) Ah, oops. I meant to ask about calling lines() on the empty string. "".lines() Looking at the implementation from a week ago [1], I think it disagrees with BufferedReader about what lines are - specifically when it comes to the empty string and any string ending with a line separator. That seems not good. But that behavior isn't specified in Jim's description or examples so I'm wondering if that's intentional. (Or I could be reading the code wrong). [1] http://hg.openjdk.java.net/amber/amber/file/5a2e574f43fb/src/java.base/share/classes/java/lang/StringLatin1.java#l560 -Michael > > Stephen From Roger.Riggs at Oracle.com Fri Mar 16 20:32:52 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 16 Mar 2018 16:32:52 -0400 Subject: RFR 8199756 : Simplify language, country, script, and variant property initialization Message-ID: Please review a small simplification of the initialization of System properties for language, country, script, and variant.? Some steps for initializing them are unnecessary. The tests pass; a careful review would be appreciated so as to avoid breakage. Webrev: ? http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ Issue: ? https://bugs.openjdk.java.net/browse/JDK-8199756 Thanks, Roger From Alan.Bateman at oracle.com Sat Mar 17 09:46:50 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Sat, 17 Mar 2018 09:46:50 +0000 Subject: RFR 8199756 : Simplify language, country, script, and variant property initialization In-Reply-To: References: Message-ID: <3fd6536d-f5d7-ff7d-106d-14eda3e72c71@oracle.com> On 16/03/2018 20:32, Roger Riggs wrote: > Please review a small simplification of the initialization of System > properties for > language, country, script, and variant.? Some steps for initializing > them are unnecessary. > The tests pass; a careful review would be appreciated so as to avoid > breakage. > > Webrev: > ? http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ > > Issue: > ? https://bugs.openjdk.java.net/browse/JDK-8199756 There are subtle interactions with how system properties are set in the VM and on the command line which will take a bit effort to research in order to review this and be satisfied that the change is safe. Have you dug into the ancient history and bugs to see why it was done this way? -Alan From sergei.tsypanov at yandex.ru Sun Mar 18 09:56:47 2018 From: sergei.tsypanov at yandex.ru (=?utf-8?B?0KHQtdGA0LPQtdC5INCm0YvQv9Cw0L3QvtCy?=) Date: Sun, 18 Mar 2018 11:56:47 +0200 Subject: [PATCH] unnecessary null check inside of java.lang.Boolean.valueOf(String) Message-ID: <6635141521367007@web3g.yandex.ru> Hi, currently (JDK 9.0.4) j.l.Boolean.valueOf(String) contains this code: public static boolean parseBoolean(String s) { ? return ((s != null) && s.equalsIgnoreCase("true")); } Null check here seems to be redundant, as String.equalsIgnoreCase does it itself: public boolean equalsIgnoreCase(String anotherString) { ? return this == anotherString ? true ? : anotherString != null ? ? && anotherString.length() == length() ? ? && regionMatches(true, 0, anotherString, 0, length()); } So we can rid this check making public static boolean parseBoolean(String s) { ? return "true".equalsIgnoreCase(s)); } which is more simple and faster. Consider benchmark: @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) public class EqualsIgnoreCaseBenchmark { @Benchmark public boolean defaultMethod(Data data) { return data.str != null && data.str.equalsIgnoreCase("true"); } @Benchmark public boolean betterMethod(Data data) { return "true".equalsIgnoreCase(data.str); } @State(Scope.Thread) public static class Data { @Param({"true", "false", "null"}) String str; @Setup public void setup() { str = "null".equals(str) ? null : str; } } } This benchmark on my machine (openjdk version "1.8.0_162", Intel(R) Core(TM) i5-4690) gives the following results: Benchmark (str) Mode Cnt Score Error Units EqualsIgnoreCaseBenchmark.betterMethod true avgt 50 5.095 ? 0.405 ns/op EqualsIgnoreCaseBenchmark.defaultMethod true avgt 50 9.113 ? 0.212 ns/op EqualsIgnoreCaseBenchmark.betterMethod false avgt 50 2.973 ? 0.076 ns/op EqualsIgnoreCaseBenchmark.defaultMethod false avgt 50 2.842 ? 0.017 ns/op EqualsIgnoreCaseBenchmark.betterMethod null avgt 50 2.395 ? 0.020 ns/op EqualsIgnoreCaseBenchmark.defaultMethod null avgt 50 2.232 ? 0.020 ns/op Also we don't need to do exlicit null check for argument of Boolean.parseBoolean(String) e.g. in jdk.internal.module.ModuleBootstrap, line 302. Here's the patch: diff --git a/src/java.base/share/classes/java/lang/Boolean.java b/src/java.base/share/classes/java/lang/Boolean.java --- a/src/java.base/share/classes/java/lang/Boolean.java +++ b/src/java.base/share/classes/java/lang/Boolean.java @@ -129,7 +129,7 @@ * @since 1.5 */ public static boolean parseBoolean(String s) { - return ((s != null) && s.equalsIgnoreCase("true")); + return "true".equalsIgnoreCase(s); } /** @@ -238,7 +238,7 @@ */ public boolean equals(Object obj) { if (obj instanceof Boolean) { - return value == ((Boolean)obj).booleanValue(); + return value == (Boolean) obj; } return false; } diff --git a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java --- a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java +++ b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java @@ -299,7 +299,7 @@ PrintStream traceOutput = null; propValue = getAndRemoveProperty("jdk.module.showModuleResolution"); - if (propValue != null && Boolean.parseBoolean(propValue)) + if (Boolean.parseBoolean(propValue)) traceOutput = System.out; // run the resolver to create the configuration Regards, Sergey Tsypanov From patrick at reini.net Sun Mar 18 10:41:40 2018 From: patrick at reini.net (Patrick Reinhart) Date: Sun, 18 Mar 2018 11:41:40 +0100 Subject: RFR 8196298 Add null Reader and Writer with latest changes In-Reply-To: <2bee222e-649b-14f6-baa7-11af737c16f8@oracle.com> References: <6AF3DEA9-5572-47B1-804E-AD7B0E46D833@reini.net> <3ebd00ec-aa2d-65b9-9f68-0d693628ef2b@oracle.com> <5a9ef0dc.77b0df0a.bb39.cc95@mx.google.com> <5D587382-6466-4854-8C70-68CBC8C7332E@oracle.com> <21DAB782-B121-4117-BBC4-CEA983DC523D@reini.net> <2EA55A50-797E-4BE1-9A1C-E41B5FB3C199@reini.net> <2bee222e-649b-14f6-baa7-11af737c16f8@oracle.com> Message-ID: <2037e930-eb0c-39a5-bcb6-c39a46447f9a@reini.net> Hi Roger, Seems there are no more comments...?? - all shocked :-) -Patrick Am 16.03.2018 um 16:21 schrieb Roger Riggs: > Hi Patrick, > > Looks good, > > If there are no more comments, I can sponsor the commit. > > Thanks, Roger > > > On 3/16/18 2:10 AM, Patrick Reinhart wrote: >> Just coming back on my webrev [1]. Are there any more feedbacks >> implementation wise to that latest version? If no I would need a >> commit sponsor for this change as the CSR [2] is reviewed and closed. >> >> -Patrick >> >> [1] http://cr.openjdk.java.net/~reinhapa/reviews/8196298/webrev.02 >> [2] https://bugs.openjdk.java.net/browse/JDK-8196350 >> >> >>> Am 07.03.2018 um 11:41 schrieb Patrick Reinhart : >>> >>> I applied those changes here: >>> >>> http://cr.openjdk.java.net/~reinhapa/reviews/8196298/webrev.02 >>> >>> -Patrick >>> >>> >>>> Am 06.03.2018 um 23:12 schrieb Brian Burkhalter >>>> : >>>> >>>> Yes, I think so and and also the parameter ?csq' is allowed to be >>>> null so Objects.requireNonNull(csq) should be removed at lines 100 >>>> and 107 as no NPE is specified for these methods [1, 2]. >>>> >>>> Thanks, >>>> >>>> Brian >>>> >>>> [1] >>>> https://download.java.net/java/jdk10/docs/api/java/io/Writer.html#append(java.lang.CharSequence) >>>> [2] >>>> https://download.java.net/java/jdk10/docs/api/java/io/Writer.html#append(java.lang.CharSequence,int,int) >>>> >>>> On Mar 6, 2018, at 11:49 AM, Bernd Eckenfels >>>> wrote: >>>> >>>>> Just a nit, Should append(CharSequence,int,int) also use >>>>> checkFromIndexSize? > From david.holmes at oracle.com Mon Mar 19 05:11:04 2018 From: david.holmes at oracle.com (David Holmes) Date: Mon, 19 Mar 2018 15:11:04 +1000 Subject: RFR (XS): 8199768 jdk/test/lib/compiler/CompilerUtils.java needs to provide more control over compilation Message-ID: <67bba63f-8d67-7f44-38f3-7fda112bbfb2@oracle.com> Unsure exactly who should review this ... bug: https://bugs.openjdk.java.net/browse/JDK-8199768 webrev: http://cr.openjdk.java.net/~dholmes/8199768/webrev/ CompilerUtils.compile compiles all source files in a given directory tree into a specific directory. This is done by passing Integer.MAX_VALUE as the 'depth' argument to Files.find. There are times when we** don't want to compile the entire tree into a single directory so it would be useful to be able to specify whether or not to recurse (depth = Integer.MAX_VALUE) or not (depth = 1). ** I need this for some tests I'm developing for Nestmates (JEP 181) and it will be simpler to fix this separately in mainline. Testing: - check locally that test using CompilerUtils still pass. - mach5 jdk/hs tier1 and 2 Thanks, David From thomas.schatzl at oracle.com Mon Mar 19 09:28:07 2018 From: thomas.schatzl at oracle.com (Thomas Schatzl) Date: Mon, 19 Mar 2018 10:28:07 +0100 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> <5A9D8F33.5060500@oracle.com> <5A9DAC84.906@oracle.com> <5A9DAE87.8020801@oracle.com> <1521102348.2448.25.camel@oracle.com> <23639144-5217-4A0F-930C-EF24B4976544@oracle.com> Message-ID: <1521451687.2323.5.camel@oracle.com> Hi, On Fri, 2018-03-16 at 17:19 +0000, Ian Rogers wrote: > Thanks Paul, very interesting. > > On Fri, Mar 16, 2018 at 9:21 AM Paul Sandoz > wrote: > > Hi Ian, Thomas, > > > > [...] > > (This is also something we need to consider if we modify buffers to > > support capacities larger than Integer.MAX_VALUE. Also connects > > with Project Panama.) > > > > If Thomas has not done so or does not plan to i can log an issue > > for you. > > > > That'd be great. I wonder if identifying more TTSP issues should also > be a bug. Its interesting to observe that overlooking TTSP in C2 > motivated the Unsafe.copyMemory change permitting a fresh TTSP issue. > If TTSP is a 1st class issue then maybe we can deprecate JNI critical > regions to support that effort :-) Please log an issue. I am still a bit unsure what and how many issues should be filed. @Ian: at bugreports.oracle.com everyone may file bug reports without the need for an account. It will take some time until they show up in Jira due to vetting, but if you have a good case, and can e.g. link to the mailing list, this should be painless. Thanks, Thomas From roger.riggs at oracle.com Mon Mar 19 13:55:04 2018 From: roger.riggs at oracle.com (Roger Riggs) Date: Mon, 19 Mar 2018 09:55:04 -0400 Subject: RFR 8199756 : Simplify language, country, script, and variant property initialization In-Reply-To: <3fd6536d-f5d7-ff7d-106d-14eda3e72c71@oracle.com> References: <3fd6536d-f5d7-ff7d-106d-14eda3e72c71@oracle.com> Message-ID: Hi Alan, The original changeset [1] is most easily viewed in the jdk-8u repo. The comment and placement of the removes of the properties and the code to re-set them around the call to the JVM_InitProperties (which sets properties from the -D arguments among others), seem to indicate that the previous property values are irrelevant. The remaining question is whether there are any side effects or usage of those four property values between the time they are initially set and when they are removed. The code in System.initProperties is straightforward and the bulk of the code is simply setting property values, with one interspersed call to initialize the sun.jnu_encoding. From all appearances there are no side effects or uses of the initially set values of those four properties. Thanks, Roger [1] https://bugs.openjdk.java.net/browse/JDK-4700857 ??? RFE: separating user locale and user interface locale On 3/17/18 5:46 AM, Alan Bateman wrote: > On 16/03/2018 20:32, Roger Riggs wrote: >> Please review a small simplification of the initialization of System >> properties for >> language, country, script, and variant.? Some steps for initializing >> them are unnecessary. >> The tests pass; a careful review would be appreciated so as to avoid >> breakage. >> >> Webrev: >> http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ >> >> Issue: >> ? https://bugs.openjdk.java.net/browse/JDK-8199756 > There are subtle interactions with how system properties are set in > the VM and on the command line which will take a bit effort to > research in order to review this and be satisfied that the change is > safe. Have you dug into the ancient history and bugs to see why it was > done this way? > > -Alan From Roger.Riggs at Oracle.com Mon Mar 19 14:10:01 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Mon, 19 Mar 2018 10:10:01 -0400 Subject: RFR 8196298 Add null Reader and Writer with latest changes In-Reply-To: <2037e930-eb0c-39a5-bcb6-c39a46447f9a@reini.net> References: <6AF3DEA9-5572-47B1-804E-AD7B0E46D833@reini.net> <3ebd00ec-aa2d-65b9-9f68-0d693628ef2b@oracle.com> <5a9ef0dc.77b0df0a.bb39.cc95@mx.google.com> <5D587382-6466-4854-8C70-68CBC8C7332E@oracle.com> <21DAB782-B121-4117-BBC4-CEA983DC523D@reini.net> <2EA55A50-797E-4BE1-9A1C-E41B5FB3C199@reini.net> <2bee222e-649b-14f6-baa7-11af737c16f8@oracle.com> <2037e930-eb0c-39a5-bcb6-c39a46447f9a@reini.net> Message-ID: <6c28facf-3f42-45d6-4def-61d446619198@Oracle.com> Hi Patrick, Committed;? Thanks for the initiative and the perseverance. Roger On 3/18/2018 6:41 AM, Patrick Reinhart wrote: > Hi Roger, > > Seems there are no more comments...?? - all shocked :-) > > -Patrick From adam.farley at uk.ibm.com Mon Mar 19 16:55:50 2018 From: adam.farley at uk.ibm.com (Adam Farley8) Date: Mon, 19 Mar 2018 16:55:50 +0000 Subject: RFR: JDK-8190187: C++ code calling JNI_CreateJavaVM can be killed by Java In-Reply-To: References: Message-ID: Bump :) Best Regards Adam Farley ---- Last email ---- Hi Alan Thanks for getting back to me on this. :) I've changed the hg_diff as described below, see the attached. > On 27/02/2018 15:04, Adam Farley8 wrote: > > Resending. Bump. :) > > On 14/02/2018 14:13, Adam Farley8 wrote: >>> Hi All, >>> >>> -- Short version -- >>> >>> Could a committer please take the fix for JDK-8190187 (full code included >>> in the bug) and: >>> >>> 1) Complete the CSR process for the new JNI Return code. >>> 2) Commit the changes that contain (a) the new return code, and (b) the >>> non-Hotspot code that handles the new code. >> The patches attached to the JIRA issue are missing the changes to the >> JVM TI spec (jvmti.xml). > >> I'm not seeing the JNI return codes in that file. Are you after one of those >> dated updates near the bottom? >> e.g. >> ``` >> >> Added JNI_SILENT_EXIT return code for early exits without errors. >> java.c's ParseArguments function now sets pret value to 2 for a NULL pwhat. >> This allows us to clearly identify when no class was set, but no other error has occurred. >> This is undone in java.c's ContinueInNewThread method, so the surface behaviour does not change. >> >> ``` > The "Agent Start-Up" section is the section to look at. The important part is: > > "The return value from Agent_OnLoad or Agent_OnLoad_ is used to indicate an error. Any value other than zero indicates an error and causes termination of the VM." > > If there is special return value to mean "VM terminates without error" then this part of the spec will need to be adjusted. Ah, that makes sense. I altered that bit and regenerated the hg_diff. > An additional point is that you can start several agents from the command line, does the VM terminate after it has started all agents or does it terminate when the first agent returns asks the VM to terminate quietly? If I'm reading the code correctly, the loop that initialises the different agents (which I believe to be the loop containing "// Invoke the Agent_OnLoad function") is not interrupted by the return of a silent exit code, however it only takes one agent returning this code to cause the VM to be destroyed once startup is complete. > > > > > >>> There is also text to be written for the JNI spec if this proposal goes >>> ahead. > >> I assume you mean the "RETURNS" section of the JNI_CreateJavaVM >> bit on the invocation.html web page. Something like this? > >> ``` >> RETURNS: >> Returns JNI_OK on success; returns a suitable JNI error code (a negative number) on failure. >> >> The sole exception is a silent exit, which returns JNI error code JNI_SILENT_EXIT. >> This indicates that the VM cannot be used, but that this is the intended behaviour for the >> arguments used. E.g. -Xlog:help (which prints help output and then destroys the VM) >> ``` > Yes, this is the place that will need changes. > Ok. The most official-looking place for this documentation is on the Oracle website. I'm not sure how to go about making this change happen though. Is the change to this documentation something I can push through one of the mailing lists? Or is it perhaps part of the CSR process? > > > > >>> >>> I don't agree that the launcher should be looking for >>> "-agentlib:jdwp=help" in the command line as it's just one of many ways >>> that the debugger agent might be started (e.g. -Xrunjdwp:, >>> _JAVA_TOOLS_OPTIONS, ...). > >> We can avoid that by finding a way around this line in ContinueInNewThread (java.c): > >> ``` >> return (ret != 0) ? ret : rslt; >> ``` > >> I have devised a means to do this, as outlined in the jvmti.xml change above. I put the >> changes into a recent clone of jdk/jdk, and attached the hg diff, along with an improved >> test. > > The launcher should only need to look at the return value from JNI CreateJavaVM. I don't think it should do any special handling for the JDWP or other agents (there are just too many ways to inject command lines and the launcher cannot be expected to handle all of them). > >-Alan > I agree. The change I made in response to your earlier comment is not jdwp-specific. Rather, it sets "ret" to "2" if the user has not specified an executable class in the command line. I did this because a ret value of "1" indicates an error, but we don't want to override a return code of JNI_SILENT_EXIT with ret's value if the only error was "no class was specified". So I set ret to "2" if no class is specified, and altered the aforementioned bit in ContinueInNewThread (java.c) to pick up on a ret value of 2. If the ret value is 2, and rslt is JNI_SILENT_EXIT, then we know that no error has occurred (other than "no class was specified"), and that JNI_SILENT_EXIT should be returned, as opposed to the current functionality, where it is the non-0 ret value which is returned (erroneously, in the event of a silent exit). I think my changeset explains this more concisely than I have. :) Let me know if this has just made you more confused. :) - Adam [attachment "hg_diff.txt" deleted by Adam Farley8/UK/IBM] 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 -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: hg_diff.txt URL: From paul.sandoz at oracle.com Mon Mar 19 17:18:13 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 19 Mar 2018 10:18:13 -0700 Subject: RFR (XS): 8199768 jdk/test/lib/compiler/CompilerUtils.java needs to provide more control over compilation In-Reply-To: <67bba63f-8d67-7f44-38f3-7fda112bbfb2@oracle.com> References: <67bba63f-8d67-7f44-38f3-7fda112bbfb2@oracle.com> Message-ID: <7D8BD00A-5CB1-4B28-93E9-CBA4126196F6@oracle.com> Looks ok, +1 Paul. > On Mar 18, 2018, at 10:11 PM, David Holmes wrote: > > Unsure exactly who should review this ... > > bug: https://bugs.openjdk.java.net/browse/JDK-8199768 > webrev: http://cr.openjdk.java.net/~dholmes/8199768/webrev/ > > CompilerUtils.compile compiles all source files in a given directory tree into a specific directory. This is done by passing Integer.MAX_VALUE as the 'depth' argument to Files.find. > > There are times when we** don't want to compile the entire tree into a single directory so it would be useful to be able to specify whether or not to recurse (depth = Integer.MAX_VALUE) or not (depth = 1). > > ** I need this for some tests I'm developing for Nestmates (JEP 181) and it will be simpler to fix this separately in mainline. > > Testing: > - check locally that test using CompilerUtils still pass. > - mach5 jdk/hs tier1 and 2 > > Thanks, > David From Alan.Bateman at oracle.com Mon Mar 19 17:23:20 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 19 Mar 2018 17:23:20 +0000 Subject: RFR (XS): 8199768 jdk/test/lib/compiler/CompilerUtils.java needs to provide more control over compilation In-Reply-To: <67bba63f-8d67-7f44-38f3-7fda112bbfb2@oracle.com> References: <67bba63f-8d67-7f44-38f3-7fda112bbfb2@oracle.com> Message-ID: On 19/03/2018 05:11, David Holmes wrote: > Unsure exactly who should review this ... > > bug: https://bugs.openjdk.java.net/browse/JDK-8199768 > webrev: http://cr.openjdk.java.net/~dholmes/8199768/webrev/ > > CompilerUtils.compile compiles all source files in a given directory > tree into a specific directory. This is done by passing > Integer.MAX_VALUE as the 'depth' argument to Files.find. > > There are times when we** don't want to compile the entire tree into a > single directory so it would be useful to be able to specify whether > or not to recurse (depth = Integer.MAX_VALUE) or not (depth = 1). > > ** I need this for some tests I'm developing for Nestmates (JEP 181) > and it will be simpler to fix this separately in mainline. Looks okay although an alternative is to just invoke the existing method with the specify source files that you want to compile (which I think what is what several tests do when they have only one or two source files to compile). -Alan From martinrb at google.com Mon Mar 19 19:29:21 2018 From: martinrb at google.com (Martin Buchholz) Date: Mon, 19 Mar 2018 19:29:21 +0000 Subject: [PATCH] unnecessary null check inside of java.lang.Boolean.valueOf(String) In-Reply-To: <6635141521367007@web3g.yandex.ru> References: <6635141521367007@web3g.yandex.ru> Message-ID: On Sun, Mar 18, 2018 at 2:57 AM ?????? ??????? wrote: ??????, ???????. https://bugs.openjdk.java.net/browse/JDK-8199800 From martinrb at google.com Mon Mar 19 19:32:08 2018 From: martinrb at google.com (Martin Buchholz) Date: Mon, 19 Mar 2018 19:32:08 +0000 Subject: [PATCH] unnecessary null check inside of java.lang.Boolean.valueOf(String) In-Reply-To: <6635141521367007@web3g.yandex.ru> References: <6635141521367007@web3g.yandex.ru> Message-ID: > > */ > public boolean equals(Object obj) { > if (obj instanceof Boolean) { > - return value == ((Boolean)obj).booleanValue(); > + return value == (Boolean) obj; > } > > This is not correct, since we might have multiple Boolean objects that are equals, but not ==. Do we have a test that would catch this? From vitalyd at gmail.com Mon Mar 19 19:58:06 2018 From: vitalyd at gmail.com (Vitaly Davidovich) Date: Mon, 19 Mar 2018 15:58:06 -0400 Subject: [PATCH] unnecessary null check inside of java.lang.Boolean.valueOf(String) In-Reply-To: References: <6635141521367007@web3g.yandex.ru> Message-ID: It's surprising that both variants don't perform the same when JIT compiled. On Mon, Mar 19, 2018 at 3:32 PM, Martin Buchholz wrote: > > > > */ > > public boolean equals(Object obj) { > > if (obj instanceof Boolean) { > > - return value == ((Boolean)obj).booleanValue(); > > + return value == (Boolean) obj; > > } > > > > > This is not correct, since we might have multiple Boolean objects that are > equals, but not ==. > Do we have a test that would catch this? > From Roger.Riggs at Oracle.com Mon Mar 19 20:12:04 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Mon, 19 Mar 2018 16:12:04 -0400 Subject: [11] RFR: 8191410 : Unicode 10.0.0 In-Reply-To: <6d3c2e65-c144-280d-cd31-3eeb6ed3417d@oracle.com> References: <6d3c2e65-c144-280d-cd31-3eeb6ed3417d@oracle.com> Message-ID: <7dca3d78-a2db-1ff3-9c07-c711aa7a930f@Oracle.com> Hi Rachna, Thanks for the updates; looks good, Roger On 3/13/2018 5:28 AM, Rachna Goel wrote: > > Hi Roger, Ivan, > > There is no change in algorithm as such but there has been mainly > stability improvements, defects fixed, performance enhancements. e.g > Updated header check, version and loading for latest binary files, > Simple case mappings will be more efficient as unnecessary checking > has been removed. > complete list of changes can be found at: > > http://bugs.icu-project.org/trac/query?status=closed&resolution=fixed&resolution=fixedbyotherticket&milestone=60.1&milestone=60.2&group=project&max=999&col=id&col=summary&col=resolution&col=milestone&col=status&col=owner&col=type&col=priority&col=project&col=weeks&order=priority > > Also, I have incorporated? suggestions given from Ivan. > Kindly have a look at updated webrev: > > http://cr.openjdk.java.net/~rgoel/JDK-8191410/webrev.01/ > > Thanks, > Rachna > > > On 3/8/18 9:47 PM, Roger Riggs wrote: >> Hi Rachna, >> >> sun/text/normalizer/NormalizerImpl.java: >> >> Is there a higher level description of the algorithmic changes? >> >> 102-105:?? These look like accidental changes: the space should not >> be removed and the trailing "{" doesn't make sense in a comment. >> >> Regards, Roger >> >> >> On 3/8/2018 6:56 AM, Rachna Goel wrote: >>> Hi, >>> >>> Please review the proposed changes for JDK-819410. >>> >>> Bug : https://bugs.openjdk.java.net/browse/JDK-8191410 >>> >>> proposed changeset is located at : >>> >>> http://cr.openjdk.java.net/~rgoel/JDK-8191410/webrev/ >>> >>> This serves as the implementation for JEP 327. >>> >> > > -- > Thanks, > Rachna From naoto.sato at oracle.com Mon Mar 19 20:20:38 2018 From: naoto.sato at oracle.com (Naoto Sato) Date: Mon, 19 Mar 2018 13:20:38 -0700 Subject: [11] RFR: 8191410 : Unicode 10.0.0 In-Reply-To: <7dca3d78-a2db-1ff3-9c07-c711aa7a930f@Oracle.com> References: <6d3c2e65-c144-280d-cd31-3eeb6ed3417d@oracle.com> <7dca3d78-a2db-1ff3-9c07-c711aa7a930f@Oracle.com> Message-ID: <9d31887f-9bba-e25b-337d-28c2d857baf6@oracle.com> +1 Naoto On 3/19/18 1:12 PM, Roger Riggs wrote: > Hi Rachna, > > Thanks for the updates; looks good, > > Roger > > > On 3/13/2018 5:28 AM, Rachna Goel wrote: >> >> Hi Roger, Ivan, >> >> There is no change in algorithm as such but there has been mainly >> stability improvements, defects fixed, performance enhancements. e.g >> Updated header check, version and loading for latest binary files, >> Simple case mappings will be more efficient as unnecessary checking >> has been removed. >> complete list of changes can be found at: >> >> http://bugs.icu-project.org/trac/query?status=closed&resolution=fixed&resolution=fixedbyotherticket&milestone=60.1&milestone=60.2&group=project&max=999&col=id&col=summary&col=resolution&col=milestone&col=status&col=owner&col=type&col=priority&col=project&col=weeks&order=priority >> >> >> Also, I have incorporated? suggestions given from Ivan. >> Kindly have a look at updated webrev: >> >> http://cr.openjdk.java.net/~rgoel/JDK-8191410/webrev.01/ >> >> Thanks, >> Rachna >> >> >> On 3/8/18 9:47 PM, Roger Riggs wrote: >>> Hi Rachna, >>> >>> sun/text/normalizer/NormalizerImpl.java: >>> >>> Is there a higher level description of the algorithmic changes? >>> >>> 102-105:?? These look like accidental changes: the space should not >>> be removed and the trailing "{" doesn't make sense in a comment. >>> >>> Regards, Roger >>> >>> >>> On 3/8/2018 6:56 AM, Rachna Goel wrote: >>>> Hi, >>>> >>>> Please review the proposed changes for JDK-819410. >>>> >>>> Bug : https://bugs.openjdk.java.net/browse/JDK-8191410 >>>> >>>> proposed changeset is located at : >>>> >>>> http://cr.openjdk.java.net/~rgoel/JDK-8191410/webrev/ >>>> >>>> This serves as the implementation for JEP 327. >>>> >>> >> >> -- >> Thanks, >> Rachna > From ivan.gerasimov at oracle.com Mon Mar 19 21:21:30 2018 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Mon, 19 Mar 2018 14:21:30 -0700 Subject: [PATCH] unnecessary null check inside of java.lang.Boolean.valueOf(String) In-Reply-To: References: <6635141521367007@web3g.yandex.ru> Message-ID: On 3/19/18 12:32 PM, Martin Buchholz wrote: >> */ >> public boolean equals(Object obj) { >> if (obj instanceof Boolean) { >> - return value == ((Boolean)obj).booleanValue(); >> + return value == (Boolean) obj; >> } >> >> > This is not correct, since we might have multiple Boolean objects that are > equals, but not ==. > Do we have a test that would catch this? > But isn't it autounboxing happening when a primitive value gets compared to a Boolean? I suspect the bytecode would be the same, and if this is the case, I would prefer to keep the original line to avoid confusion. -- With kind regards, Ivan Gerasimov From david.holmes at oracle.com Mon Mar 19 21:41:27 2018 From: david.holmes at oracle.com (David Holmes) Date: Tue, 20 Mar 2018 07:41:27 +1000 Subject: RFR (XS): 8199768 jdk/test/lib/compiler/CompilerUtils.java needs to provide more control over compilation In-Reply-To: <7D8BD00A-5CB1-4B28-93E9-CBA4126196F6@oracle.com> References: <67bba63f-8d67-7f44-38f3-7fda112bbfb2@oracle.com> <7D8BD00A-5CB1-4B28-93E9-CBA4126196F6@oracle.com> Message-ID: <43c72baf-e191-b2ba-9739-c4d761e76729@oracle.com> Thanks Paul! David On 20/03/2018 3:18 AM, Paul Sandoz wrote: > Looks ok, +1 > > Paul. > >> On Mar 18, 2018, at 10:11 PM, David Holmes wrote: >> >> Unsure exactly who should review this ... >> >> bug: https://bugs.openjdk.java.net/browse/JDK-8199768 >> webrev: http://cr.openjdk.java.net/~dholmes/8199768/webrev/ >> >> CompilerUtils.compile compiles all source files in a given directory tree into a specific directory. This is done by passing Integer.MAX_VALUE as the 'depth' argument to Files.find. >> >> There are times when we** don't want to compile the entire tree into a single directory so it would be useful to be able to specify whether or not to recurse (depth = Integer.MAX_VALUE) or not (depth = 1). >> >> ** I need this for some tests I'm developing for Nestmates (JEP 181) and it will be simpler to fix this separately in mainline. >> >> Testing: >> - check locally that test using CompilerUtils still pass. >> - mach5 jdk/hs tier1 and 2 >> >> Thanks, >> David > From david.holmes at oracle.com Mon Mar 19 21:44:06 2018 From: david.holmes at oracle.com (David Holmes) Date: Tue, 20 Mar 2018 07:44:06 +1000 Subject: RFR (XS): 8199768 jdk/test/lib/compiler/CompilerUtils.java needs to provide more control over compilation In-Reply-To: References: <67bba63f-8d67-7f44-38f3-7fda112bbfb2@oracle.com> Message-ID: Thanks for looking at this Alan! On 20/03/2018 3:23 AM, Alan Bateman wrote: > On 19/03/2018 05:11, David Holmes wrote: >> Unsure exactly who should review this ... >> >> bug: https://bugs.openjdk.java.net/browse/JDK-8199768 >> webrev: http://cr.openjdk.java.net/~dholmes/8199768/webrev/ >> >> CompilerUtils.compile compiles all source files in a given directory >> tree into a specific directory. This is done by passing >> Integer.MAX_VALUE as the 'depth' argument to Files.find. >> >> There are times when we** don't want to compile the entire tree into a >> single directory so it would be useful to be able to specify whether >> or not to recurse (depth = Integer.MAX_VALUE) or not (depth = 1). >> >> ** I need this for some tests I'm developing for Nestmates (JEP 181) >> and it will be simpler to fix this separately in mainline. > Looks okay although an alternative is to just invoke the existing method > with the specify source files that you want to compile (which I think > what is what several tests do when they have only one or two source > files to compile). Based on the description I hadn't realized the Path could actually just be a single file. But I think my change makes it easier to compile things without needing to enumerate all the source files. You can now compile 1 file, 1 directory, or 1 directory tree. Thanks, David > -Alan From david.holmes at oracle.com Mon Mar 19 22:38:18 2018 From: david.holmes at oracle.com (David Holmes) Date: Tue, 20 Mar 2018 08:38:18 +1000 Subject: RFR 8199756 : Simplify language, country, script, and variant property initialization In-Reply-To: References: <3fd6536d-f5d7-ff7d-106d-14eda3e72c71@oracle.com> Message-ID: Hi Roger, On 19/03/2018 11:55 PM, Roger Riggs wrote: > Hi Alan, > > The original changeset [1] is most easily viewed in the jdk-8u repo. > > The comment and placement of the removes of the properties and the code > to re-set them > around the call to the JVM_InitProperties (which sets properties from the > -D arguments among others), seem to indicate that the previous property > values are irrelevant. Not irrelevant: defaults. > > The remaining question is whether there are any side effects or usage of > those > four property values between the time they are initially set and when > they are removed. > The code in System.initProperties is straightforward and the bulk of the > code > is simply setting property values, with one interspersed call to > initialize the sun.jnu_encoding. > From all appearances there are no side effects or uses of the initially > set values of those four properties. I would have expected these values to possibly have an impact on InitalizeEncoding and subsequent use of PUTPROP_ForPlatformNString. Else why set them early then unset them again? Or maybe they impact any error messages that might arise in this stage of initialization? I expect any issues here to be extremely subtle - as Alan indicated. If there is any path to Java code that may try to read and use these properties then they need to be set. And if these are truly unnecessary then doesn't that imply that placing them in sprops via GetJavaProperties in the first place is also unnecessary? Has this been extensively tested on a non-English Windows system? And do we even have tests for various initialization failures? David ----- > Thanks, Roger > > [1] https://bugs.openjdk.java.net/browse/JDK-4700857 > ??? RFE: separating user locale and user interface locale > > On 3/17/18 5:46 AM, Alan Bateman wrote: >> On 16/03/2018 20:32, Roger Riggs wrote: >>> Please review a small simplification of the initialization of System >>> properties for >>> language, country, script, and variant.? Some steps for initializing >>> them are unnecessary. >>> The tests pass; a careful review would be appreciated so as to avoid >>> breakage. >>> >>> Webrev: >>> http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ >>> >>> Issue: >>> ? https://bugs.openjdk.java.net/browse/JDK-8199756 >> There are subtle interactions with how system properties are set in >> the VM and on the command line which will take a bit effort to >> research in order to review this and be satisfied that the change is >> safe. Have you dug into the ancient history and bugs to see why it was >> done this way? >> >> -Alan > From ivan.gerasimov at oracle.com Tue Mar 20 08:58:55 2018 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 20 Mar 2018 01:58:55 -0700 Subject: RFR 8199843 : Optimize Integer/Long.highestOneBit() Message-ID: Hello! The hightestOneBit function doesn't have an intrinsic and is currently implemented with a dozen of instructions. Alternatively, it could be implemented as MIN_VALUE >>> numberOfLeadingZeros(i), which works for all integers but zero. The former function gets intrisified by hotspot, which results in +27% of throughput (see the jmh results below). Would you please help review this simple fix? BUGURL: https://bugs.openjdk.java.net/browse/JDK-8199843 WEBREV: http://cr.openjdk.java.net/~igerasim/8199843/00/webrev/ Benchmark: http://cr.openjdk.java.net/~igerasim/8199843/00/MyBenchmark.java Benchmark results: Benchmark (arg) Mode Cnt Score Error Units MyBenchmark.int_testMethod_new 0 thrpt 35 323430664.593 ? 7492044.171 ops/s MyBenchmark.int_testMethod_new 42 thrpt 35 298526237.078 ? 5978291.689 ops/s MyBenchmark.int_testMethod_new -42 thrpt 35 302903562.073 ? 7984723.721 ops/s MyBenchmark.int_testMethod_org 0 thrpt 35 236245042.891 ? 3635990.596 ops/s MyBenchmark.int_testMethod_org 42 thrpt 35 237903410.753 ? 3437684.390 ops/s MyBenchmark.int_testMethod_org -42 thrpt 35 238472580.618 ? 2654886.010 ops/s MyBenchmark.long_testMethod_new 0 thrpt 35 282646114.501 ? 48028366.305 ops/s MyBenchmark.long_testMethod_new 42 thrpt 35 282382228.405 ? 5781529.307 ops/s MyBenchmark.long_testMethod_new -42 thrpt 35 276724858.286 ? 6529561.227 ops/s MyBenchmark.long_testMethod_org 0 thrpt 35 198500211.972 ? 15096862.367 ops/s MyBenchmark.long_testMethod_org 42 thrpt 35 215854630.194 ? 3112930.563 ops/s MyBenchmark.long_testMethod_org -42 thrpt 35 217992805.521 ? 2622877.082 ops/s Thanks in advance! -- With kind regards, Ivan Gerasimov From claes.redestad at oracle.com Tue Mar 20 09:46:01 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 20 Mar 2018 10:46:01 +0100 Subject: RFR 8199843 : Optimize Integer/Long.highestOneBit() In-Reply-To: References: Message-ID: Hi, On 2018-03-20 09:58, Ivan Gerasimov wrote: > Hello! > > The hightestOneBit function doesn't have an intrinsic and is currently > implemented with a dozen of instructions. > Alternatively, it could be implemented as MIN_VALUE >>> > numberOfLeadingZeros(i), which works for all integers but zero. > The former function gets intrisified by hotspot, which results in +27% > of throughput (see the jmh results below). > > Would you please help review this simple fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8199843 > WEBREV: http://cr.openjdk.java.net/~igerasim/8199843/00/webrev/ nice optimization! > Benchmark: > http://cr.openjdk.java.net/~igerasim/8199843/00/MyBenchmark.java > > Benchmark results: > > Benchmark??????????????????????? (arg)?? Mode? Cnt Score Error? Units > MyBenchmark.int_testMethod_new?????? 0? thrpt?? 35 323430664.593 ?? > 7492044.171? ops/s > MyBenchmark.int_testMethod_new????? 42? thrpt?? 35 298526237.078 ?? > 5978291.689? ops/s > MyBenchmark.int_testMethod_new???? -42? thrpt?? 35 302903562.073 ?? > 7984723.721? ops/s > MyBenchmark.int_testMethod_org?????? 0? thrpt?? 35 236245042.891 ?? > 3635990.596? ops/s > MyBenchmark.int_testMethod_org????? 42? thrpt?? 35 237903410.753 ?? > 3437684.390? ops/s > MyBenchmark.int_testMethod_org???? -42? thrpt?? 35 238472580.618 ?? > 2654886.010? ops/s > MyBenchmark.long_testMethod_new????? 0? thrpt?? 35 282646114.501 ? > 48028366.305? ops/s > MyBenchmark.long_testMethod_new???? 42? thrpt?? 35 282382228.405 ?? > 5781529.307? ops/s > MyBenchmark.long_testMethod_new??? -42? thrpt?? 35 276724858.286 ?? > 6529561.227? ops/s > MyBenchmark.long_testMethod_org????? 0? thrpt?? 35 198500211.972 ? > 15096862.367? ops/s > MyBenchmark.long_testMethod_org???? 42? thrpt?? 35 215854630.194 ?? > 3112930.563? ops/s > MyBenchmark.long_testMethod_org??? -42? thrpt?? 35 217992805.521 ?? > 2622877.082? ops/s To nitpick a bit: Please run with some appropriate time unit, e.g., "-tu us" to make results more human readable. And where are the baseline results? :-) It'd also be nice to verify we don't regress too much in case there's no intrinsic, i.e., test with the intrinsic disabled. Thanks! /Claes From claes.redestad at oracle.com Tue Mar 20 13:00:58 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 20 Mar 2018 14:00:58 +0100 Subject: RFR: 8199862: Examine ProxyBuilder::referencedTypes startup cost Message-ID: <5fb829e1-495e-824c-dfc8-7c10217f6233@oracle.com> Hi, by desugaring Stream+lambda usage in Proxy$ProxyBuilder::referencedTypes - and carefully avoiding cloning of parameter and exception type arrays - we can significantly reduce the startup overhead of doing annotation processing in a set of typical applications. Webrev: http://cr.openjdk.java.net/~redestad/8199862/open.00/ Bug: https://bugs.openjdk.java.net/browse/JDK-8199862 Thanks! /Claes From peter.levart at gmail.com Tue Mar 20 13:05:48 2018 From: peter.levart at gmail.com (Peter Levart) Date: Tue, 20 Mar 2018 14:05:48 +0100 Subject: RFR 8199843 : Optimize Integer/Long.highestOneBit() In-Reply-To: References: Message-ID: <1f0c20c9-4618-79fd-9c3b-be97504f65dc@gmail.com> Hi Ivan, What about branch-less variant? public static int highestOneBit(int i) { ??? return i & (MIN_VALUE >>> numberOfLeadingZeros(i)); } Would it be any better for call sites that vary 0 and non-0 argument? Regards, Peter On 03/20/2018 09:58 AM, Ivan Gerasimov wrote: > Hello! > > The hightestOneBit function doesn't have an intrinsic and is currently > implemented with a dozen of instructions. > Alternatively, it could be implemented as MIN_VALUE >>> > numberOfLeadingZeros(i), which works for all integers but zero. > The former function gets intrisified by hotspot, which results in +27% > of throughput (see the jmh results below). > > Would you please help review this simple fix? > > BUGURL: https://bugs.openjdk.java.net/browse/JDK-8199843 > WEBREV: http://cr.openjdk.java.net/~igerasim/8199843/00/webrev/ > Benchmark: > http://cr.openjdk.java.net/~igerasim/8199843/00/MyBenchmark.java > > Benchmark results: > > Benchmark??????????????????????? (arg)?? Mode? Cnt Score Error? Units > MyBenchmark.int_testMethod_new?????? 0? thrpt?? 35 323430664.593 ?? > 7492044.171? ops/s > MyBenchmark.int_testMethod_new????? 42? thrpt?? 35 298526237.078 ?? > 5978291.689? ops/s > MyBenchmark.int_testMethod_new???? -42? thrpt?? 35 302903562.073 ?? > 7984723.721? ops/s > MyBenchmark.int_testMethod_org?????? 0? thrpt?? 35 236245042.891 ?? > 3635990.596? ops/s > MyBenchmark.int_testMethod_org????? 42? thrpt?? 35 237903410.753 ?? > 3437684.390? ops/s > MyBenchmark.int_testMethod_org???? -42? thrpt?? 35 238472580.618 ?? > 2654886.010? ops/s > MyBenchmark.long_testMethod_new????? 0? thrpt?? 35 282646114.501 ? > 48028366.305? ops/s > MyBenchmark.long_testMethod_new???? 42? thrpt?? 35 282382228.405 ?? > 5781529.307? ops/s > MyBenchmark.long_testMethod_new??? -42? thrpt?? 35 276724858.286 ?? > 6529561.227? ops/s > MyBenchmark.long_testMethod_org????? 0? thrpt?? 35 198500211.972 ? > 15096862.367? ops/s > MyBenchmark.long_testMethod_org???? 42? thrpt?? 35 215854630.194 ?? > 3112930.563? ops/s > MyBenchmark.long_testMethod_org??? -42? thrpt?? 35 217992805.521 ?? > 2622877.082? ops/s > > Thanks in advance! > From james.laskey at oracle.com Tue Mar 20 13:35:59 2018 From: james.laskey at oracle.com (Jim Laskey) Date: Tue, 20 Mar 2018 10:35:59 -0300 Subject: Raw String Literal Library Support In-Reply-To: References: Message-ID: <07A1E569-20BC-42F8-9756-83D5A84A4BA0@oracle.com> Summary. A. Line support. - Supporting a mix of line terminators `\n|\r\n|\r` is already a well established pattern in language parsers, in the JDK (ex. see java.nio.file.FileChannelLinesSpliterator) and RegEx (ex. see `\R`). The performance difference between checking one vs the three is negligible. - Yes, Stream stream = Pattern.compile("\n|\r\n|\r").splitAsStream(string); is very useful (Spliterators rule), but is cumbersome in this expected to be common use case. Only so-so streamy. :-) - BufferedRead.lines() vs. String.lines() is a tricky discussion. It comes down to whether the new line is a terminator or a separator. In the i/o case, it seems terminator is the right answer. A well formed text file will have a new line at the end of every line. However, I think you?ll find when people work with multi-line strings they think of new line as a separator. Hence, the common use of split(?\n?) and ??.split(?\n?).length == 1. Indentation, the position of closing delimiter and margin trimming makes that last line very fluid. What clinches the deal is that string.lines().collect(joining(?\n?)).equals(string). I?ll ensure both versions of lines() have the difference well javadocumented. - The current Spliterator implementation makes String.lines().toArray(String[]::new) an order of magnitude faster than split(`\n|\r\n|\r`). That?s why I implemented it for margin management. Faster still if no collection/array is constructed. BTW: split(`\R`) is 2x-3x faster than split(`\n|\r\n|\r`). Nice. B. Additions to basic trim methods. - Revamped to become strip, stripLeading, stripTrailing using Character.isWhiteSpace(codepoint) as the test (optimized using ch == ? ' || ch == ?\t? || Character.isWhiteSpace(ch)). - No strong feeling about it, but String.trim() could be recommended for deprecation. C. Margin management. - String.trimMarkers() as a default to String.trimMarkers(?|?, ?|?) is reasonable. Will put it in the CSR for broader discussion. - Re use of patterns. I think the Stream lines() method will make it very easy enough to create custom trim margin lambdas. D. Escape management. - Good Cheers, ? Jim > On Mar 13, 2018, at 10:47 AM, Jim Laskey wrote: > > With the announcement of JEP 326 Raw String Literals, we would like to open up a discussion with regards to RSL library support. Below are several implemented String methods that are believed to be appropriate. Please comment on those mentioned below including recommending alternate names or signatures. Additional methods can be considered if warranted, but as always, the bar for inclusion in String is high. > > You should keep a couple things in mind when reviewing these methods. > > Methods should be applicable to all strings, not just Raw String Literals. > > The number of additional methods should be minimized, not adding every possible method. > > Don't put any emphasis on performance. That is a separate discussion. > > Cheers, > > -- Jim > > A. Line support. > > public Stream lines() > Returns a stream of substrings extracted from this string partitioned by line terminators. Internally, the stream is implemented using a Spliteratorthat extracts one line at a time. The line terminators recognized are \n, \r\n and \r. This method provides versatility for the developer working with multi-line strings. > Example: > > String string = "abc\ndef\nghi"; > Stream stream = string.lines(); > List list = stream.collect(Collectors.toList()); > > Result: > > [abc, def, ghi] > > > Example: > > String string = "abc\ndef\nghi"; > String[] array = string.lines().toArray(String[]::new); > > Result: > > [Ljava.lang.String;@33e5ccce // [abc, def, ghi] > > > Example: > > String string = "abc\ndef\r\nghi\rjkl"; > String platformString = > string.lines().collect(joining(System.lineSeparator())); > > Result: > > abc > def > ghi > jkl > > > Example: > > String string = " abc \n def \n ghi "; > String trimmedString = > string.lines().map(s -> s.trim()).collect(joining("\n")); > > Result: > > abc > def > ghi > > > Example: > > String table = `First Name Surname Phone > Al Albert 555-1111 > Bob Roberts 555-2222 > Cal Calvin 555-3333 > `; > > // Extract headers > String firstLine = table.lines().findFirst?().orElse(""); > List headings = List.of(firstLine.trim().split(`\s{2,}`)); > > // Build stream of maps > Stream> stream = > table.lines().skip(1) > .map(line -> line.trim()) > .filter(line -> !line.isEmpty()) > .map(line -> line.split(`\s{2,}`)) > .map(columns -> { > List values = List.of(columns); > return IntStream.range(0, headings.size()).boxed() > .collect(toMap(headings::get, values::get)); > }); > > // print all "First Name" > stream.map(row -> row.get("First Name")) > .forEach(name -> System.out.println(name)); > > Result: > > Al > Bob > Cal > B. Additions to basic trim methods. In addition to margin methods trimIndent and trimMarkers described below in Section C, it would be worth introducing trimLeft and trimRight to augment the longstanding trim method. A key question is how trimLeft and trimRight should detect whitespace, because different definitions of whitespace exist in the library. > > trim itself uses the simple test less than or equal to the space character, a fast test but not Unicode friendly. > > Character.isWhitespace(codepoint) returns true if codepoint one of the following; > > SPACE_SEPARATOR. > LINE_SEPARATOR. > PARAGRAPH_SEPARATOR. > '\t', U+0009 HORIZONTAL TABULATION. > '\n', U+000A LINE FEED. > '\u000B', U+000B VERTICAL TABULATION. > '\f', U+000C FORM FEED. > '\r', U+000D CARRIAGE RETURN. > '\u001C', U+001C FILE SEPARATOR. > '\u001D', U+001D GROUP SEPARATOR. > '\u001E', U+001E RECORD SEPARATOR. > '\u001F', U+001F UNIT SEPARATOR. > ' ', U+0020 SPACE. > (Note: that non-breaking space (\u00A0) is excluded) > > Character.isSpaceChar(codepoint) returns true if codepoint one of the following; > > SPACE_SEPARATOR. > LINE_SEPARATOR. > PARAGRAPH_SEPARATOR. > ' ', U+0020 SPACE. > '\u00A0', U+00A0 NON-BREAKING SPACE. > That sets up several kinds of whitespace; trim's whitespace (TWS), Character whitespace (CWS) and the union of the two (UWS). TWS is a fast test. CWS is a slow test. UWS is fast for Latin1 and slow-ish for UTF-16. > > We are recommending that trimLeft and trimRight use UWS, leave trim alone to avoid breaking the world and then possibly introduce trimWhitespace that uses UWS. > > public String trim() > Removes characters less than equal to space from the beginning and end of the string. No, change except spec clarification and links to the new trim methods. > Examples: > "".trim(); // "" > " ".trim(); // "" > " abc ".trim(); // "abc" > " \u2028abc ".trim(); // "\u2028abc" > public String trimWhitespace() > Removes whitespace from the beginning and end of the string. > Examples: > > "".trimWhitespace(); // "" > " ".trimWhitespace(); // "" > " abc ".trimWhitespace(); // "abc" > " \u2028abc ".trimWhitespace(); // "abc" > public String trimLeft() > Removes whitespace from the beginning of the string. > Examples: > > "".trimLeft(); // "" > " ".trimLeft(); // "" > " abc ".trimLeft(); // "abc " > public String trimRight() > Removes whitespace from the end of the string. > Examples: > > "".trimRight(); // "" > " ".trimRight(); // "" > " abc ".trimRight(); // " abc" > C. Margin management. With introduction of multi-line Raw String Literals, developers will have to deal with the extraneous spacing introduced by indenting and formatting string bodies. > > Note that for all the methods in this group, if the first line is empty then it is removed and if the last is empty then it is removed. This removal provides a means for developers that use delimiters on separate lines to bracket string bodies. Also note, that all line separators are replaced with \n. > > public String trimIndent() > This method determines a representative line in the string body that has a non-whitespace character closest to the left margin. Once that line has been determined, the number of leading whitespaces is tallied to produce a minimal indent amount. Consequently, the result of the method is a string with the minimal indent amount removed from each line. The first line is unaffected since it is preceded by the open delimiter. The type of whitespace used (spaces or tabs) does not affect the result as long as the developer is consistent with the whitespace used. > Example: > > String x = ` > This is a line > This is a line > This is a line > This is a line > This is a line > `.trimIndent(); > > Result: > > This is a line > This is a line > This is a line > This is a line > This is a line > public String trimMarkers(String leftMarker, String rightMarker) > Each line of the multi-line string is first trimmed. If the trimmed line contains the leftMarker at the beginning of the string then it is removed. Finally, if the line contains the rightMarker at the end of line, it is removed. > Example: > > String x = `|This is a line| > |This is a line| > |This is a line|`.trimMarkers("|", "|"); > Result: > > This is a line > This is a line > This is a line > > Example: > > String x = `>> This is a line >>> This is a line >>> This is a line`.trimMarkers(">> ", ""); > Result: > > This is a line > This is a line > This is a line > D. Escape management. Since Raw String Literals do not interpret Unicode escapes (\unnnn) or escape sequences (\n, \b, etc), we need to provide a scheme for developers who just want multi-line strings but still have escape sequences interpreted. > > public String unescape() throws MalformedEscapeException > Translates each Unicode escape or escape sequence in the string into the character represented by the escape. @jls 3.3, 3.10.6 > Example: > > `abc\u2022def\nghi`.unescape(); > > Result: > > abc?def > ghi > public String unescape(EscapeType... escape) throws MalformedEscapeException > Selectively translates Unicode escape or escape sequence based on the escape type flags provided. > public enum EscapeType { > /** Backslash escape sequences based on section 3.10.6 of the > * The Java™ Language Specification. > * This includes sequences for backspace, horizontal tab, > * line feed, form feed, carriage return, double quote, > * single quote, backslash and octal escape sequences. > */ > BACKSLASH, // > > /** Unicode sequences based on section 3.3 of the > * The Java™ Language Specification. > * This includes sequences in the form {@code \u005Cunnnn}. > */ > UNICODE > } > > > Example: > > `abc\u2022def\nghi`.unescape(EscapeType.BACKSLASH); > > Result: > > abc\u2022def > ghi > > > Example: > > `abc\u2022def\nghi`.unescape(EscapeType.UNICODE); > > Result: > > abc?def\nghi > Conversely, there are circumstances where the inverse is required > > public String escape() > Translates each quote, backslash, non-graphic character or non-ASCII character into an Unicode escape or escape sequence. The method is equivalent to escape(BACKSLASH, UNICODE) . > Example: > > `abc?def > ghi`.escape(); > > Result: > > abc\u2022def\nghi > public String escape(EscapeType... escape) > Selectively translates each quote, backslash, non-graphic character or non-ASCII character into an Unicode escape or escape sequence based on the escape type flags provided. > Example: > > `abc?def > ghi`.escape(EscapeType.BACKSLASH); > > Result: > > abc?def\nghi > > > Example: > > `abc?def > ghi`.escape(EscapeType.UNICODE); > > Result: > > abc\u2022def > ghi > From claes.redestad at oracle.com Tue Mar 20 14:47:26 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 20 Mar 2018 15:47:26 +0100 Subject: RFR: 8199865: Avoid initializing ShortCache in ProxyGenerator Message-ID: <999d6d92-5bb3-49d1-936c-e0cf2d1c4586@oracle.com> Hi, by using Map instead of Map (preserving shortness of values) we can avoid having ProxyGenerator depend on Short$ShortCache, which is a small startup and footprint win (since Integer$IntegerCache is 100% likely to have already been initialized): http://cr.openjdk.java.net/~redestad/8199865/open.00/ Thanks! /Claes From adam.petcher at oracle.com Tue Mar 20 14:50:55 2018 From: adam.petcher at oracle.com (Adam Petcher) Date: Tue, 20 Mar 2018 10:50:55 -0400 Subject: RFR 8181594: Efficient and constant-time modular arithmetic In-Reply-To: References: <7bd6c1ae-4173-4384-fc57-66d1b185ba56@oracle.com> <9021dd99-4ac1-f7a1-fc91-ab0a9cf1685b@oracle.com> Message-ID: <72822337-a8db-1807-6600-8b4cf628bb83@oracle.com> Latest webrev: http://cr.openjdk.java.net/~apetcher/8181594/webrev.02/ Comments inline below. In addition, I also changed the name of IntegerModuloP_Base to IntegerModuloP, and IntegerModuloP to ImmutableIntegerModuloP. On 3/11/2018 12:04 PM, Xuelei Fan wrote: > On 2/26/2018 10:39 AM, Adam Petcher wrote: >> >> On 2/23/2018 12:46 PM, Xuelei Fan wrote: >> >>> ArrayUtil.java: >>> =============== >>> I'm not very sure how widely this utilities will be used in the >>> future. Looks like only BigIntegerModuloP uses this classes.? I may >>> prefer to define private methods for byte array swap in >>> BigIntegerModuloP. >> >> It is also used by XDHPublicKeyImpl (in the XDH code review). XDH >> public keys are represented as BigInteger, and I use the array >> reverse method to convert encoded keys to BigInteger. >> > If it is not widely used by other classes, please have these methods > in the class where is get called.?? The sun.security.util is exported > to other modules as well, we may not want to add stuff into this > package unless it is really necessary. Okay. I put these methods in BigIntegerModuloP and removed the ArrayUtil class. This array reverse code will be duplicated where it is used by XDH public keys (in the other code review). > >>> >>> MutableIntegerModuloP.java >>> ========================== >>> void conditionalSwapWith(MutableIntegerModuloP b, int swap); >>> As the 'swap' parameter can only be 0 or 1, could it be a boolean >>> parameter? >> >> I couldn't come up with a way to implement this without branching >> when the swap parameter is boolean. See >> IntegerPolynomial.conditionalSwap to see how this is implemented in >> arithmetic with an int swap argument. If you (or anyone) can think of >> a way to do this with boolean, let me know. >> >> I added a sentence to the comment above conditionalSwapWith that >> describes why it is an int instead of a boolean. >> > I did not get the point about the need to avoid branching.? Can you > have more details? The goal is to avoid things like if(secret){...}, in order to prevent the secrets from leaking into side channels (mostly timing and cache). The way this method is used by XDH, the swap parameter is a single bit of the private key. By storing this bit as an integer, and then doing the swap using only integer arithmetic, we can avoid branching which may leak the bits of the key. > >>> >>> Except the conditionalSwapWith() method, I did not get the points >>> why we need a mutable version.? Would you please have more >>> description of this requirement? >> >> The comment above the class definition has this sentence: >> >> "This interface can be used to improve performance and avoid the >> allocation of a large number of temporary objects." >> >> Do you need more information than this in the comments? The >> performance motivation is so that a.add(b).multiply(c)... can be done >> without allocating a new buffer for each operation. For example, >> without mutable field elements, an X25519 point multiplication would >> allocate around 4,300 temporary arrays totaling 350,000 bytes. If I >> remember correctly, switching the X25519 implementation to mutable >> field elements reduced the point multiplication time by about half. >> > I see your point.? The benefits is obviously. > > OK, why you need the immutable version then? Sounds like the mutable > version interface is sufficient, including performance. If an > immutable version is really needed, we can have the implementation > making the decision.? Accordingly, the conditionalSwapWith() can be > defined as optional method, if it is not required to be implemented in > immutable implementation. > > It's confusing to me that the immutable and mutable and the base > versions/interfaces mixed together.? It would be nice if we can > simplify the interface a little bit. > > For internal APIs, sometimes we don't want the same quality level as > public APIs.? I think this set of class will be widely used by new EC > curves, ChaCha20/Poly1305, or more in the future.? It would be nice if > we could do it good at the beginning. The mutable version adds the conditional swap as well as mutable versions of many of the basic operations. The XDH implementation uses both the mutable and immutable versions. The immutable version allows me to simplify the client code because I don't have to worry about whether some value has been modified. For example, the XDH code keeps a representation of 0, 1, and the constant that defines the curve as immutable values. So I prefer to have both. It complicates this API a bit, but it allows simpler and more robust code in the client of this API. > >>> >>> >>> IntegerModuloP_Base.java >>> ======================== >>> default byte[] addModPowerTwo(IntegerModuloP_Base b, int len) >>> void addModPowerTwo(IntegerModuloP_Base b, byte[] result); >>> >>> For the first sign of the method names, I thought it is to calculate >>> as "(this + b) ^ 2 mod m". >> >> To be precise, it calculates "((this % p) + (b % p)) % 2^m" (where p >> is the prime that defines the field, and m is the desired length, in >> bits). Note that the addition here is normal integer addition (not >> addition in GF(p)). >> >> This operation is not used in XDH, but it is used in Poly1305 to add >> the AES encryption of a nonce to a field element. So you can get more >> information about this operation by reading the Poly1305 paper/RFC. >> > I was not meant to say the function of the method.? I meant that the > method name is a little bit misleading, not very straightforward to me. > >>> Besides, what's the benefits of the two methods?? Could we just use: >>> ????? this.add(b).asByteArray() >> >> No, because that would calculate "((this + b) mod p) mod 2^m". The >> value of (this + b) can be larger than p, so this would not produce >> the desired result. >> ?>> >>> I guess, but not very sure, it is for constant time calculation. If >>> the function is required, could it be renamed as: >>> >>> ????? // the result is inside of the size range >>> ????? IntegerModuloP addModSize(IntegerModuloP_Base b, int size) >>> Or >>> ????? // the result is wrapped if outside of the size range >>> ????? IntegerModuloP addOnWrap(IntegerModuloP_Base b, int size) >>> >>> and the use may look like: >>> ????? this.addModSize(b, size).asByteArray() >>> >> >> Any attempt to perform the addition in IntegerModuloP and then pull >> out the byte array will not work. > Does it mean if I perform a addition, and cannot get the byte array in > the following step? > ???? that = this.add(b); > ???? byte[] bs = that.asByteArray();?????????? // does not work? > or > ???? byte[] bs = that.asByteArray(length);??? // does not work? > or > ???? byte[] bs = that.asByteArray(byteArray); // does not work? > >> This class can only represent field elements, so the sum would be in >> the field, which is not what we want. >> > I did not get the point.? If getting an add result, the add is done > (sum in the field).? Did you have an example that pulling out the byte > array will not work? Say we are in the field of integers modulo 269, and the final result of some computation will be stored in a single byte. In this example, we discard information when we truncate to the byte array. This may seem strange, but it is exactly what Poly1305 does. Now say we want to add x with itself, and x has the value 260. // x.add(x) has value 251 byte[] result = new byte[1]; x.add(x).asByteArray(result); // result has value 251 x.addModPowerTwo(x, result) // result has value 8 The difference between the two statements above is that the first one does a reduction mod 269 after the addition (and before converting to a byte array), while the second one does not. I can't split addModPowerTwo into two method calls without also adding another type for integers modulo a possibly-non-prime, and I didn't think it was worth the effort. I don't have a problem with renaming the method if you think this will make it more clear. Let me know which name you prefer. The name addModSize is probably okay, although technically we are reducing mod 2^size, so the name might be slightly misleading. Maybe something a little less precise like addToSize? From xuelei.fan at oracle.com Tue Mar 20 15:22:47 2018 From: xuelei.fan at oracle.com (Xuelei Fan) Date: Tue, 20 Mar 2018 08:22:47 -0700 Subject: RFR 8181594: Efficient and constant-time modular arithmetic In-Reply-To: <72822337-a8db-1807-6600-8b4cf628bb83@oracle.com> References: <7bd6c1ae-4173-4384-fc57-66d1b185ba56@oracle.com> <9021dd99-4ac1-f7a1-fc91-ab0a9cf1685b@oracle.com> <72822337-a8db-1807-6600-8b4cf628bb83@oracle.com> Message-ID: <241c0fc0-51cc-6e8b-b78a-7f2e6d33fdc8@oracle.com> I have no other comments. Thanks, Xuelei On 3/20/2018 7:50 AM, Adam Petcher wrote: > Latest webrev: http://cr.openjdk.java.net/~apetcher/8181594/webrev.02/ > > Comments inline below. > > In addition, I also changed the name of IntegerModuloP_Base to > IntegerModuloP, and IntegerModuloP to ImmutableIntegerModuloP. > > > On 3/11/2018 12:04 PM, Xuelei Fan wrote: >> On 2/26/2018 10:39 AM, Adam Petcher wrote: >>> >>> On 2/23/2018 12:46 PM, Xuelei Fan wrote: >>> >>>> ArrayUtil.java: >>>> =============== >>>> I'm not very sure how widely this utilities will be used in the >>>> future. Looks like only BigIntegerModuloP uses this classes.? I may >>>> prefer to define private methods for byte array swap in >>>> BigIntegerModuloP. >>> >>> It is also used by XDHPublicKeyImpl (in the XDH code review). XDH >>> public keys are represented as BigInteger, and I use the array >>> reverse method to convert encoded keys to BigInteger. >>> >> If it is not widely used by other classes, please have these methods >> in the class where is get called.?? The sun.security.util is exported >> to other modules as well, we may not want to add stuff into this >> package unless it is really necessary. > > Okay. I put these methods in BigIntegerModuloP and removed the ArrayUtil > class. This array reverse code will be duplicated where it is used by > XDH public keys (in the other code review). > >> >>>> >>>> MutableIntegerModuloP.java >>>> ========================== >>>> void conditionalSwapWith(MutableIntegerModuloP b, int swap); >>>> As the 'swap' parameter can only be 0 or 1, could it be a boolean >>>> parameter? >>> >>> I couldn't come up with a way to implement this without branching >>> when the swap parameter is boolean. See >>> IntegerPolynomial.conditionalSwap to see how this is implemented in >>> arithmetic with an int swap argument. If you (or anyone) can think of >>> a way to do this with boolean, let me know. >>> >>> I added a sentence to the comment above conditionalSwapWith that >>> describes why it is an int instead of a boolean. >>> >> I did not get the point about the need to avoid branching.? Can you >> have more details? > > The goal is to avoid things like if(secret){...}, in order to prevent > the secrets from leaking into side channels (mostly timing and cache). > The way this method is used by XDH, the swap parameter is a single bit > of the private key. By storing this bit as an integer, and then doing > the swap using only integer arithmetic, we can avoid branching which may > leak the bits of the key. > >> >>>> >>>> Except the conditionalSwapWith() method, I did not get the points >>>> why we need a mutable version.? Would you please have more >>>> description of this requirement? >>> >>> The comment above the class definition has this sentence: >>> >>> "This interface can be used to improve performance and avoid the >>> allocation of a large number of temporary objects." >>> >>> Do you need more information than this in the comments? The >>> performance motivation is so that a.add(b).multiply(c)... can be done >>> without allocating a new buffer for each operation. For example, >>> without mutable field elements, an X25519 point multiplication would >>> allocate around 4,300 temporary arrays totaling 350,000 bytes. If I >>> remember correctly, switching the X25519 implementation to mutable >>> field elements reduced the point multiplication time by about half. >>> >> I see your point.? The benefits is obviously. >> >> OK, why you need the immutable version then? Sounds like the mutable >> version interface is sufficient, including performance. If an >> immutable version is really needed, we can have the implementation >> making the decision.? Accordingly, the conditionalSwapWith() can be >> defined as optional method, if it is not required to be implemented in >> immutable implementation. >> >> It's confusing to me that the immutable and mutable and the base >> versions/interfaces mixed together.? It would be nice if we can >> simplify the interface a little bit. >> >> For internal APIs, sometimes we don't want the same quality level as >> public APIs.? I think this set of class will be widely used by new EC >> curves, ChaCha20/Poly1305, or more in the future.? It would be nice if >> we could do it good at the beginning. > > The mutable version adds the conditional swap as well as mutable > versions of many of the basic operations. The XDH implementation uses > both the mutable and immutable versions. The immutable version allows me > to simplify the client code because I don't have to worry about whether > some value has been modified. For example, the XDH code keeps a > representation of 0, 1, and the constant that defines the curve as > immutable values. > > So I prefer to have both. It complicates this API a bit, but it allows > simpler and more robust code in the client of this API. > >> >>>> >>>> >>>> IntegerModuloP_Base.java >>>> ======================== >>>> default byte[] addModPowerTwo(IntegerModuloP_Base b, int len) >>>> void addModPowerTwo(IntegerModuloP_Base b, byte[] result); >>>> >>>> For the first sign of the method names, I thought it is to calculate >>>> as "(this + b) ^ 2 mod m". >>> >>> To be precise, it calculates "((this % p) + (b % p)) % 2^m" (where p >>> is the prime that defines the field, and m is the desired length, in >>> bits). Note that the addition here is normal integer addition (not >>> addition in GF(p)). >>> >>> This operation is not used in XDH, but it is used in Poly1305 to add >>> the AES encryption of a nonce to a field element. So you can get more >>> information about this operation by reading the Poly1305 paper/RFC. >>> >> I was not meant to say the function of the method.? I meant that the >> method name is a little bit misleading, not very straightforward to me. >> >>>> Besides, what's the benefits of the two methods?? Could we just use: >>>> ????? this.add(b).asByteArray() >>> >>> No, because that would calculate "((this + b) mod p) mod 2^m". The >>> value of (this + b) can be larger than p, so this would not produce >>> the desired result. >>> ?>> >>>> I guess, but not very sure, it is for constant time calculation. If >>>> the function is required, could it be renamed as: >>>> >>>> ????? // the result is inside of the size range >>>> ????? IntegerModuloP addModSize(IntegerModuloP_Base b, int size) >>>> Or >>>> ????? // the result is wrapped if outside of the size range >>>> ????? IntegerModuloP addOnWrap(IntegerModuloP_Base b, int size) >>>> >>>> and the use may look like: >>>> ????? this.addModSize(b, size).asByteArray() >>>> >>> >>> Any attempt to perform the addition in IntegerModuloP and then pull >>> out the byte array will not work. >> Does it mean if I perform a addition, and cannot get the byte array in >> the following step? >> ???? that = this.add(b); >> ???? byte[] bs = that.asByteArray();?????????? // does not work? >> or >> ???? byte[] bs = that.asByteArray(length);??? // does not work? >> or >> ???? byte[] bs = that.asByteArray(byteArray); // does not work? >> >>> This class can only represent field elements, so the sum would be in >>> the field, which is not what we want. >>> >> I did not get the point.? If getting an add result, the add is done >> (sum in the field).? Did you have an example that pulling out the byte >> array will not work? > > Say we are in the field of integers modulo 269, and the final result of > some computation will be stored in a single byte. In this example, we > discard information when we truncate to the byte array. This may seem > strange, but it is exactly what Poly1305 does. Now say we want to add x > with itself, and x has the value 260. > > // x.add(x) has value 251 > byte[] result = new byte[1]; > x.add(x).asByteArray(result); // result has value 251 > x.addModPowerTwo(x, result) // result has value 8 > > The difference between the two statements above is that the first one > does a reduction mod 269 after the addition (and before converting to a > byte array), while the second one does not. I can't split addModPowerTwo > into two method calls without also adding another type for integers > modulo a possibly-non-prime, and I didn't think it was worth the effort. > > I don't have a problem with renaming the method if you think this will > make it more clear. Let me know which name you prefer. The name > addModSize is probably okay, although technically we are reducing mod > 2^size, so the name might be slightly misleading. Maybe something a > little less precise like addToSize? > From mandy.chung at oracle.com Tue Mar 20 16:36:09 2018 From: mandy.chung at oracle.com (mandy chung) Date: Tue, 20 Mar 2018 09:36:09 -0700 Subject: RFR: 8199865: Avoid initializing ShortCache in ProxyGenerator In-Reply-To: <999d6d92-5bb3-49d1-936c-e0cf2d1c4586@oracle.com> References: <999d6d92-5bb3-49d1-936c-e0cf2d1c4586@oracle.com> Message-ID: <020a69d0-3a8f-38a9-f2e4-ba82244deba9@oracle.com> Looks fine.? Nice small perf gain. Mandy On 3/20/18 7:47 AM, Claes Redestad wrote: > Hi, > > by using Map instead of Map > (preserving shortness of values) we can avoid having ProxyGenerator > depend on Short$ShortCache, which is a small startup and footprint win > (since Integer$IntegerCache is 100% likely to have already been > initialized): > > http://cr.openjdk.java.net/~redestad/8199865/open.00/ > > Thanks! > > /Claes > From paul.sandoz at oracle.com Tue Mar 20 17:12:23 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 20 Mar 2018 10:12:23 -0700 Subject: RFR 8199773 (bf) XXXBuffer:compareTo method is not working as expected Message-ID: <0C0EF738-CAC2-48A2-8651-CA7A37883EBF@oracle.com> Hi, Please review this simple fix for a silly mistake when calculating the result of comparing two buffers: http://cr.openjdk.java.net/~psandoz/jdk/JDK-8199773-buffer-compare-value/webrev/ Paul. From mandy.chung at oracle.com Tue Mar 20 17:12:59 2018 From: mandy.chung at oracle.com (mandy chung) Date: Tue, 20 Mar 2018 10:12:59 -0700 Subject: RFR: 8199862: Examine ProxyBuilder::referencedTypes startup cost In-Reply-To: <5fb829e1-495e-824c-dfc8-7c10217f6233@oracle.com> References: <5fb829e1-495e-824c-dfc8-7c10217f6233@oracle.com> Message-ID: On 3/20/18 6:00 AM, Claes Redestad wrote: > Hi, > > by desugaring Stream+lambda usage in > Proxy$ProxyBuilder::referencedTypes - and carefully avoiding cloning > of parameter and exception type arrays - we can significantly reduce > the startup overhead of doing annotation processing in a set of > typical applications. > > Webrev: http://cr.openjdk.java.net/~redestad/8199862/open.00/ > > Bug: https://bugs.openjdk.java.net/browse/JDK-8199862 This looks fine.?? Thanks for doing it. ? I started looking into the ProxyBuilder performance for annotations which creates proxies for one single interface but didn't get back to it. Mandy From ivan.gerasimov at oracle.com Tue Mar 20 17:20:46 2018 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 20 Mar 2018 10:20:46 -0700 Subject: RFR 8199843 : Optimize Integer/Long.highestOneBit() In-Reply-To: <1f0c20c9-4618-79fd-9c3b-be97504f65dc@gmail.com> References: <1f0c20c9-4618-79fd-9c3b-be97504f65dc@gmail.com> Message-ID: <012cec3f-aa82-d76f-4ec8-bf83e7c049c0@oracle.com> Hi Peter! On 3/20/18 6:05 AM, Peter Levart wrote: > Hi Ivan, > > What about branch-less variant? > > public static int highestOneBit(int i) { > return i & (MIN_VALUE >>> numberOfLeadingZeros(i)); > } > Nice variant! I tried to run it, but the numbers are non-distinguishable for non-zero arguments. And my variant performs slightly better with zero argument. So, I think it's reasonable to keep the variant with the ternary operator. Here are the results: Benchmark (arg) Mode Cnt Score Error Units MyBenchmark.int_testMethod_00_base 0 thrpt 35 352.509 ? 20.796 ops/us MyBenchmark.int_testMethod_00_base 42 thrpt 35 362.955 ? 7.278 ops/us MyBenchmark.int_testMethod_00_base -42 thrpt 35 366.084 ? 6.770 ops/us MyBenchmark.int_testMethod_01_org 0 thrpt 35 249.340 ? 1.981 ops/us MyBenchmark.int_testMethod_01_org 42 thrpt 35 249.007 ? 2.005 ops/us MyBenchmark.int_testMethod_01_org -42 thrpt 35 241.866 ? 4.759 ops/us MyBenchmark.int_testMethod_02_new 0 thrpt 35 328.389 ? 5.883 ops/us MyBenchmark.int_testMethod_02_new 42 thrpt 35 306.381 ? 5.505 ops/us MyBenchmark.int_testMethod_02_new -42 thrpt 35 300.328 ? 5.644 ops/us MyBenchmark.int_testMethod_03_and 0 thrpt 35 301.559 ? 5.453 ops/us MyBenchmark.int_testMethod_03_and 42 thrpt 35 299.694 ? 5.000 ops/us MyBenchmark.int_testMethod_03_and -42 thrpt 35 301.505 ? 5.664 ops/us The benchmark updated in place: http://cr.openjdk.java.net/~igerasim/8199843/00/MyBenchmark.java With kind regards Ivan > Would it be any better for call sites that vary 0 and non-0 argument? > > Regards, Peter > > On 03/20/2018 09:58 AM, Ivan Gerasimov wrote: >> Hello! >> >> The hightestOneBit function doesn't have an intrinsic and is >> currently implemented with a dozen of instructions. >> Alternatively, it could be implemented as MIN_VALUE >>> >> numberOfLeadingZeros(i), which works for all integers but zero. >> The former function gets intrisified by hotspot, which results in >> +27% of throughput (see the jmh results below). >> >> Would you please help review this simple fix? >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8199843 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8199843/00/webrev/ >> Benchmark: >> http://cr.openjdk.java.net/~igerasim/8199843/00/MyBenchmark.java >> >> Benchmark results: >> >> Benchmark (arg) Mode Cnt Score Error Units >> MyBenchmark.int_testMethod_new 0 thrpt 35 323430664.593 ? >> 7492044.171 ops/s >> MyBenchmark.int_testMethod_new 42 thrpt 35 298526237.078 ? >> 5978291.689 ops/s >> MyBenchmark.int_testMethod_new -42 thrpt 35 302903562.073 ? >> 7984723.721 ops/s >> MyBenchmark.int_testMethod_org 0 thrpt 35 236245042.891 ? >> 3635990.596 ops/s >> MyBenchmark.int_testMethod_org 42 thrpt 35 237903410.753 ? >> 3437684.390 ops/s >> MyBenchmark.int_testMethod_org -42 thrpt 35 238472580.618 ? >> 2654886.010 ops/s >> MyBenchmark.long_testMethod_new 0 thrpt 35 282646114.501 ? >> 48028366.305 ops/s >> MyBenchmark.long_testMethod_new 42 thrpt 35 282382228.405 ? >> 5781529.307 ops/s >> MyBenchmark.long_testMethod_new -42 thrpt 35 276724858.286 ? >> 6529561.227 ops/s >> MyBenchmark.long_testMethod_org 0 thrpt 35 198500211.972 ? >> 15096862.367 ops/s >> MyBenchmark.long_testMethod_org 42 thrpt 35 215854630.194 ? >> 3112930.563 ops/s >> MyBenchmark.long_testMethod_org -42 thrpt 35 217992805.521 ? >> 2622877.082 ops/s >> >> Thanks in advance! >> > -- With kind regards, Ivan Gerasimov From ivan.gerasimov at oracle.com Tue Mar 20 17:24:00 2018 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Tue, 20 Mar 2018 10:24:00 -0700 Subject: RFR 8199843 : Optimize Integer/Long.highestOneBit() In-Reply-To: References: Message-ID: <3650b830-07be-09c1-57f2-4ae2cebf0490@oracle.com> Hi Claes! On 3/20/18 2:46 AM, Claes Redestad wrote: > Hi, > > On 2018-03-20 09:58, Ivan Gerasimov wrote: >> Hello! >> >> The hightestOneBit function doesn't have an intrinsic and is >> currently implemented with a dozen of instructions. >> Alternatively, it could be implemented as MIN_VALUE >>> >> numberOfLeadingZeros(i), which works for all integers but zero. >> The former function gets intrisified by hotspot, which results in >> +27% of throughput (see the jmh results below). >> >> Would you please help review this simple fix? >> >> BUGURL: https://bugs.openjdk.java.net/browse/JDK-8199843 >> WEBREV: http://cr.openjdk.java.net/~igerasim/8199843/00/webrev/ > > nice optimization! > >> Benchmark: >> http://cr.openjdk.java.net/~igerasim/8199843/00/MyBenchmark.java >> >> Benchmark results: >> >> Benchmark (arg) Mode Cnt Score Error Units >> MyBenchmark.int_testMethod_new 0 thrpt 35 323430664.593 ? >> 7492044.171 ops/s >> MyBenchmark.int_testMethod_new 42 thrpt 35 298526237.078 ? >> 5978291.689 ops/s >> MyBenchmark.int_testMethod_new -42 thrpt 35 302903562.073 ? >> 7984723.721 ops/s >> MyBenchmark.int_testMethod_org 0 thrpt 35 236245042.891 ? >> 3635990.596 ops/s >> MyBenchmark.int_testMethod_org 42 thrpt 35 237903410.753 ? >> 3437684.390 ops/s >> MyBenchmark.int_testMethod_org -42 thrpt 35 238472580.618 ? >> 2654886.010 ops/s >> MyBenchmark.long_testMethod_new 0 thrpt 35 282646114.501 ? >> 48028366.305 ops/s >> MyBenchmark.long_testMethod_new 42 thrpt 35 282382228.405 ? >> 5781529.307 ops/s >> MyBenchmark.long_testMethod_new -42 thrpt 35 276724858.286 ? >> 6529561.227 ops/s >> MyBenchmark.long_testMethod_org 0 thrpt 35 198500211.972 ? >> 15096862.367 ops/s >> MyBenchmark.long_testMethod_org 42 thrpt 35 215854630.194 ? >> 3112930.563 ops/s >> MyBenchmark.long_testMethod_org -42 thrpt 35 217992805.521 ? >> 2622877.082 ops/s > > To nitpick a bit: > > Please run with some appropriate time unit, e.g., "-tu us" to make > results more human readable. > And where are the baseline results? :-) > > It'd also be nice to verify we don't regress too much in case there's > no intrinsic, i.e., test with the > intrinsic disabled. > Good point! Here are results for Integer.highestOneBit with the intrinsic of numberOfLeadingZeros being disabled: Benchmark (arg) Mode Cnt Score Error Units MyBenchmark.int_testMethod_00_base 0 thrpt 35 324.369 ? 15.437 ops/us MyBenchmark.int_testMethod_00_base 42 thrpt 35 307.741 ? 29.623 ops/us MyBenchmark.int_testMethod_00_base -42 thrpt 35 324.563 ? 25.039 ops/us MyBenchmark.int_testMethod_01_org 0 thrpt 35 231.276 ? 8.392 ops/us MyBenchmark.int_testMethod_01_org 42 thrpt 35 230.466 ? 10.557 ops/us MyBenchmark.int_testMethod_01_org -42 thrpt 35 238.579 ? 8.257 ops/us MyBenchmark.int_testMethod_02_new 0 thrpt 35 326.752 ? 18.400 ops/us MyBenchmark.int_testMethod_02_new 42 thrpt 35 200.604 ? 8.139 ops/us MyBenchmark.int_testMethod_02_new -42 thrpt 35 212.313 ? 21.284 ops/us Base case just returns the argument, thus shows the maximum possible upper bound of the throughput. With non-zero values the new function performs 11-13% worse. I guess it's acceptable? With kind regards, Ivan > Thanks! > > /Claes > -- With kind regards, Ivan Gerasimov From Alan.Bateman at oracle.com Tue Mar 20 17:24:50 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 20 Mar 2018 17:24:50 +0000 Subject: RFR 8199773 (bf) XXXBuffer:compareTo method is not working as expected In-Reply-To: <0C0EF738-CAC2-48A2-8651-CA7A37883EBF@oracle.com> References: <0C0EF738-CAC2-48A2-8651-CA7A37883EBF@oracle.com> Message-ID: On 20/03/2018 17:12, Paul Sandoz wrote: > Hi, > > Please review this simple fix for a silly mistake when calculating the result of comparing two buffers: > > http://cr.openjdk.java.net/~psandoz/jdk/JDK-8199773-buffer-compare-value/webrev/ > Looks good to me, we probably should have caught this in the core review. -Alan From nishit.jain at oracle.com Tue Mar 20 17:37:26 2018 From: nishit.jain at oracle.com (Nishit Jain) Date: Tue, 20 Mar 2018 23:07:26 +0530 Subject: [11] RFR JDK-8196399, JDK-8199672: Formatting a decimal using locale-specific grouping..., ClassCastException is thrown... Message-ID: <9f714734-ddc5-22f8-0acf-2872689f7e77@oracle.com> Hi, Please review the fix for JDK-8196399 & JDK-8199672 Bug: https://bugs.openjdk.java.net/browse/JDK-8196399 https://bugs.openjdk.java.net/browse/JDK-8199672 Webrev: http://cr.openjdk.java.net/~nishjain/8196399_8199672/webrev.01/ Issue: 8196399: Locales such as hy_AM do not use grouping, but specify a grouping separator. Formatter throws ArithmeticException / by zero while identifying the position, as the grouping size is zero. 8199672: Unconditional casting of NumberFormat instance to DecimalFormat Fix: 8196399: Reset the grouping separator to null character, so that grouping separator position identification is skipped. 8199672: Check if the instance returned is DecimalFormat; else, use DecimalFormat constructor to obtain the instance. Regards, Nishit Jain From paul.sandoz at oracle.com Tue Mar 20 17:45:08 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 20 Mar 2018 10:45:08 -0700 Subject: RFR 8199773 (bf) XXXBuffer:compareTo method is not working as expected In-Reply-To: References: <0C0EF738-CAC2-48A2-8651-CA7A37883EBF@oracle.com> Message-ID: <1CDE8E22-1311-4C05-9C4B-E9D86A7BE795@oracle.com> > On Mar 20, 2018, at 10:24 AM, Alan Bateman wrote: > > > > On 20/03/2018 17:12, Paul Sandoz wrote: >> Hi, >> >> Please review this simple fix for a silly mistake when calculating the result of comparing two buffers: >> >> http://cr.openjdk.java.net/~psandoz/jdk/JDK-8199773-buffer-compare-value/webrev/ >> > Looks good to me, we probably should have caught this in the core review. > Thanks. Hard to spot. I am glad the JCK tests found it. I should have realized the test needed to do pos/limit as well as pos/limit/slice (the latter caught bugs early in the development process). Paul. From huizhe.wang at oracle.com Tue Mar 20 17:57:18 2018 From: huizhe.wang at oracle.com (Joe Wang) Date: Tue, 20 Mar 2018 10:57:18 -0700 Subject: RFR (JDK11/java.xml) 8199792: Wrong license header in XMLLimitAnalyzer.java Message-ID: <5AB14B7E.2010603@oracle.com> Hi, Please help review a quick fix for a license header. Note that I didn't change the copyright year since there's no code change, and also I'd like to maintain the same copyright year as the other classes that were added together with this class. JBS: https://bugs.openjdk.java.net/browse/JDK-8199792 webrev: http://cr.openjdk.java.net/~joehw/jdk11/8199792/webrev/ Thanks, Joe From lance.andersen at oracle.com Tue Mar 20 18:00:43 2018 From: lance.andersen at oracle.com (Lance Andersen) Date: Tue, 20 Mar 2018 14:00:43 -0400 Subject: RFR (JDK11/java.xml) 8199792: Wrong license header in XMLLimitAnalyzer.java In-Reply-To: <5AB14B7E.2010603@oracle.com> References: <5AB14B7E.2010603@oracle.com> Message-ID: <88178D7A-6E02-4390-A575-ED0446FE44D7@oracle.com> +1 > On Mar 20, 2018, at 1:57 PM, Joe Wang wrote: > > Hi, > > Please help review a quick fix for a license header. Note that I didn't change the copyright year since there's no code change, and also I'd like to maintain the same copyright year as the other classes that were added together with this class. > > JBS: https://bugs.openjdk.java.net/browse/JDK-8199792 > webrev: http://cr.openjdk.java.net/~joehw/jdk11/8199792/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 naoto.sato at oracle.com Tue Mar 20 17:58:43 2018 From: naoto.sato at oracle.com (Naoto Sato) Date: Tue, 20 Mar 2018 10:58:43 -0700 Subject: [11] RFR JDK-8196399, JDK-8199672: Formatting a decimal using locale-specific grouping..., ClassCastException is thrown... In-Reply-To: <9f714734-ddc5-22f8-0acf-2872689f7e77@oracle.com> References: <9f714734-ddc5-22f8-0acf-2872689f7e77@oracle.com> Message-ID: <5a9fd28d-e345-fe13-09c2-b76cf9594ce0@oracle.com> Looks good to me. Naoto On 3/20/18 10:37 AM, Nishit Jain wrote: > Hi, > > Please review the fix for JDK-8196399 & JDK-8199672 > > Bug: https://bugs.openjdk.java.net/browse/JDK-8196399 > https://bugs.openjdk.java.net/browse/JDK-8199672 > Webrev: http://cr.openjdk.java.net/~nishjain/8196399_8199672/webrev.01/ > > Issue: > 8196399: Locales such as hy_AM do not use grouping, but specify a > grouping separator. Formatter throws ArithmeticException / by zero while > identifying the position, as the grouping size is zero. > 8199672: Unconditional casting of NumberFormat instance to DecimalFormat > > Fix: > 8196399: Reset the grouping separator to null character, so that > grouping separator position identification is skipped. > 8199672: Check if the instance returned is DecimalFormat; else, use > DecimalFormat constructor to obtain the instance. > > > Regards, > Nishit Jain From huizhe.wang at oracle.com Tue Mar 20 18:25:35 2018 From: huizhe.wang at oracle.com (Joe Wang) Date: Tue, 20 Mar 2018 11:25:35 -0700 Subject: RFR (JDK11/java.xml) 8199792: Wrong license header in XMLLimitAnalyzer.java In-Reply-To: <88178D7A-6E02-4390-A575-ED0446FE44D7@oracle.com> References: <5AB14B7E.2010603@oracle.com> <88178D7A-6E02-4390-A575-ED0446FE44D7@oracle.com> Message-ID: Thanks! On 3/20/2018 11:00 AM, Lance Andersen wrote: > +1 >> On Mar 20, 2018, at 1:57 PM, Joe Wang > > wrote: >> >> Hi, >> >> Please help review a quick fix for a license header. Note that I >> didn't change the copyright year since there's no code change, and >> also I'd like to maintain the same copyright year as the other >> classes that were added together with this class. >> >> JBS: https://bugs.openjdk.java.net/browse/JDK-8199792 >> webrev: http://cr.openjdk.java.net/~joehw/jdk11/8199792/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 brian.burkhalter at oracle.com Tue Mar 20 21:13:40 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Tue, 20 Mar 2018 14:13:40 -0700 Subject: RFR 8199843 : Optimize Integer/Long.highestOneBit() In-Reply-To: <3650b830-07be-09c1-57f2-4ae2cebf0490@oracle.com> References: <3650b830-07be-09c1-57f2-4ae2cebf0490@oracle.com> Message-ID: <63FB828C-40C2-4087-AB71-8F1291278E89@oracle.com> Hi Ivan, On Mar 20, 2018, at 10:24 AM, Ivan Gerasimov wrote: > With non-zero values the new function performs 11-13% worse. > I guess it's acceptable? If we are mostly concerned about the intrinsified cases then I would think that this would be acceptable. Brian From roger.riggs at oracle.com Tue Mar 20 21:28:08 2018 From: roger.riggs at oracle.com (Roger Riggs) Date: Tue, 20 Mar 2018 17:28:08 -0400 Subject: RFR (JDK11/java.xml) 8199792: Wrong license header in XMLLimitAnalyzer.java In-Reply-To: <5AB14B7E.2010603@oracle.com> References: <5AB14B7E.2010603@oracle.com> Message-ID: <287c420d-0453-1774-bb17-4c8d2ebae84e@oracle.com> Hi Joe, Looks fine Roger On 3/20/18 1:57 PM, Joe Wang wrote: > Hi, > > Please help review a quick fix for a license header. Note that I > didn't change the copyright year since there's no code change, and > also I'd like to maintain the same copyright year as the other classes > that were added together with this class. > > JBS: https://bugs.openjdk.java.net/browse/JDK-8199792 > webrev: http://cr.openjdk.java.net/~joehw/jdk11/8199792/webrev/ > > Thanks, > Joe From irogers at google.com Wed Mar 21 02:07:30 2018 From: irogers at google.com (Ian Rogers) Date: Wed, 21 Mar 2018 02:07:30 +0000 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: <1521451687.2323.5.camel@oracle.com> References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> <5A9D8F33.5060500@oracle.com> <5A9DAC84.906@oracle.com> <5A9DAE87.8020801@oracle.com> <1521102348.2448.25.camel@oracle.com> <23639144-5217-4A0F-930C-EF24B4976544@oracle.com> <1521451687.2323.5.camel@oracle.com> Message-ID: Thanks, via bugreport.java.com I filed bugs/RFEs with ids 9053047, 9053048, 9053049, 9053050 and 9053051. Ian On Mon, Mar 19, 2018 at 2:28 AM Thomas Schatzl wrote: > Hi, > > On Fri, 2018-03-16 at 17:19 +0000, Ian Rogers wrote: > > Thanks Paul, very interesting. > > > > On Fri, Mar 16, 2018 at 9:21 AM Paul Sandoz > > wrote: > > > Hi Ian, Thomas, > > > > > > [...] > > > (This is also something we need to consider if we modify buffers to > > > support capacities larger than Integer.MAX_VALUE. Also connects > > > with Project Panama.) > > > > > > If Thomas has not done so or does not plan to i can log an issue > > > for you. > > > > > > > That'd be great. I wonder if identifying more TTSP issues should also > > be a bug. Its interesting to observe that overlooking TTSP in C2 > > motivated the Unsafe.copyMemory change permitting a fresh TTSP issue. > > If TTSP is a 1st class issue then maybe we can deprecate JNI critical > > regions to support that effort :-) > > Please log an issue. I am still a bit unsure what and how many issues > should be filed. > > @Ian: at bugreports.oracle.com everyone may file bug reports without > the need for an account. > It will take some time until they show up in Jira due to vetting, but > if you have a good case, and can e.g. link to the mailing list, this > should be painless. > > Thanks, > Thomas > > From james.laskey at oracle.com Wed Mar 21 14:51:11 2018 From: james.laskey at oracle.com (Jim Laskey) Date: Wed, 21 Mar 2018 11:51:11 -0300 Subject: Raw String Literal Library Support In-Reply-To: <07A1E569-20BC-42F8-9756-83D5A84A4BA0@oracle.com> References: <07A1E569-20BC-42F8-9756-83D5A84A4BA0@oracle.com> Message-ID: <9E664743-56E4-433B-AE96-3E2D5353A38C@oracle.com> One more change set. trimIndent -> stripIndent trimMarkers -> stripMarkers > On Mar 20, 2018, at 10:35 AM, Jim Laskey wrote: > > Summary. > > A. Line support. > > - Supporting a mix of line terminators `\n|\r\n|\r` is already a well established pattern in language parsers, in the JDK (ex. see java.nio.file.FileChannelLinesSpliterator) and RegEx (ex. see `\R`). The performance difference between checking one vs the three is negligible. > > - Yes, Stream stream = Pattern.compile("\n|\r\n|\r").splitAsStream(string); is very useful (Spliterators rule), but is cumbersome in this expected to be common use case. Only so-so streamy. :-) > > - BufferedRead.lines() vs. String.lines() is a tricky discussion. It comes down to whether the new line is a terminator or a separator. In the i/o case, it seems terminator is the right answer. A well formed text file will have a new line at the end of every line. However, I think you?ll find when people work with multi-line strings they think of new line as a separator. Hence, the common use of split(?\n?) and ??.split(?\n?).length == 1. Indentation, the position of closing delimiter and margin trimming makes that last line very fluid. > > What clinches the deal is that string.lines().collect(joining(?\n?)).equals(string). I?ll ensure both versions of lines() have the difference well javadocumented. > > - The current Spliterator implementation makes String.lines().toArray(String[]::new) an order of magnitude faster than split(`\n|\r\n|\r`). That?s why I implemented it for margin management. Faster still if no collection/array is constructed. > > BTW: split(`\R`) is 2x-3x faster than split(`\n|\r\n|\r`). Nice. > > B. Additions to basic trim methods. > > - Revamped to become strip, stripLeading, stripTrailing using Character.isWhiteSpace(codepoint) as the test (optimized using ch == ? ' || ch == ?\t? || Character.isWhiteSpace(ch)). > > - No strong feeling about it, but String.trim() could be recommended for deprecation. > > C. Margin management. > > - String.trimMarkers() as a default to String.trimMarkers(?|?, ?|?) is reasonable. Will put it in the CSR for broader discussion. > > - Re use of patterns. I think the Stream lines() method will make it very easy enough to create custom trim margin lambdas. > > D. Escape management. > > - Good > > Cheers, > > ? Jim > > > > >> On Mar 13, 2018, at 10:47 AM, Jim Laskey wrote: >> >> With the announcement of JEP 326 Raw String Literals, we would like to open up a discussion with regards to RSL library support. Below are several implemented String methods that are believed to be appropriate. Please comment on those mentioned below including recommending alternate names or signatures. Additional methods can be considered if warranted, but as always, the bar for inclusion in String is high. >> >> You should keep a couple things in mind when reviewing these methods. >> >> Methods should be applicable to all strings, not just Raw String Literals. >> >> The number of additional methods should be minimized, not adding every possible method. >> >> Don't put any emphasis on performance. That is a separate discussion. >> >> Cheers, >> >> -- Jim >> >> A. Line support. >> >> public Stream lines() >> Returns a stream of substrings extracted from this string partitioned by line terminators. Internally, the stream is implemented using a Spliteratorthat extracts one line at a time. The line terminators recognized are \n, \r\n and \r. This method provides versatility for the developer working with multi-line strings. >> Example: >> >> String string = "abc\ndef\nghi"; >> Stream stream = string.lines(); >> List list = stream.collect(Collectors.toList()); >> >> Result: >> >> [abc, def, ghi] >> >> >> Example: >> >> String string = "abc\ndef\nghi"; >> String[] array = string.lines().toArray(String[]::new); >> >> Result: >> >> [Ljava.lang.String;@33e5ccce // [abc, def, ghi] >> >> >> Example: >> >> String string = "abc\ndef\r\nghi\rjkl"; >> String platformString = >> string.lines().collect(joining(System.lineSeparator())); >> >> Result: >> >> abc >> def >> ghi >> jkl >> >> >> Example: >> >> String string = " abc \n def \n ghi "; >> String trimmedString = >> string.lines().map(s -> s.trim()).collect(joining("\n")); >> >> Result: >> >> abc >> def >> ghi >> >> >> Example: >> >> String table = `First Name Surname Phone >> Al Albert 555-1111 >> Bob Roberts 555-2222 >> Cal Calvin 555-3333 >> `; >> >> // Extract headers >> String firstLine = table.lines().findFirst?().orElse(""); >> List headings = List.of(firstLine.trim().split(`\s{2,}`)); >> >> // Build stream of maps >> Stream> stream = >> table.lines().skip(1) >> .map(line -> line.trim()) >> .filter(line -> !line.isEmpty()) >> .map(line -> line.split(`\s{2,}`)) >> .map(columns -> { >> List values = List.of(columns); >> return IntStream.range(0, headings.size()).boxed() >> .collect(toMap(headings::get, values::get)); >> }); >> >> // print all "First Name" >> stream.map(row -> row.get("First Name")) >> .forEach(name -> System.out.println(name)); >> >> Result: >> >> Al >> Bob >> Cal >> B. Additions to basic trim methods. In addition to margin methods trimIndent and trimMarkers described below in Section C, it would be worth introducing trimLeft and trimRight to augment the longstanding trim method. A key question is how trimLeft and trimRight should detect whitespace, because different definitions of whitespace exist in the library. >> >> trim itself uses the simple test less than or equal to the space character, a fast test but not Unicode friendly. >> >> Character.isWhitespace(codepoint) returns true if codepoint one of the following; >> >> SPACE_SEPARATOR. >> LINE_SEPARATOR. >> PARAGRAPH_SEPARATOR. >> '\t', U+0009 HORIZONTAL TABULATION. >> '\n', U+000A LINE FEED. >> '\u000B', U+000B VERTICAL TABULATION. >> '\f', U+000C FORM FEED. >> '\r', U+000D CARRIAGE RETURN. >> '\u001C', U+001C FILE SEPARATOR. >> '\u001D', U+001D GROUP SEPARATOR. >> '\u001E', U+001E RECORD SEPARATOR. >> '\u001F', U+001F UNIT SEPARATOR. >> ' ', U+0020 SPACE. >> (Note: that non-breaking space (\u00A0) is excluded) >> >> Character.isSpaceChar(codepoint) returns true if codepoint one of the following; >> >> SPACE_SEPARATOR. >> LINE_SEPARATOR. >> PARAGRAPH_SEPARATOR. >> ' ', U+0020 SPACE. >> '\u00A0', U+00A0 NON-BREAKING SPACE. >> That sets up several kinds of whitespace; trim's whitespace (TWS), Character whitespace (CWS) and the union of the two (UWS). TWS is a fast test. CWS is a slow test. UWS is fast for Latin1 and slow-ish for UTF-16. >> >> We are recommending that trimLeft and trimRight use UWS, leave trim alone to avoid breaking the world and then possibly introduce trimWhitespace that uses UWS. >> >> public String trim() >> Removes characters less than equal to space from the beginning and end of the string. No, change except spec clarification and links to the new trim methods. >> Examples: >> "".trim(); // "" >> " ".trim(); // "" >> " abc ".trim(); // "abc" >> " \u2028abc ".trim(); // "\u2028abc" >> public String trimWhitespace() >> Removes whitespace from the beginning and end of the string. >> Examples: >> >> "".trimWhitespace(); // "" >> " ".trimWhitespace(); // "" >> " abc ".trimWhitespace(); // "abc" >> " \u2028abc ".trimWhitespace(); // "abc" >> public String trimLeft() >> Removes whitespace from the beginning of the string. >> Examples: >> >> "".trimLeft(); // "" >> " ".trimLeft(); // "" >> " abc ".trimLeft(); // "abc " >> public String trimRight() >> Removes whitespace from the end of the string. >> Examples: >> >> "".trimRight(); // "" >> " ".trimRight(); // "" >> " abc ".trimRight(); // " abc" >> C. Margin management. With introduction of multi-line Raw String Literals, developers will have to deal with the extraneous spacing introduced by indenting and formatting string bodies. >> >> Note that for all the methods in this group, if the first line is empty then it is removed and if the last is empty then it is removed. This removal provides a means for developers that use delimiters on separate lines to bracket string bodies. Also note, that all line separators are replaced with \n. >> >> public String trimIndent() >> This method determines a representative line in the string body that has a non-whitespace character closest to the left margin. Once that line has been determined, the number of leading whitespaces is tallied to produce a minimal indent amount. Consequently, the result of the method is a string with the minimal indent amount removed from each line. The first line is unaffected since it is preceded by the open delimiter. The type of whitespace used (spaces or tabs) does not affect the result as long as the developer is consistent with the whitespace used. >> Example: >> >> String x = ` >> This is a line >> This is a line >> This is a line >> This is a line >> This is a line >> `.trimIndent(); >> >> Result: >> >> This is a line >> This is a line >> This is a line >> This is a line >> This is a line >> public String trimMarkers(String leftMarker, String rightMarker) >> Each line of the multi-line string is first trimmed. If the trimmed line contains the leftMarker at the beginning of the string then it is removed. Finally, if the line contains the rightMarker at the end of line, it is removed. >> Example: >> >> String x = `|This is a line| >> |This is a line| >> |This is a line|`.trimMarkers("|", "|"); >> Result: >> >> This is a line >> This is a line >> This is a line >> >> Example: >> >> String x = `>> This is a line >>>> This is a line >>>> This is a line`.trimMarkers(">> ", ""); >> Result: >> >> This is a line >> This is a line >> This is a line >> D. Escape management. Since Raw String Literals do not interpret Unicode escapes (\unnnn) or escape sequences (\n, \b, etc), we need to provide a scheme for developers who just want multi-line strings but still have escape sequences interpreted. >> >> public String unescape() throws MalformedEscapeException >> Translates each Unicode escape or escape sequence in the string into the character represented by the escape. @jls 3.3, 3.10.6 >> Example: >> >> `abc\u2022def\nghi`.unescape(); >> >> Result: >> >> abc?def >> ghi >> public String unescape(EscapeType... escape) throws MalformedEscapeException >> Selectively translates Unicode escape or escape sequence based on the escape type flags provided. >> public enum EscapeType { >> /** Backslash escape sequences based on section 3.10.6 of the >> * The Java™ Language Specification. >> * This includes sequences for backspace, horizontal tab, >> * line feed, form feed, carriage return, double quote, >> * single quote, backslash and octal escape sequences. >> */ >> BACKSLASH, // >> >> /** Unicode sequences based on section 3.3 of the >> * The Java™ Language Specification. >> * This includes sequences in the form {@code \u005Cunnnn}. >> */ >> UNICODE >> } >> >> >> Example: >> >> `abc\u2022def\nghi`.unescape(EscapeType.BACKSLASH); >> >> Result: >> >> abc\u2022def >> ghi >> >> >> Example: >> >> `abc\u2022def\nghi`.unescape(EscapeType.UNICODE); >> >> Result: >> >> abc?def\nghi >> Conversely, there are circumstances where the inverse is required >> >> public String escape() >> Translates each quote, backslash, non-graphic character or non-ASCII character into an Unicode escape or escape sequence. The method is equivalent to escape(BACKSLASH, UNICODE) . >> Example: >> >> `abc?def >> ghi`.escape(); >> >> Result: >> >> abc\u2022def\nghi >> public String escape(EscapeType... escape) >> Selectively translates each quote, backslash, non-graphic character or non-ASCII character into an Unicode escape or escape sequence based on the escape type flags provided. >> Example: >> >> `abc?def >> ghi`.escape(EscapeType.BACKSLASH); >> >> Result: >> >> abc?def\nghi >> >> >> Example: >> >> `abc?def >> ghi`.escape(EscapeType.UNICODE); >> >> Result: >> >> abc\u2022def >> ghi >> > From david.lloyd at redhat.com Wed Mar 21 15:58:20 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 21 Mar 2018 10:58:20 -0500 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc Message-ID: Since adding a field called "name" to java.lang.ClassLoader, the "name" anchor which previously referred to the section entitled "binary names" has been broken. The attached doc-only patch changes the name of the anchor to "binary-name". It applies with "patch -p1". -- - DML -------------- next part -------------- diff --git a/src/java.base/share/classes/java/lang/ClassLoader.java b/src/java.base/share/classes/java/lang/ClassLoader.java index f0d41f425dd..cb6193f2b1f 100644 --- a/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/src/java.base/share/classes/java/lang/ClassLoader.java @@ -73,7 +73,7 @@ import sun.security.util.SecurityConstants; /** * A class loader is an object that is responsible for loading classes. The * class {@code ClassLoader} is an abstract class. Given the binary name of a class, a class loader should attempt to + * href="#binary-name">binary name of a class, a class loader should attempt to * locate or generate data that constitutes a definition for the class. A * typical strategy is to transform the name into a file name and then read a * "class file" of that name from a file system. @@ -202,7 +202,7 @@ import sun.security.util.SecurityConstants; * } * * - *

Binary names

+ *

Binary names

* *

Any class name provided as a {@code String} parameter to methods in * {@code ClassLoader} must be a binary name as defined by @@ -480,7 +480,7 @@ public abstract class ClassLoader { // -- Class -- /** - * Loads the class with the specified binary name. + * Loads the class with the specified binary name. * This method searches for classes in the same manner as the {@link * #loadClass(String, boolean)} method. It is invoked by the Java virtual * machine to resolve class references. Invoking this method is equivalent @@ -488,7 +488,7 @@ public abstract class ClassLoader { * false)}. * * @param name - * The binary name of the class + * The binary name of the class * * @return The resulting {@code Class} object * @@ -500,7 +500,7 @@ public abstract class ClassLoader { } /** - * Loads the class with the specified binary name. The + * Loads the class with the specified binary name. The * default implementation of this method searches for classes in the * following order: * @@ -530,7 +530,7 @@ public abstract class ClassLoader { * during the entire class loading process. * * @param name - * The binary name of the class + * The binary name of the class * * @param resolve * If {@code true} then resolve the class @@ -579,7 +579,7 @@ public abstract class ClassLoader { } /** - * Loads the class with the specified binary name + * Loads the class with the specified binary name * in a module defined to this class loader. This method returns {@code null} * if the class could not be found. * @@ -598,7 +598,7 @@ public abstract class ClassLoader { * @param module * The module * @param name - * The binary name of the class + * The binary name of the class * * @return The resulting {@code Class} object in a module defined by * this class loader, or {@code null} if the class could not be found. @@ -674,7 +674,7 @@ public abstract class ClassLoader { } /** - * Finds the class with the specified binary name. + * Finds the class with the specified binary name. * This method should be overridden by class loader implementations that * follow the delegation model for loading classes, and will be invoked by * the {@link #loadClass loadClass} method after checking the @@ -683,7 +683,7 @@ public abstract class ClassLoader { * @implSpec The default implementation throws {@code ClassNotFoundException}. * * @param name - * The binary name of the class + * The binary name of the class * * @return The resulting {@code Class} object * @@ -697,7 +697,7 @@ public abstract class ClassLoader { } /** - * Finds the class with the given binary name + * Finds the class with the given binary name * in a module defined to this class loader. * Class loader implementations that support the loading from modules * should override this method. @@ -715,7 +715,7 @@ public abstract class ClassLoader { * class loader * @param name - * The binary name of the class + * The binary name of the class * * @return The resulting {@code Class} object, or {@code null} * if the class could not be found. @@ -737,7 +737,7 @@ public abstract class ClassLoader { * Converts an array of bytes into an instance of class {@code Class}. * Before the {@code Class} can be used it must be resolved. This method * is deprecated in favor of the version that takes a binary name as its first argument, and is more secure. + * href="#binary-name">binary name as its first argument, and is more secure. * * @param b * The bytes that make up the class data. The bytes in positions @@ -804,12 +804,12 @@ public abstract class ClassLoader { * This method defines a package in this class loader corresponding to the * package of the {@code Class} (if such a package has not already been defined * in this class loader). The name of the defined package is derived from - * the binary name of the class specified by + * the binary name of the class specified by * the byte array {@code b}. * Other properties of the defined package are as specified by {@link Package}. * * @param name - * The expected binary name of the class, or + * The expected binary name of the class, or * {@code null} if not known * * @param b @@ -923,7 +923,7 @@ public abstract class ClassLoader { * package must contain the same set of certificates or a * {@code SecurityException} will be thrown. Note that if * {@code name} is {@code null}, this check is not performed. - * You should always pass in the binary name of the + * You should always pass in the binary name of the * class you are defining as well as the bytes. This ensures that the * class you are defining is indeed the class you think it is. * @@ -931,19 +931,19 @@ public abstract class ClassLoader { * only be defined by the {@linkplain #getPlatformClassLoader() * platform class loader} or its ancestors; otherwise {@code SecurityException} * will be thrown. If {@code name} is not {@code null}, it must be equal to - * the binary name of the class + * the binary name of the class * specified by the byte array {@code b}, otherwise a {@link * NoClassDefFoundError NoClassDefFoundError} will be thrown. * *

This method defines a package in this class loader corresponding to the * package of the {@code Class} (if such a package has not already been defined * in this class loader). The name of the defined package is derived from - * the binary name of the class specified by + * the binary name of the class specified by * the byte array {@code b}. * Other properties of the defined package are as specified by {@link Package}. * * @param name - * The expected binary name of the class, or + * The expected binary name of the class, or * {@code null} if not known * * @param b @@ -969,7 +969,7 @@ public abstract class ClassLoader { * * @throws NoClassDefFoundError * If {@code name} is not {@code null} and not equal to the - * binary name of the class specified by {@code b} + * binary name of the class specified by {@code b} * * @throws IndexOutOfBoundsException * If either {@code off} or {@code len} is negative, or if @@ -1027,7 +1027,7 @@ public abstract class ClassLoader { *

* * @param name - * The expected binary name. of the class, or + * The expected binary name. of the class, or * {@code null} if not known * * @param b @@ -1047,7 +1047,7 @@ public abstract class ClassLoader { * * @throws NoClassDefFoundError * If {@code name} is not {@code null} and not equal to the - * binary name of the class specified by {@code b} + * binary name of the class specified by {@code b} * * @throws SecurityException * If an attempt is made to add this class to a package that @@ -1198,7 +1198,7 @@ public abstract class ClassLoader { } /** - * Finds a class with the specified binary name, + * Finds a class with the specified binary name, * loading it if necessary. * *

This method loads the class through the system class loader (see @@ -1209,7 +1209,7 @@ public abstract class ClassLoader { * #findClass(String)}.

* * @param name - * The binary name of the class + * The binary name of the class * * @return The {@code Class} object for the specified {@code name} * @@ -1239,13 +1239,13 @@ public abstract class ClassLoader { private native Class findBootstrapClass(String name); /** - * Returns the class with the given binary name if this + * Returns the class with the given binary name if this * loader has been recorded by the Java virtual machine as an initiating - * loader of a class with that binary name. Otherwise + * loader of a class with that binary name. Otherwise * {@code null} is returned. * * @param name - * The binary name of the class + * The binary name of the class * * @return The {@code Class} object, or {@code null} if the class has * not been loaded @@ -2087,9 +2087,9 @@ public abstract class ClassLoader { } /** - * Defines a package by name in this {@code ClassLoader}. + * Defines a package by name in this {@code ClassLoader}. *

- * Package names must be unique within a class loader and + * Package names must be unique within a class loader and * cannot be redefined or changed once created. *

* If a class loader wishes to define a package with specific properties, @@ -2123,7 +2123,7 @@ public abstract class ClassLoader { * in a named module may be for example sealed with different seal base. * * @param name - * The package name + * The package name * * @param specTitle * The specification title @@ -2185,10 +2185,10 @@ public abstract class ClassLoader { } /** - * Returns a {@code Package} of the given name that + * Returns a {@code Package} of the given name that * has been defined by this class loader. * - * @param name The package name + * @param name The package name * * @return The {@code Package} of the given name that has been defined * by this class loader, or {@code null} if not found @@ -2233,7 +2233,7 @@ public abstract class ClassLoader { } /** - * Finds a package by name in this class loader and its ancestors. + * Finds a package by name in this class loader and its ancestors. *

* If this class loader defines a {@code Package} of the given name, * the {@code Package} is returned. Otherwise, the ancestors of @@ -2247,7 +2247,7 @@ public abstract class ClassLoader { * class loader. * * @param name - * The package name + * The package name * * @return The {@code Package} of the given name that has been defined by * this class loader or its ancestors, or {@code null} if not found. From david.lloyd at redhat.com Wed Mar 21 16:02:22 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 21 Mar 2018 11:02:22 -0500 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: References: Message-ID: I discovered there are a couple of references outside of ClassLoader as well. Here's the updated patch... On Wed, Mar 21, 2018 at 10:58 AM, David Lloyd wrote: > Since adding a field called "name" to java.lang.ClassLoader, the > "name" anchor which previously referred to the section entitled > "binary names" has been broken. > > The attached doc-only patch changes the name of the anchor to > "binary-name". It applies with "patch -p1". > > -- > - DML -- - DML -------------- next part -------------- diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index cf34ff2d86e..adb61e69d35 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -382,7 +382,7 @@ public final class Class implements java.io.Serializable, /** - * Returns the {@code Class} with the given + * Returns the {@code Class} with the given * binary name in the given module. * *

This method attempts to locate, load, and link the class or interface. @@ -404,7 +404,7 @@ public final class Class implements java.io.Serializable, * loads a class in another module. * * @param module A module - * @param name The binary name + * @param name The binary name * of the class * @return {@code Class} object of the given name defined in the given module; * {@code null} if not found. diff --git a/src/java.base/share/classes/java/lang/ClassLoader.java b/src/java.base/share/classes/java/lang/ClassLoader.java index f0d41f425dd..cb6193f2b1f 100644 --- a/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/src/java.base/share/classes/java/lang/ClassLoader.java @@ -73,7 +73,7 @@ import sun.security.util.SecurityConstants; /** * A class loader is an object that is responsible for loading classes. The * class {@code ClassLoader} is an abstract class. Given the binary name of a class, a class loader should attempt to + * href="#binary-name">binary name of a class, a class loader should attempt to * locate or generate data that constitutes a definition for the class. A * typical strategy is to transform the name into a file name and then read a * "class file" of that name from a file system. @@ -202,7 +202,7 @@ import sun.security.util.SecurityConstants; * } * * - *

Binary names

+ *

Binary names

* *

Any class name provided as a {@code String} parameter to methods in * {@code ClassLoader} must be a binary name as defined by @@ -480,7 +480,7 @@ public abstract class ClassLoader { // -- Class -- /** - * Loads the class with the specified binary name. + * Loads the class with the specified binary name. * This method searches for classes in the same manner as the {@link * #loadClass(String, boolean)} method. It is invoked by the Java virtual * machine to resolve class references. Invoking this method is equivalent @@ -488,7 +488,7 @@ public abstract class ClassLoader { * false)}. * * @param name - * The binary name of the class + * The binary name of the class * * @return The resulting {@code Class} object * @@ -500,7 +500,7 @@ public abstract class ClassLoader { } /** - * Loads the class with the specified binary name. The + * Loads the class with the specified binary name. The * default implementation of this method searches for classes in the * following order: * @@ -530,7 +530,7 @@ public abstract class ClassLoader { * during the entire class loading process. * * @param name - * The binary name of the class + * The binary name of the class * * @param resolve * If {@code true} then resolve the class @@ -579,7 +579,7 @@ public abstract class ClassLoader { } /** - * Loads the class with the specified binary name + * Loads the class with the specified binary name * in a module defined to this class loader. This method returns {@code null} * if the class could not be found. * @@ -598,7 +598,7 @@ public abstract class ClassLoader { * @param module * The module * @param name - * The binary name of the class + * The binary name of the class * * @return The resulting {@code Class} object in a module defined by * this class loader, or {@code null} if the class could not be found. @@ -674,7 +674,7 @@ public abstract class ClassLoader { } /** - * Finds the class with the specified binary name. + * Finds the class with the specified binary name. * This method should be overridden by class loader implementations that * follow the delegation model for loading classes, and will be invoked by * the {@link #loadClass loadClass} method after checking the @@ -683,7 +683,7 @@ public abstract class ClassLoader { * @implSpec The default implementation throws {@code ClassNotFoundException}. * * @param name - * The binary name of the class + * The binary name of the class * * @return The resulting {@code Class} object * @@ -697,7 +697,7 @@ public abstract class ClassLoader { } /** - * Finds the class with the given binary name + * Finds the class with the given binary name * in a module defined to this class loader. * Class loader implementations that support the loading from modules * should override this method. @@ -715,7 +715,7 @@ public abstract class ClassLoader { * class loader * @param name - * The binary name of the class + * The binary name of the class * * @return The resulting {@code Class} object, or {@code null} * if the class could not be found. @@ -737,7 +737,7 @@ public abstract class ClassLoader { * Converts an array of bytes into an instance of class {@code Class}. * Before the {@code Class} can be used it must be resolved. This method * is deprecated in favor of the version that takes a binary name as its first argument, and is more secure. + * href="#binary-name">binary name as its first argument, and is more secure. * * @param b * The bytes that make up the class data. The bytes in positions @@ -804,12 +804,12 @@ public abstract class ClassLoader { * This method defines a package in this class loader corresponding to the * package of the {@code Class} (if such a package has not already been defined * in this class loader). The name of the defined package is derived from - * the binary name of the class specified by + * the binary name of the class specified by * the byte array {@code b}. * Other properties of the defined package are as specified by {@link Package}. * * @param name - * The expected binary name of the class, or + * The expected binary name of the class, or * {@code null} if not known * * @param b @@ -923,7 +923,7 @@ public abstract class ClassLoader { * package must contain the same set of certificates or a * {@code SecurityException} will be thrown. Note that if * {@code name} is {@code null}, this check is not performed. - * You should always pass in the binary name of the + * You should always pass in the binary name of the * class you are defining as well as the bytes. This ensures that the * class you are defining is indeed the class you think it is. * @@ -931,19 +931,19 @@ public abstract class ClassLoader { * only be defined by the {@linkplain #getPlatformClassLoader() * platform class loader} or its ancestors; otherwise {@code SecurityException} * will be thrown. If {@code name} is not {@code null}, it must be equal to - * the binary name of the class + * the binary name of the class * specified by the byte array {@code b}, otherwise a {@link * NoClassDefFoundError NoClassDefFoundError} will be thrown. * *

This method defines a package in this class loader corresponding to the * package of the {@code Class} (if such a package has not already been defined * in this class loader). The name of the defined package is derived from - * the binary name of the class specified by + * the binary name of the class specified by * the byte array {@code b}. * Other properties of the defined package are as specified by {@link Package}. * * @param name - * The expected binary name of the class, or + * The expected binary name of the class, or * {@code null} if not known * * @param b @@ -969,7 +969,7 @@ public abstract class ClassLoader { * * @throws NoClassDefFoundError * If {@code name} is not {@code null} and not equal to the - * binary name of the class specified by {@code b} + * binary name of the class specified by {@code b} * * @throws IndexOutOfBoundsException * If either {@code off} or {@code len} is negative, or if @@ -1027,7 +1027,7 @@ public abstract class ClassLoader { *

* * @param name - * The expected binary name. of the class, or + * The expected binary name. of the class, or * {@code null} if not known * * @param b @@ -1047,7 +1047,7 @@ public abstract class ClassLoader { * * @throws NoClassDefFoundError * If {@code name} is not {@code null} and not equal to the - * binary name of the class specified by {@code b} + * binary name of the class specified by {@code b} * * @throws SecurityException * If an attempt is made to add this class to a package that @@ -1198,7 +1198,7 @@ public abstract class ClassLoader { } /** - * Finds a class with the specified binary name, + * Finds a class with the specified binary name, * loading it if necessary. * *

This method loads the class through the system class loader (see @@ -1209,7 +1209,7 @@ public abstract class ClassLoader { * #findClass(String)}.

* * @param name - * The binary name of the class + * The binary name of the class * * @return The {@code Class} object for the specified {@code name} * @@ -1239,13 +1239,13 @@ public abstract class ClassLoader { private native Class findBootstrapClass(String name); /** - * Returns the class with the given binary name if this + * Returns the class with the given binary name if this * loader has been recorded by the Java virtual machine as an initiating - * loader of a class with that binary name. Otherwise + * loader of a class with that binary name. Otherwise * {@code null} is returned. * * @param name - * The binary name of the class + * The binary name of the class * * @return The {@code Class} object, or {@code null} if the class has * not been loaded @@ -2087,9 +2087,9 @@ public abstract class ClassLoader { } /** - * Defines a package by name in this {@code ClassLoader}. + * Defines a package by name in this {@code ClassLoader}. *

- * Package names must be unique within a class loader and + * Package names must be unique within a class loader and * cannot be redefined or changed once created. *

* If a class loader wishes to define a package with specific properties, @@ -2123,7 +2123,7 @@ public abstract class ClassLoader { * in a named module may be for example sealed with different seal base. * * @param name - * The package name + * The package name * * @param specTitle * The specification title @@ -2185,10 +2185,10 @@ public abstract class ClassLoader { } /** - * Returns a {@code Package} of the given name that + * Returns a {@code Package} of the given name that * has been defined by this class loader. * - * @param name The package name + * @param name The package name * * @return The {@code Package} of the given name that has been defined * by this class loader, or {@code null} if not found @@ -2233,7 +2233,7 @@ public abstract class ClassLoader { } /** - * Finds a package by name in this class loader and its ancestors. + * Finds a package by name in this class loader and its ancestors. *

* If this class loader defines a {@code Package} of the given name, * the {@code Package} is returned. Otherwise, the ancestors of @@ -2247,7 +2247,7 @@ public abstract class ClassLoader { * class loader. * * @param name - * The package name + * The package name * * @return The {@code Package} of the given name that has been defined by * this class loader or its ancestors, or {@code null} if not found. diff --git a/src/java.base/share/classes/java/lang/StackWalker.java b/src/java.base/share/classes/java/lang/StackWalker.java index af20b79771c..009b70c6eb4 100644 --- a/src/java.base/share/classes/java/lang/StackWalker.java +++ b/src/java.base/share/classes/java/lang/StackWalker.java @@ -100,7 +100,7 @@ public final class StackWalker { */ public interface StackFrame { /** - * Gets the binary name + * Gets the binary name * of the declaring class of the method represented by this stack frame. * * @return the binary name of the declaring class of the method From martinrb at google.com Wed Mar 21 16:10:37 2018 From: martinrb at google.com (Martin Buchholz) Date: Wed, 21 Mar 2018 16:10:37 +0000 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: References: Message-ID: Hi David. I'll take this one. - * Returns a {@code Package} of the given name that + * Returns a {@code Package} of the given name that Do Packages (I should really learn about Packages) actually have binary names? I'm confused by the subject. There is no such bug 9053056: Anchor name conflict in ClassLoader JavaDoc On Wed, Mar 21, 2018 at 9:03 AM David Lloyd wrote: > I discovered there are a couple of references outside of ClassLoader > as well. Here's the updated patch... > > On Wed, Mar 21, 2018 at 10:58 AM, David Lloyd > wrote: > > Since adding a field called "name" to java.lang.ClassLoader, the > > "name" anchor which previously referred to the section entitled > > "binary names" has been broken. > > > > The attached doc-only patch changes the name of the anchor to > > "binary-name". It applies with "patch -p1". > > > > -- > > - DML > > > > -- > - DML > From david.lloyd at redhat.com Wed Mar 21 16:15:01 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 21 Mar 2018 11:15:01 -0500 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: References: Message-ID: On Wed, Mar 21, 2018 at 11:10 AM, Martin Buchholz wrote: > Hi David. > > I'll take this one. Thanks. > - * Returns a {@code Package} of the given name that > + * Returns a {@code Package} of the given href="#binary-name">name that > > Do Packages (I should really learn about Packages) actually have binary > names? Maybe but AFAICT they would be identical to the Java language name. Rather than try to solve this distinction, in the spirit of solving one bug at a time (and also laziness), I opted to just replace all existing references and otherwise change nothing. > I'm confused by the subject. There is no such bug I submitted it via bugreport.java.com; it hasn't been reviewed yet. I expect it might show up soon. > On Wed, Mar 21, 2018 at 9:03 AM David Lloyd wrote: >> >> I discovered there are a couple of references outside of ClassLoader >> as well. Here's the updated patch... >> >> On Wed, Mar 21, 2018 at 10:58 AM, David Lloyd >> wrote: >> > Since adding a field called "name" to java.lang.ClassLoader, the >> > "name" anchor which previously referred to the section entitled >> > "binary names" has been broken. >> > >> > The attached doc-only patch changes the name of the anchor to >> > "binary-name". It applies with "patch -p1". >> > >> > -- >> > - DML >> >> >> >> -- >> - DML -- - DML From martinrb at google.com Wed Mar 21 16:24:10 2018 From: martinrb at google.com (Martin Buchholz) Date: Wed, 21 Mar 2018 09:24:10 -0700 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: References: Message-ID: Found it. https://bugs.openjdk.java.net/browse/JDK-8199947 From david.lloyd at redhat.com Wed Mar 21 16:27:58 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 21 Mar 2018 11:27:58 -0500 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: References: Message-ID: Ah, so the submitted bug ID doesn't match the final bug ID. Excellent. On Wed, Mar 21, 2018 at 11:24 AM, Martin Buchholz wrote: > Found it. > https://bugs.openjdk.java.net/browse/JDK-8199947 > -- - DML From Alan.Bateman at oracle.com Wed Mar 21 16:19:52 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 21 Mar 2018 16:19:52 +0000 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: References: Message-ID: On 21/03/2018 16:10, Martin Buchholz wrote: > : > > I'm confused by the subject. There is no such bug > 9053056: Anchor name conflict in ClassLoader JavaDoc > I've just moved it to the jdk project where it is JDK-8199947. -Alan From brian.burkhalter at oracle.com Wed Mar 21 16:48:34 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 21 Mar 2018 09:48:34 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> Message-ID: <24C4893C-DCDB-4C93-BD8A-E491F38B8BA5@oracle.com> On Mar 16, 2018, at 8:04 AM, Brian Burkhalter wrote: > On Mar 16, 2018, at 7:59 AM, Roger Riggs wrote: > >> ByteArrayOutputStream: 166: Add spaces after "," in the code. > > Done: webrev.01 updated in place. > >> Write: >> Thanks for converting to TestNG. >> There are probably some more testng'ish ways of coding the test but its fine as is. >> >> All set as far as I'm concerned. The CSR for this has been approved with the comment that 165 *

This method is equivalent to {@link #write(byte[],int,int) 166 * write(b ,0, b.length)} looks like an @implSpec tag. Brian From Roger.Riggs at Oracle.com Wed Mar 21 16:58:12 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Wed, 21 Mar 2018 12:58:12 -0400 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: <24C4893C-DCDB-4C93-BD8A-E491F38B8BA5@oracle.com> References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> <24C4893C-DCDB-4C93-BD8A-E491F38B8BA5@oracle.com> Message-ID: Hi Brian, An @impSpec for that is fine with me. Roger On 3/21/2018 12:48 PM, Brian Burkhalter wrote: > > On Mar 16, 2018, at 8:04 AM, Brian Burkhalter > > wrote: > >> On Mar 16, 2018, at 7:59 AM, Roger Riggs > > wrote: >> >>> ByteArrayOutputStream: 166:? Add spaces after "," in the code. >> >> Done: webrev.01 updated in place. >> >>> Write: >>> ?Thanks for converting to TestNG. >>> ?There are probably some more testng'ish ways of coding the test but >>> its fine as is. >>> >>> All set as far as I'm concerned. > > The CSR for this has been approved with the comment that > > ?165??????*?

?This?method?is?equivalent?to?{@link?#write(byte[],int,int) > ?166??????*?write(b?,0,?b.length)} > > looks like an @implSpec tag. > > Brian From brian.burkhalter at oracle.com Wed Mar 21 17:00:57 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 21 Mar 2018 10:00:57 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> <24C4893C-DCDB-4C93-BD8A-E491F38B8BA5@oracle.com> Message-ID: <737113AA-08DC-4E04-A9CA-51A0A18ED970@oracle.com> Hi Roger, I?ll change before pushing. Thanks, Brian On Mar 21, 2018, at 9:58 AM, Roger Riggs wrote: > An @impSpec for that is fine with me. From mandy.chung at oracle.com Wed Mar 21 17:04:13 2018 From: mandy.chung at oracle.com (mandy chung) Date: Wed, 21 Mar 2018 10:04:13 -0700 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: References: Message-ID: On 3/21/18 8:58 AM, David Lloyd wrote: > Since adding a field called "name" to java.lang.ClassLoader, the > "name" anchor which previously referred to the section entitled > "binary names" has been broken. > > The attached doc-only patch changes the name of the anchor to > "binary-name". It applies with "patch -p1". > The links are not broken in the published javadoc as it only generates javadoc for the public elements. Are you seeing the broken links from your own javadoc build including private elements? Mandy From irogers at google.com Wed Mar 21 17:05:01 2018 From: irogers at google.com (Ian Rogers) Date: Wed, 21 Mar 2018 17:05:01 +0000 Subject: GetPrimitiveArrayCritical vs GetByteArrayRegion: 140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream In-Reply-To: References: <22bbd632-47c1-7702-bd65-6a51f0bbad02@oracle.com> <9b5ff318-af41-03c4-efdc-b41b97cf6e61@oracle.com> <5A9D8C60.3050505@oracle.com> <5A9D8F33.5060500@oracle.com> <5A9DAC84.906@oracle.com> <5A9DAE87.8020801@oracle.com> <1521102348.2448.25.camel@oracle.com> <23639144-5217-4A0F-930C-EF24B4976544@oracle.com> <1521451687.2323.5.camel@oracle.com> Message-ID: Thanks for accepting these as bugs/RFEs: "140x slow-down using -Xcheck:jni and java.util.zip.DeflaterOutputStream" https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8199920 "Deprecate JNI critical APIs" https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8199919 "Report tardy threads as potential TTSP issues" https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8199921 "With -Xcheck:jni warn when a JNI critical region is "too long"" https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8199922 "Reduce size of JNI critical regions in JDK (for example via loop strip mining)" https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8199916 Ian On Tue, Mar 20, 2018 at 7:07 PM Ian Rogers wrote: > Thanks, via bugreport.java.com I filed bugs/RFEs with ids 9053047, > 9053048, 9053049, 9053050 and 9053051. > Ian > > On Mon, Mar 19, 2018 at 2:28 AM Thomas Schatzl > wrote: > >> Hi, >> >> On Fri, 2018-03-16 at 17:19 +0000, Ian Rogers wrote: >> > Thanks Paul, very interesting. >> > >> > On Fri, Mar 16, 2018 at 9:21 AM Paul Sandoz >> > wrote: >> > > Hi Ian, Thomas, >> > > >> > > [...] >> > > (This is also something we need to consider if we modify buffers to >> > > support capacities larger than Integer.MAX_VALUE. Also connects >> > > with Project Panama.) >> > > >> > > If Thomas has not done so or does not plan to i can log an issue >> > > for you. >> > > >> > >> > That'd be great. I wonder if identifying more TTSP issues should also >> > be a bug. Its interesting to observe that overlooking TTSP in C2 >> > motivated the Unsafe.copyMemory change permitting a fresh TTSP issue. >> > If TTSP is a 1st class issue then maybe we can deprecate JNI critical >> > regions to support that effort :-) >> >> Please log an issue. I am still a bit unsure what and how many issues >> should be filed. >> >> @Ian: at bugreports.oracle.com everyone may file bug reports without >> the need for an account. >> It will take some time until they show up in Jira due to vetting, but >> if you have a good case, and can e.g. link to the mailing list, this >> should be painless. >> >> Thanks, >> Thomas >> >> From david.lloyd at redhat.com Wed Mar 21 17:26:59 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 21 Mar 2018 12:26:59 -0500 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: References: Message-ID: On Wed, Mar 21, 2018 at 12:04 PM, mandy chung wrote: > > > On 3/21/18 8:58 AM, David Lloyd wrote: > > Since adding a field called "name" to java.lang.ClassLoader, the > "name" anchor which previously referred to the section entitled > "binary names" has been broken. > > The attached doc-only patch changes the name of the anchor to > "binary-name". It applies with "patch -p1". > > The links are not broken in the published javadoc as it only generates > javadoc for the public elements. > > Are you seeing the broken links from your own javadoc build including > private elements? I see it with IntelliJ IDEA when I pop up "quick JavaDoc" on, say, defineClass and then click on "binary name"; it's actually using the sources, rather than generated JavaDoc. -- - DML From brian.burkhalter at oracle.com Wed Mar 21 18:01:33 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 21 Mar 2018 11:01:33 -0700 Subject: RFR of 8180451: ByteArrayInputStream should override readAllBytes, readNBytes, and transferTo In-Reply-To: References: <09F39E3A-76B0-4D36-98F3-78AD246B91A7@oracle.com> <37818C83-0741-42EE-AD95-6259695E2DF9@oracle.com> <50B3A2D3-82B0-48DB-95D9-6318F1491725@oracle.com> Message-ID: This is still in need of final approval, assuming it is OK. Thanks, Brian On Mar 14, 2018, at 10:50 AM, Brian Burkhalter wrote: > On Mar 14, 2018, at 9:27 AM, David Lloyd wrote: > >> @@ -196,14 +194,32 @@ >> return len; >> } >> >> + public synchronized byte[] readAllBytes() { >> + byte[] result = Arrays.copyOfRange(buf, pos, count); >> + pos = count; >> + return result; >> + } >> + >> + public synchronized int readNBytes(byte[] b, int off, int len) { >> + int n = read(b, off, len); >> + return n == -1 ? 0 : n; >> + } >> >> This probably doesn't need to be synchronized, though I imagine the >> difference would be minimal. > > You are correct, it does not. > >> + public synchronized long transferTo(OutputStream out) throws IOException { >> + int len = count - pos >> + out.write(but, pos, len); >> >> s/but/buf/ I guess? > > Webrevs corrected in place: > > http://cr.openjdk.java.net/~bpb/8180451/webrev.00-01/ > http://cr.openjdk.java.net/~bpb/8180451/webrev.01/ From brian.burkhalter at oracle.com Wed Mar 21 18:02:05 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 21 Mar 2018 11:02:05 -0700 Subject: RFR 8198997: Cache normalized/resolved user.dir property In-Reply-To: <511EF388-9569-46E2-9BF5-7EFA00281051@oracle.com> References: <511EF388-9569-46E2-9BF5-7EFA00281051@oracle.com> Message-ID: <39FDEB0A-87B4-414D-864D-151CB4395007@oracle.com> Ping ? On Mar 13, 2018, at 12:33 PM, Brian Burkhalter wrote: > On Mar 13, 2018, at 12:24 PM, Alan Bateman wrote: > >> As relative paths are command then it might be simpler to just change the static initializer > > Static initializer or constructor? > >> to initialize userDir to normalize(props.getProperty("user.dir")). > > I was originally going to put that in the constructor but did not know about calling the normalize() instance method from the ctor. From Alan.Bateman at oracle.com Wed Mar 21 18:08:25 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 21 Mar 2018 18:08:25 +0000 Subject: RFR 8198997: Cache normalized/resolved user.dir property In-Reply-To: <39FDEB0A-87B4-414D-864D-151CB4395007@oracle.com> References: <511EF388-9569-46E2-9BF5-7EFA00281051@oracle.com> <39FDEB0A-87B4-414D-864D-151CB4395007@oracle.com> Message-ID: On 21/03/2018 18:02, Brian Burkhalter wrote: > Ping ? I think we're waiting for a new version that will normalize the value of user.dir in the WinNTFileSystem constructor. -Alan From brian.burkhalter at oracle.com Wed Mar 21 18:12:17 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 21 Mar 2018 11:12:17 -0700 Subject: RFR 8198997: Cache normalized/resolved user.dir property In-Reply-To: References: <511EF388-9569-46E2-9BF5-7EFA00281051@oracle.com> <39FDEB0A-87B4-414D-864D-151CB4395007@oracle.com> Message-ID: On Mar 21, 2018, at 11:08 AM, Alan Bateman wrote: > On 21/03/2018 18:02, Brian Burkhalter wrote: >> Ping ? > I think we're waiting for a new version that will normalize the value of user.dir in the WinNTFileSystem constructor. That was unclear, at least to me: --- a/src/java.base/windows/classes/java/io/WinNTFileSystem.java +++ b/src/java.base/windows/classes/java/io/WinNTFileSystem.java @@ -48,11 +48,11 @@ public WinNTFileSystem() { Properties props = GetPropertyAction.privilegedGetProperties(); slash = props.getProperty("file.separator").charAt(0); semicolon = props.getProperty("path.separator").charAt(0); altSlash = (this.slash == '\\') ? '/' : '\\'; - userDir = props.getProperty("user.dir"); + userDir = normalize(props.getProperty("user.dir")); } Thanks, Brian From brian.burkhalter at oracle.com Wed Mar 21 18:27:44 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 21 Mar 2018 11:27:44 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: <737113AA-08DC-4E04-A9CA-51A0A18ED970@oracle.com> References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> <24C4893C-DCDB-4C93-BD8A-E491F38B8BA5@oracle.com> <737113AA-08DC-4E04-A9CA-51A0A18ED970@oracle.com> Message-ID: <3C4A921F-F063-4A87-B65F-81E7538DD498@oracle.com> The diff: --- a/src/java.base/share/classes/java/io/ByteArrayOutputStream.java +++ b/src/java.base/share/classes/java/io/ByteArrayOutputStream.java @@ -158,15 +158,16 @@ count += len; } /** * Writes the complete contents of the specified byte array * to this {@code ByteArrayOutputStream}. * - *

This method is equivalent to {@link #write(byte[],int,int) + * @implSpec + * This method is equivalent to {@link #write(byte[],int,int) * write(b ,0, b.length)}. * * @param b the data. * @throws NullPointerException if {@code b} is {@code null}. * @since 11 */ public void writeBytes(byte b[]) { Thanks, Brina On Mar 21, 2018, at 10:00 AM, Brian Burkhalter wrote: > I?ll change before pushing. > > Thanks, > > Brian > > On Mar 21, 2018, at 9:58 AM, Roger Riggs wrote: > >> An @impSpec for that is fine with me. From Alan.Bateman at oracle.com Wed Mar 21 18:36:26 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 21 Mar 2018 18:36:26 +0000 Subject: RFR 8198997: Cache normalized/resolved user.dir property In-Reply-To: References: <511EF388-9569-46E2-9BF5-7EFA00281051@oracle.com> <39FDEB0A-87B4-414D-864D-151CB4395007@oracle.com> Message-ID: On 21/03/2018 18:12, Brian Burkhalter wrote: > > That was unclear, at least to me: > > --- a/src/java.base/windows/classes/java/io/WinNTFileSystem.java > +++ b/src/java.base/windows/classes/java/io/WinNTFileSystem.java > @@ -48,11 +48,11 @@ > ? public WinNTFileSystem() { > ? ? ? Properties props = GetPropertyAction.privilegedGetProperties(); > ? ? ? slash = props.getProperty("file.separator").charAt(0); > ? ? ? semicolon = props.getProperty("path.separator").charAt(0); > ? ? ? altSlash = (this.slash == '\\') ? '/' : '\\'; > - ? ? ? userDir = props.getProperty("user.dir"); > + ? ? ? userDir = normalize(props.getProperty("user.dir")); > ? } > That looks right.? I assume there's no test for this as it's never been supported to change user.dir on the command line. -Alan From brian.burkhalter at oracle.com Wed Mar 21 18:37:30 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 21 Mar 2018 11:37:30 -0700 Subject: RFR 8198997: Cache normalized/resolved user.dir property In-Reply-To: References: <511EF388-9569-46E2-9BF5-7EFA00281051@oracle.com> <39FDEB0A-87B4-414D-864D-151CB4395007@oracle.com> Message-ID: On Mar 21, 2018, at 11:36 AM, Alan Bateman wrote: > That looks right. I assume there's no test for this as it's never been supported to change user.dir on the command line. I don?t think a test is called for. Thanks, Brian From huizhe.wang at oracle.com Wed Mar 21 19:08:41 2018 From: huizhe.wang at oracle.com (Joe Wang) Date: Wed, 21 Mar 2018 12:08:41 -0700 Subject: RFR (JDK11/doc-only) 8199176: Accessibility issues in java.base docs Message-ID: <5AB2ADB9.8080909@oracle.com> Hi, Please an accessibility fix for several package-info files. The report contained 4 items. Among them, 1 and 2 are issues in the javadoc tool, and 3 could use an improvement in the tool or documentation. For reference, please see the linked issues in JBS [1]. For the current issue, we're fixing item 3 manually. Item 4 is a separate issue, but it's bundled with this fix to cut the overhead. *Item 3*: Heading leavels should only increase by one This is due to the javadoc tool generates a header with an addition of headings, in this particular case,

. The fix for this particular case is to replace the

s with

. Since I know the java.xml packages suffer the same issue, I've included them in this fix as well. For other modules, I'll leave it to the accessibility team. The fix is verified using the accessibility tool, the issue "Heading leavels should only increase by one" no longer showed for the new API doc. *Item 4*: Broken inner link There were 4: 3 of them missed the "#" sign (as in "FEATURE", "INTERIM", "UPDATE"), the last one was due to capitalization, the inner linked was mistyped in lower case "#feature" when it should have been "#FEATURE". You may search the source with JBS: https://bugs.openjdk.java.net/browse/JDK-8199176 webrev: http://cr.openjdk.java.net/~joehw/jdk11/8199176/webrev/ [1] https://bugs.openjdk.java.net/browse/JDK-8199176 Thanks, Joe From lance.andersen at oracle.com Wed Mar 21 19:27:48 2018 From: lance.andersen at oracle.com (Lance Andersen) Date: Wed, 21 Mar 2018 15:27:48 -0400 Subject: RFR (JDK11/doc-only) 8199176: Accessibility issues in java.base docs In-Reply-To: <5AB2ADB9.8080909@oracle.com> References: <5AB2ADB9.8080909@oracle.com> Message-ID: <5E5A4F48-7163-40BD-A7F2-AD69CA91A945@oracle.com> looks fine Joe > On Mar 21, 2018, at 3:08 PM, Joe Wang wrote: > > Hi, > > Please an accessibility fix for several package-info files. > > The report contained 4 items. Among them, 1 and 2 are issues in the javadoc tool, and 3 could use an improvement in the tool or documentation. For reference, please see the linked issues in JBS [1]. > > > For the current issue, we're fixing item 3 manually. Item 4 is a separate issue, but it's bundled with this fix to cut the overhead. > > *Item 3*: Heading leavels should only increase by one > This is due to the javadoc tool generates a header with an addition of headings, in this particular case,

. The fix for this particular case is to replace the

s with

. > > Since I know the java.xml packages suffer the same issue, I've included them in this fix as well. For other modules, I'll leave it to the accessibility team. > > The fix is verified using the accessibility tool, the issue "Heading leavels should only increase by one" no longer showed for the new API doc. > > *Item 4*: Broken inner link > There were 4: 3 of them missed the "#" sign (as in "FEATURE", "INTERIM", "UPDATE"), the last one was due to capitalization, the inner linked was mistyped in lower case "#feature" when it should have been "#FEATURE". > > You may search the source with > > > > > > JBS: https://bugs.openjdk.java.net/browse/JDK-8199176 > webrev: http://cr.openjdk.java.net/~joehw/jdk11/8199176/webrev/ > > > [1] https://bugs.openjdk.java.net/browse/JDK-8199176 > > 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 stuart.marks at oracle.com Wed Mar 21 19:34:13 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Wed, 21 Mar 2018 12:34:13 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: <3C4A921F-F063-4A87-B65F-81E7538DD498@oracle.com> References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> <24C4893C-DCDB-4C93-BD8A-E491F38B8BA5@oracle.com> <737113AA-08DC-4E04-A9CA-51A0A18ED970@oracle.com> <3C4A921F-F063-4A87-B65F-81E7538DD498@oracle.com> Message-ID: <3e48e0ea-10b2-e290-d8d5-41b404d80374@oracle.com> On 3/21/18 11:27 AM, Brian Burkhalter wrote: > --- a/src/java.base/share/classes/java/io/ByteArrayOutputStream.java > +++ b/src/java.base/share/classes/java/io/ByteArrayOutputStream.java > @@ -158,15 +158,16 @@ > count += len; > } > > /** > * Writes the complete contents of the specified byte array > * to this {@code ByteArrayOutputStream}. > * > - *

This method is equivalent to {@link #write(byte[],int,int) > + * @implSpec > + * This method is equivalent to {@link #write(byte[],int,int) > * write(b ,0, b.length)}. > * > * @param b the data. > * @throws NullPointerException if {@code b} is {@code null}. > * @since 11 > */ > public void writeBytes(byte b[]) { Sorry, this is an @apiNote, not an @implSpec. Having this as an @implSpec sounds as if the implementation of this method in BAOS is *required* to call write(b, 0, b.length). It happens to do that in the current webrev, but this is not a requirement on the implementation. (At least that doesn't appear to be the intent.) Instead, this statement explains and clarifies, but otherwise doesn't add any testable assertions or change any semantics of the contract specified in the first sentence of the doc. Thus, it's a note on the API. Thanks, s'marks > > Thanks, > > Brina > > On Mar 21, 2018, at 10:00 AM, Brian Burkhalter wrote: > >> I?ll change before pushing. >> >> Thanks, >> >> Brian >> >> On Mar 21, 2018, at 9:58 AM, Roger Riggs wrote: >> >>> An @impSpec for that is fine with me. > From brian.burkhalter at oracle.com Wed Mar 21 20:01:12 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 21 Mar 2018 13:01:12 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: <3e48e0ea-10b2-e290-d8d5-41b404d80374@oracle.com> References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> <24C4893C-DCDB-4C93-BD8A-E491F38B8BA5@oracle.com> <737113AA-08DC-4E04-A9CA-51A0A18ED970@oracle.com> <3C4A921F-F063-4A87-B65F-81E7538DD498@oracle.com> <3e48e0ea-10b2-e290-d8d5-41b404d80374@oracle.com> Message-ID: On Mar 21, 2018, at 12:34 PM, Stuart Marks wrote: > Having this as an @implSpec sounds as if the implementation of this method in BAOS is *required* to call write(b, 0, b.length). It happens to do that in the current webrev, but this is not a requirement on the implementation. (At least that doesn't appear to be the intent.) Perhaps instead the verbiage just needs to be changed to, e.g., ?The implementation in this class simply invokes {@link #write(byte[],int,int) write(b, 0, b.length)}.? which appears to correspond to the description Implementation Specification. This is where the default implementation (or an overrideable implementation in a class) is specified. [1] Thanks, Brian [1] https://bugs.openjdk.java.net/browse/JDK-8068562 From stuart.marks at oracle.com Wed Mar 21 20:23:47 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Wed, 21 Mar 2018 13:23:47 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> <24C4893C-DCDB-4C93-BD8A-E491F38B8BA5@oracle.com> <737113AA-08DC-4E04-A9CA-51A0A18ED970@oracle.com> <3C4A921F-F063-4A87-B65F-81E7538DD498@oracle.com> <3e48e0ea-10b2-e290-d8d5-41b404d80374@oracle.com> Message-ID: <0e17eb45-5284-09c4-eb53-ffb5669c372c@oracle.com> On 3/21/18 1:01 PM, Brian Burkhalter wrote: > On Mar 21, 2018, at 12:34 PM, Stuart Marks > wrote: > >> Having this as an @implSpec sounds as if the implementation of this method in >> BAOS is *required* to call write(b, 0, b.length). It happens to do that in >> the current webrev, but this is not a requirement on the implementation. (At >> least that doesn't appear to be the intent.) > > Perhaps instead the verbiage just needs to be changed to, e.g., > > ?The implementation in this class simply invokes {@link #write(byte[],int,int) > write(b, 0, b.length)}.? I don't think you want to specify this detail about the implementation. Consider a possible future refactoring, where writeBytes() calls some internal method instead of calling write(b, 0, b.length). This might be done, for example, to leverage an intrinsic, or to avoid unnecessary bounds checks, or for some other reason we can't imagine at the moment. Such a refactoring would be prohibited by an @implSpec. s'marks From david.lloyd at redhat.com Wed Mar 21 20:25:33 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 21 Mar 2018 15:25:33 -0500 Subject: RFR of 8180451: ByteArrayInputStream should override readAllBytes, readNBytes, and transferTo In-Reply-To: References: <09F39E3A-76B0-4D36-98F3-78AD246B91A7@oracle.com> <37818C83-0741-42EE-AD95-6259695E2DF9@oracle.com> <50B3A2D3-82B0-48DB-95D9-6318F1491725@oracle.com> Message-ID: Sorry. This looks OK to me (non-reviewer) now. On Wed, Mar 21, 2018 at 1:01 PM, Brian Burkhalter wrote: > This is still in need of final approval, assuming it is OK. > > Thanks, > > Brian > > On Mar 14, 2018, at 10:50 AM, Brian Burkhalter > wrote: > > On Mar 14, 2018, at 9:27 AM, David Lloyd wrote: > > @@ -196,14 +194,32 @@ > return len; > } > > + public synchronized byte[] readAllBytes() { > + byte[] result = Arrays.copyOfRange(buf, pos, count); > + pos = count; > + return result; > + } > + > + public synchronized int readNBytes(byte[] b, int off, int len) { > + int n = read(b, off, len); > + return n == -1 ? 0 : n; > + } > > This probably doesn't need to be synchronized, though I imagine the > difference would be minimal. > > > You are correct, it does not. > > + public synchronized long transferTo(OutputStream out) throws > IOException { > + int len = count - pos > + out.write(but, pos, len); > > s/but/buf/ I guess? > > > Webrevs corrected in place: > > http://cr.openjdk.java.net/~bpb/8180451/webrev.00-01/ > http://cr.openjdk.java.net/~bpb/8180451/webrev.01/ > > -- - DML From brian.burkhalter at oracle.com Wed Mar 21 20:27:14 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 21 Mar 2018 13:27:14 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: <0e17eb45-5284-09c4-eb53-ffb5669c372c@oracle.com> References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> <24C4893C-DCDB-4C93-BD8A-E491F38B8BA5@oracle.com> <737113AA-08DC-4E04-A9CA-51A0A18ED970@oracle.com> <3C4A921F-F063-4A87-B65F-81E7538DD498@oracle.com> <3e48e0ea-10b2-e290-d8d5-41b404d80374@oracle.com> <0e17eb45-5284-09c4-eb53-ffb5669c372c@oracle.com> Message-ID: <47458469-2A63-4EA5-A5D6-CEFACC2CBA22@oracle.com> On Mar 21, 2018, at 1:23 PM, Stuart Marks wrote: >> Perhaps instead the verbiage just needs to be changed to, e.g., >> >> ?The implementation in this class simply invokes {@link #write(byte[],int,int) write(b, 0, b.length)}.? > I don't think you want to specify this detail about the implementation. > > Consider a possible future refactoring, where writeBytes() calls some internal method instead of calling write(b, 0, b.length). This might be done, for example, to leverage an intrinsic, or to avoid unnecessary bounds checks, or for some other reason we can't imagine at the moment. > > Such a refactoring would be prohibited by an @implSpec. Why then not an @implNote instead of an @apiNote? Thanks, Brian From mandy.chung at oracle.com Wed Mar 21 20:39:28 2018 From: mandy.chung at oracle.com (mandy chung) Date: Wed, 21 Mar 2018 13:39:28 -0700 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: References: Message-ID: <557d65e1-3498-afbc-dd0c-8a21869c2a58@oracle.com> On 3/21/18 10:26 AM, David Lloyd wrote: > I see it with IntelliJ IDEA when I pop up "quick JavaDoc" on, say, > defineClass and then click on "binary name"; it's actually using the > sources, rather than generated JavaDoc. I don't object to do this renaming as I favor this more explicit id.? However you will hit the same issue if another class names an anchor conflicts with its private member.?? Can you configure IntelliJ to generate public/protected elements to avoid this issue? Mandy From jonathan.gibbons at oracle.com Wed Mar 21 20:59:02 2018 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 21 Mar 2018 13:59:02 -0700 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: <557d65e1-3498-afbc-dd0c-8a21869c2a58@oracle.com> References: <557d65e1-3498-afbc-dd0c-8a21869c2a58@oracle.com> Message-ID: <5AB2C796.9080001@oracle.com> On 03/21/2018 01:39 PM, mandy chung wrote: > > > On 3/21/18 10:26 AM, David Lloyd wrote: >> I see it with IntelliJ IDEA when I pop up "quick JavaDoc" on, say, >> defineClass and then click on "binary name"; it's actually using the >> sources, rather than generated JavaDoc. > > I don't object to do this renaming as I favor this more explicit id. > However you will hit the same issue if another class names an anchor > conflicts with its private member. Can you configure IntelliJ to > generate public/protected elements to avoid this issue? > Mandy Mandy, I think that maybe we should establish a convention such that user-defined anchors can never conflict with javadoc-generated anchors. Using an embedded "-" (as in this proposal) in user-defined anchors is a good start. A secondary proposal would be to have doclint check for potential clashes. Even though we may use access filters to restrict the set of elements included in any documentation, it should never be good to facilitate clashes that may be caused by non-default options or non-default tools. -- Jon From david.lloyd at redhat.com Wed Mar 21 21:03:14 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 21 Mar 2018 16:03:14 -0500 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: <557d65e1-3498-afbc-dd0c-8a21869c2a58@oracle.com> References: <557d65e1-3498-afbc-dd0c-8a21869c2a58@oracle.com> Message-ID: On Wed, Mar 21, 2018 at 3:39 PM, mandy chung wrote: > On 3/21/18 10:26 AM, David Lloyd wrote: > > I see it with IntelliJ IDEA when I pop up "quick JavaDoc" on, say, > defineClass and then click on "binary name"; it's actually using the > sources, rather than generated JavaDoc. > > > I don't object to do this renaming as I favor this more explicit id. > However you will hit the same issue if another class names an anchor > conflicts with its private member. Can you configure IntelliJ to generate > public/protected elements to avoid this issue? My impression is that it is generating its indexes and rendering on the fly (or at least in some opaque manner) directly from the sources. There does not seem to be any setting which governs what is produced or displayed; I think it is generally a feature (not a bug) that one can browse into dependency and JDK sources and get quick JavaDoc on any element, even non-public elements. -- - DML From martinrb at google.com Wed Mar 21 21:13:23 2018 From: martinrb at google.com (Martin Buchholz) Date: Wed, 21 Mar 2018 14:13:23 -0700 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: References: <557d65e1-3498-afbc-dd0c-8a21869c2a58@oracle.com> Message-ID: On Wed, Mar 21, 2018 at 2:03 PM, David Lloyd wrote: > On Wed, Mar 21, 2018 at 3:39 PM, mandy chung > wrote: > > On 3/21/18 10:26 AM, David Lloyd wrote: > > > > I see it with IntelliJ IDEA when I pop up "quick JavaDoc" on, say, > > defineClass and then click on "binary name"; it's actually using the > > sources, rather than generated JavaDoc. > > > > > > I don't object to do this renaming as I favor this more explicit id. > > However you will hit the same issue if another class names an anchor > > conflicts with its private member. Can you configure IntelliJ to > generate > > public/protected elements to avoid this issue? > > My impression is that it is generating its indexes and rendering on > the fly (or at least in some opaque manner) directly from the sources. > There does not seem to be any setting which governs what is produced > or displayed; I think it is generally a feature (not a bug) that one > can browse into dependency and JDK sources and get quick JavaDoc on > any element, even non-public elements. > I agree with David - it's a feature of Intellij to make use of any documentation available in the sources, including html links in private javadoc. Private method javadoc is less important than its public sibling. Nevertheless, just like with any other documentation, it requires maintenance. From martinrb at google.com Wed Mar 21 21:18:37 2018 From: martinrb at google.com (Martin Buchholz) Date: Wed, 21 Mar 2018 14:18:37 -0700 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: <5AB2C796.9080001@oracle.com> References: <557d65e1-3498-afbc-dd0c-8a21869c2a58@oracle.com> <5AB2C796.9080001@oracle.com> Message-ID: On Wed, Mar 21, 2018 at 1:59 PM, Jonathan Gibbons < jonathan.gibbons at oracle.com> wrote: > > I think that maybe we should establish a convention such that user-defined > anchors can never conflict with javadoc-generated anchors. Using an > embedded "-" (as in this proposal) in user-defined anchors is a good start. > It never occurred to me that use of "-" in an anchor can prevent future conflicts with java identifiers. This is another reason to use multi-word anchors with "-" as separator, which I was already personally leaning towards. > A secondary proposal would be to have doclint check for potential clashes. > Even though we may use access filters to restrict the set of elements > included in any documentation, it should never be good to facilitate > clashes that may be caused by non-default options or non-default tools. > Javadoc runs with -private over all the sources needs a lower bar than with the default, but certain classes of errors like broken links should be made impossible by design of the release process. From stuart.marks at oracle.com Wed Mar 21 21:21:04 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Wed, 21 Mar 2018 14:21:04 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: <47458469-2A63-4EA5-A5D6-CEFACC2CBA22@oracle.com> References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> <24C4893C-DCDB-4C93-BD8A-E491F38B8BA5@oracle.com> <737113AA-08DC-4E04-A9CA-51A0A18ED970@oracle.com> <3C4A921F-F063-4A87-B65F-81E7538DD498@oracle.com> <3e48e0ea-10b2-e290-d8d5-41b404d80374@oracle.com> <0e17eb45-5284-09c4-eb53-ffb5669c372c@oracle.com> <47458469-2A63-4EA5-A5D6-CEFACC2CBA22@oracle.com> Message-ID: <11ad5528-588c-bfc4-cffa-85436cb94048@oracle.com> On 3/21/18 1:27 PM, Brian Burkhalter wrote: > On Mar 21, 2018, at 1:23 PM, Stuart Marks > wrote: >>> Perhaps instead the verbiage just needs to be changed to, e.g., >>> >>> ?The implementation in this class simply invokes {@link >>> #write(byte[],int,int) write(b, 0, b.length)}.? >> I don't think you want to specify this detail about the implementation. >> >> Consider a possible future refactoring, where writeBytes() calls some >> internal method instead of calling write(b, 0, b.length). This might be done, >> for example, to leverage an intrinsic, or to avoid unnecessary bounds checks, >> or for some other reason we can't imagine at the moment. >> >> Such a refactoring would be prohibited by an @implSpec. > Why then not an @implNote instead of an @apiNote? The statement that was proposed: This method is equivalent to write(b, 0, b.length). is a statement about the semantics of writeBytes(b). Put another way, it states that the requirements on the behavior of writeBytes(b) are equivalent to those on write(b, 0, b.length). Those are statements about the API. I don't think anything needs to be said about implementation. s'marks From brian.burkhalter at oracle.com Wed Mar 21 21:23:18 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Wed, 21 Mar 2018 14:23:18 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: <11ad5528-588c-bfc4-cffa-85436cb94048@oracle.com> References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> <24C4893C-DCDB-4C93-BD8A-E491F38B8BA5@oracle.com> <737113AA-08DC-4E04-A9CA-51A0A18ED970@oracle.com> <3C4A921F-F063-4A87-B65F-81E7538DD498@oracle.com> <3e48e0ea-10b2-e290-d8d5-41b404d80374@oracle.com> <0e17eb45-5284-09c4-eb53-ffb5669c372c@oracle.com> <47458469-2A63-4EA5-A5D6-CEFACC2CBA22@oracle.com> <11ad5528-588c-bfc4-cffa-85436cb94048@oracle.com> Message-ID: <6AEEFE73-B143-4201-AB6F-9E2B97CB6217@oracle.com> On Mar 21, 2018, at 2:21 PM, Stuart Marks wrote: >>> Such a refactoring would be prohibited by an @implSpec. >> Why then not an @implNote instead of an @apiNote? > The statement that was proposed: > This method is equivalent to write(b, 0, b.length). > is a statement about the semantics of writeBytes(b). Put another way, it states that the requirements on the behavior of writeBytes(b) are equivalent to those on write(b, 0, b.length). Those are statements about the API. > > I don't think anything needs to be said about implementation. I can see what you are saying now. It would be good to have comments from someone else as well. Thanks, Brian From jonathan.gibbons at oracle.com Wed Mar 21 21:26:27 2018 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 21 Mar 2018 14:26:27 -0700 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: References: <557d65e1-3498-afbc-dd0c-8a21869c2a58@oracle.com> <5AB2C796.9080001@oracle.com> Message-ID: On 3/21/18 2:18 PM, Martin Buchholz wrote: > > > On Wed, Mar 21, 2018 at 1:59 PM, Jonathan Gibbons > > wrote: > > > I think that maybe we should establish a convention such that > user-defined anchors can never conflict with javadoc-generated > anchors. Using an embedded "-" (as in this proposal) in > user-defined anchors is a good start. > > > It never occurred to me that use of "-" in an anchor can prevent > future conflicts with java identifiers.? This is another reason to use > multi-word anchors with "-" as separator, which I was already > personally leaning towards. If you're (still) using javadoc with -html4, then the set of legal characters in an id is limited, and javadoc makes use of '-' to encode signatures, so you're still somewhat at risk for a clash. But, if you use -html5, the set of characters is much less limited ("no spaces") and javadoc does not resort to encoding with `-`. All of which says, "use '-' and HTML5". > A secondary proposal would be to have doclint check for potential > clashes. Even though we may use access filters to restrict the set > of elements included in any documentation, it should never be good > to facilitate clashes that may be caused by non-default options or > non-default tools. > > > Javadoc runs with -private over all the sources needs a lower bar than > with the default, but certain classes of errors like broken links > should be made impossible by design of the release process. I foresee an investigation and potential cleanup :-) -- Jon From Alan.Bateman at oracle.com Wed Mar 21 21:28:06 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 21 Mar 2018 21:28:06 +0000 Subject: RFR (JDK11/doc-only) 8199176: Accessibility issues in java.base docs In-Reply-To: <5AB2ADB9.8080909@oracle.com> References: <5AB2ADB9.8080909@oracle.com> Message-ID: <551fd76a-bd69-3186-865f-b38ade2a5ba6@oracle.com> On 21/03/2018 19:08, Joe Wang wrote: > : > > *Item 3*: Heading leavels should only increase by one > ??? This is due to the javadoc tool generates a header with an > addition of headings, in this particular case,

. The fix for this > particular case is to replace the

s with

. I assume this has the effect of increasing the size of the headings. Does it look okay? I assume many of these usages of h3 choose that to avoid heading in very large font. -Alan From jonathan.gibbons at oracle.com Wed Mar 21 21:39:54 2018 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Wed, 21 Mar 2018 14:39:54 -0700 Subject: RFR (JDK11/doc-only) 8199176: Accessibility issues in java.base docs In-Reply-To: <551fd76a-bd69-3186-865f-b38ade2a5ba6@oracle.com> References: <5AB2ADB9.8080909@oracle.com> <551fd76a-bd69-3186-865f-b38ade2a5ba6@oracle.com> Message-ID: <37c2ae02-38da-a8e4-9efe-3b7d817fcb87@oracle.com> On 3/21/18 2:28 PM, Alan Bateman wrote: > On 21/03/2018 19:08, Joe Wang wrote: >> : >> >> *Item 3*: Heading leavels should only increase by one >> ??? This is due to the javadoc tool generates a header with an >> addition of headings, in this particular case,

. The fix for this >> particular case is to replace the

s with

. > I assume this has the effect of increasing the size of the headings. > Does it look okay? I assume many of these usages of h3 choose that to > avoid heading in very large font. > > -Alan I know accessibility fixes are important, but usability is important too.? The uses of h3 were previously consistent across different pages. We could remediate the problem either by figuring a design that has javadoc put a similar set of headers on every page (thus rendering this changeset unnecessary) or else changing the stylesheet so that

on a package-summary page looks the same as

on a class page (which sounds icky, even as I type it.) -- Jon From mandy.chung at oracle.com Wed Mar 21 22:38:51 2018 From: mandy.chung at oracle.com (mandy chung) Date: Wed, 21 Mar 2018 15:38:51 -0700 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: <5AB2C796.9080001@oracle.com> References: <557d65e1-3498-afbc-dd0c-8a21869c2a58@oracle.com> <5AB2C796.9080001@oracle.com> Message-ID: <0495fb9d-ac8e-bbca-37e0-1cb7688ad809@oracle.com> On 3/21/18 1:59 PM, Jonathan Gibbons wrote: > > > On 03/21/2018 01:39 PM, mandy chung wrote: >> >> >> On 3/21/18 10:26 AM, David Lloyd wrote: >>> I see it with IntelliJ IDEA when I pop up "quick JavaDoc" on, say, >>> defineClass and then click on "binary name"; it's actually using the >>> sources, rather than generated JavaDoc. >> >> I don't object to do this renaming as I favor this more explicit id.? >> However you will hit the same issue if another class names an anchor >> conflicts with its private member.?? Can you configure IntelliJ to >> generate public/protected elements to avoid this issue? >> Mandy > > Mandy, > > I think that maybe we should establish a convention such that > user-defined anchors can never conflict with javadoc-generated > anchors. Using an embedded "-" (as in this proposal) in user-defined > anchors is a good start. > > A secondary proposal would be to have doclint check for potential > clashes. Even though we may use access filters to restrict the set of > elements included in any documentation, it should never be good to > facilitate clashes that may be caused by non-default options or > non-default tools. > I forgot that you are on this list. This is a good idea.? This is what I was planning to brainstorm with you what we could do to help catch this and generate clean javadoc including private elements. Mandy From huizhe.wang at oracle.com Wed Mar 21 22:47:03 2018 From: huizhe.wang at oracle.com (Joe Wang) Date: Wed, 21 Mar 2018 15:47:03 -0700 Subject: RFR (JDK11/doc-only) 8199176: Accessibility issues in java.base docs In-Reply-To: <37c2ae02-38da-a8e4-9efe-3b7d817fcb87@oracle.com> References: <5AB2ADB9.8080909@oracle.com> <551fd76a-bd69-3186-865f-b38ade2a5ba6@oracle.com> <37c2ae02-38da-a8e4-9efe-3b7d817fcb87@oracle.com> Message-ID: They look ok. They actually go better with the package name when they are just 1 level down instead of 2, that is,

rather than

for the titles when the package name is

. If we don't want the strong emphasis on the titles, we could lower the package name generated by javadoc to

instead of

. Then we could keep the

s. Most of the package-info pages have already used

for titles, which is why we're fixing only a handful of them here. Consider: *Currently using

:* https://docs.oracle.com/javase/10/docs/api//java/io/package-summary.html https://docs.oracle.com/javase/10/docs/api//java/lang/invoke/package-summary.html In the later page, it actually started with

: ?

Summary of relevant Java Virtual Machine changes

*Currently using

:* https://docs.oracle.com/javase/10/docs/api//javax/xml/transform/package-summary.html -Joe On 3/21/2018 2:39 PM, Jonathan Gibbons wrote: > > > On 3/21/18 2:28 PM, Alan Bateman wrote: >> On 21/03/2018 19:08, Joe Wang wrote: >>> : >>> >>> *Item 3*: Heading leavels should only increase by one >>> ??? This is due to the javadoc tool generates a header with an >>> addition of headings, in this particular case,

. The fix for >>> this particular case is to replace the

s with

. >> I assume this has the effect of increasing the size of the headings. >> Does it look okay? I assume many of these usages of h3 choose that to >> avoid heading in very large font. >> >> -Alan > > I know accessibility fixes are important, but usability is important > too.? The uses of h3 were previously consistent across different pages. > > We could remediate the problem either by figuring a design that has > javadoc put a similar set of headers on every page (thus rendering > this changeset unnecessary) or else changing the stylesheet so that >

on a package-summary page looks the same as

on a class page > (which sounds icky, even as I type it.) > > -- Jon > From martinrb at google.com Wed Mar 21 23:00:25 2018 From: martinrb at google.com (Martin Buchholz) Date: Wed, 21 Mar 2018 16:00:25 -0700 Subject: [11] [PATCH] 9053056: Anchor name conflict in ClassLoader JavaDoc In-Reply-To: <0495fb9d-ac8e-bbca-37e0-1cb7688ad809@oracle.com> References: <557d65e1-3498-afbc-dd0c-8a21869c2a58@oracle.com> <5AB2C796.9080001@oracle.com> <0495fb9d-ac8e-bbca-37e0-1cb7688ad809@oracle.com> Message-ID: Hmmm... it's a hard problem because we intentionally have invalid html in our private javadoc, since it's designed primarily for human readers, e.g. error: malformed HTML [javadoc] * Precondition and postcondition: 0 <= i < modulus. jsr166 has: [javadoc] 86 errors [javadoc] 780 warnings ... the world wants to be able to use markdown in javadoc ... From james at lightbend.com Thu Mar 22 00:09:45 2018 From: james at lightbend.com (James Roper) Date: Thu, 22 Mar 2018 11:09:45 +1100 Subject: Reactive Streams utility API In-Reply-To: References: Message-ID: Hi all, We've created a reference implementation. It's been done in such a way that implementation of new features (stages) is quite straight forward, there is an abstraction that does the hard work of handling concurrency, the reactive streams spec conformance, and managing demand and buffering, and error handling, and then individual stages (eg, map, filter, flatMap) are implemented using a very easy to use API (note, this API/abstraction is all private, internal to the reference implementation). Rudimentary tests on performance show that it's not terrible compared to other reactive streams implementations, with a number of clear optimization paths identified should we decide that's necessary. I believe this proposal is now close to complete - the remaining work is: * Decide what scope beyond JDK8 streams it should support - while this decision is not trivial, the amount of work required to actually add these to the API and implement in the reference implementation is trivial. * Fill out the TCK with more rigorous verification. * Create some rigorous benchmarks. I'm not sure what should be done next. I have talked to a number of people who are either involved in, or are writing APIs that use Reactive Streams in private, and interest seems high. Also, there is general consensus in public discussions in the Jakarta EE/MicroProfile communities that an API like this would be very valuable in the JDK. The API of course could be done in Jakarta EE instead, but given that Reactive Streams is part of and used by the JDK, and given that the JDK8 Streams API is part of the JDK, Jakarta EE would seem an odd place to put this library - it essentially would mean that to make effective use of JDK libraries that use Reactive Streams (eg HTTP client, possibly java.sql2 aka ADBA), you need to use Jakarta EE (or some third party streaming library). So unless there's any major feedback coming here on this list, I'd like to put this forward as a JEP. Regards, James On 15 March 2018 at 12:24, James Roper wrote: > Hi all, > > An update on this. We've now filled out the API with feature parity with > the JDK8 Streams API - for operators that make sense in Reactive Streams. > We've provided example implementations of the API backed by both Akka > Streams and rxjava, showing that it can be widely implemented. The TCK > still needs some work, but covers the major features, and comprehensively > covers all publishers/subscribers with the Reactive Streams TCK (so > comprehensive that we actually found two Reactive Streams TCK violations in > Akka Streams with this, and a couple in rxjava too). > > There are two major areas of work left to get something that would be > ready to be a candidate for a final API. The first is to produce a zero > dependency reference implementation of the API. This is what I plan on > starting on next. > > The second is to decide what additional operators and generators the API > should provide. So far, the scope has been mostly limited to a subset of > the JDK8 Streams scope, only a few additional API pieces have been created, > such as a few variations on flatMap (one that supports CompletionStage, and > one that supports Iterable). There are a number of other features for > consideration to provide basic necessary functionality for this API, here's > some examples off the top of my head (some of these can already be > implemented in terms of other stages already provided): > > * A cancelled subscriber (useful for cleaning up hot publishers) > * An ignoring subscriber (useful when you do the actual work in a previous > stage of the graph, such as mapping to completion stages) > * Error handling subscribers and/or processors > * Termination listening subscribers and/or processors > * A processor that wraps a subscriber and publisher > * The ability to merge streams - so far only concat is provided, and all > flatMaps are essentially concatenations, merge variants may be useful > (though introduce a lot of complexity, such as specifying breadth) > * The ability to split streams into sub streams - a use case for this is > in parsing a stream that contains potentially large sub streams, like > parsing a multipart/form-data body > * Batching of elements in a stream, based on predicate, influenced by > backpressure or based on a scheduled tick > * Scheduled features such as emitting ticks, rate limiting, etc > * The ability to control buffering and asynchronous boundaries within a > graph > * Naming of stages for debug/error reporting/monitoring purposes > > Not all of the above may be absolutely necessary, but should be > considered, and there may be other features as well that would be useful to > consider. > > Please visit the repo and any feedback would be much appreciated: > > https://github.com/lightbend/reactive-streams-utils > > Regards, > > James > > On 8 March 2018 at 03:59, Brian Goetz wrote: > >> To answer the questions at the bottom: the next step is to start working >> on this and get folks excited about contributing. There's plenty of time >> for process later, but filing a JEP or creating a project shouldn't be a >> barrier to innovating. >> >> >> On 2/28/2018 10:33 PM, James Roper wrote: >> >>> Hi all, >>> >>> We've put together a simple proposal for this. Please read the README for >>> an introduction to this proposal. >>> >>> https://github.com/lightbend/reactive-streams-utils >>> >>> Regards, >>> >>> James >>> >>> On 22 February 2018 at 11:47, James Roper wrote: >>> >>> Hi all, >>>> >>>> This is an email to give people a heads up that we'd like to look at >>>> creating an API, in the same vein as the JDK8 Streams API, for building >>>> reactive streams (a la JDK9 juc.Flow). Our goals for this are: >>>> >>>> * To fill a gap in the JDK where if a developer wants to do even the >>>> simplest of things with a JDK9 juc.Flow, such as map or filter, they >>>> need >>>> to bring in a third party library that implements that. >>>> * To produce an API that can build Publishers, Subscribers, Processors, >>>> and complete graphs, for the purposes of consuming APIs that use >>>> reactive >>>> streams (for example, JDK9 Http Client). >>>> * To produce an API that aligns closely with ju.stream.Stream, using it >>>> for inspiration for naming, scope, general API shape, and other aspects. >>>> The purpose of this goal is to ensure familiarity of Java developers >>>> with >>>> the new API, and to limit the number of concepts Java developers need to >>>> understand to do the different types of streaming offered by the JDK. >>>> * To produce an API that can be implemented by multiple providers >>>> (including an RI in the JDK itself), using the ServiceLoader mechanism >>>> to >>>> provide and load a default implementation (while allowing custom >>>> implementations to be manually provided). There are a lot of concerns >>>> that >>>> each different streams implementation provides and implements, beyond >>>> streaming, for example monitoring/tracing, concurrency modelling, >>>> buffering >>>> strategies, performance aspects of the streams handling including >>>> fusing, >>>> and context (eg thread local) propagation. This will allow libraries to >>>> use >>>> and provide contracts based on this API without depending on a >>>> particular >>>> implementation, and allows developers to select the implementation that >>>> meets their needs. >>>> >>>> Non goals: >>>> >>>> * To produce a kitchen sink of utilities for working with reactive >>>> streams. There already exist a number of reactive streams >>>> implementations >>>> that seek to meet this goal (eg, Akka Streams, Reactor, RxJava), and >>>> once >>>> you go past the basics (map, filter, collect), and start dealing with >>>> things like fan in/out, cycles, restarting, etc, the different >>>> approaches >>>> to solving this start to vary greatly. The JDK should provide enough to >>>> be >>>> useful for typical every day streaming use cases, with developers being >>>> able to select a third party library for anything more advanced. >>>> >>>> We will update this list when we have something ready for public review. >>>> This probably won't be far off. Our hope is that we can propose this as >>>> a >>>> JEP. >>>> >>>> Regards, >>>> >>>> James >>>> >>>> -- >>>> *James Roper* >>>> *Senior Octonaut* >>>> >>>> Lightbend ? Build reactive apps! >>>> Twitter: @jroper >>>> >>>> >>> >>> >> > > > -- > *James Roper* > *Senior Octonaut* > > Lightbend ? Build reactive apps! > Twitter: @jroper > -- *James Roper* *Senior Octonaut* Lightbend ? Build reactive apps! Twitter: @jroper From stuart.marks at oracle.com Thu Mar 22 00:51:43 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Wed, 21 Mar 2018 17:51:43 -0700 Subject: [11] RFR: 8193128: Reduce number of implementation classes returned by List/Set/Map.of() In-Reply-To: <98bb59c5-c091-a90d-723e-1a0ce1d6df93@oracle.com> References: <7d367ca5-2915-bd80-8247-c748260f93c8@oracle.com> <461185061.1582235.1512601042847.JavaMail.zimbra@u-pem.fr> <8746a7ab-4c1c-98fc-a0ba-05594bce794c@oracle.com> <71b8baf0-0f4b-2e64-36d9-610e2286b59e@oracle.com> <4ec012ce-cd0c-003b-c20a-4c77e317e40f@gmail.com> <14910571-3cc8-75a5-9f80-8d633b23ac4b@oracle.com> <94ea8e2e-418c-4408-2dc2-7bea1ca099d4@gmail.com> <2845d01f-742a-bcfe-330c-5fbd586eaf88@oracle.com> <1bcb7c02-5ce0-be4f-e28c-842f229004bc@gmail.com> <98bb59c5-c091-a90d-723e-1a0ce1d6df93@oracle.com> Message-ID: <97367d24-f411-0a75-677d-93e9d213ef94@oracle.com> Hi Claes, I'm finally finally getting back to this. I reviewed the current state of the patch located here: http://cr.openjdk.java.net/~redestad/8193128/open.06/ I think this is mostly fine as it is. There are some things about it that could be adjusted, but none of them stand in the way of it going in. If you want to take care of any of these items before pushing, that'd be great, otherwise they can be handled separately later. * AbstractImmutableCollection and AbstractImmutableSet are in the "List Implementations" section of the file. Seems like AIC ought to be moved to the top, since it's common to List and Set, and AIS ought to be moved to the "Set Implementations" section. This is just location in the file, not nesting level. * The SubList constructors that are overloaded based on the type of the 1st arg (List vs SubList) seems subtle and error-prone. I misread the code the first time I saw it. Seems like it would be preferable to have well-named static factory methods, each calling a policy-free (private) constructor. * Should SubList.size be final? Should any of the SubList fields be @Stable? * Does the SubList class need to nested within AbstractImmutableList? Note that it also extends AIL, so I don't think nesting gives it access to anything that it doesn't already have. Plus it includes an anonymous inner class based on ListIterator, which is a fourth level of nested classes. It'd be good to flatten this out a bit if possible. * The instance returned by SubList.iterator() is also a ListIterator. Hmmm. But I'm also wondering if SubList's iterators can be shared somehow with AIL's Itr and ListItr. * Several indexOf tests are added to ListFactories.java. Are these redundant with the indexOf tests that were added to MOAT? Let me know what, if any, you fix up before pushing, and I'll track the rest. Thanks, s'marks From andrey.x.nazarov at oracle.com Thu Mar 22 01:12:35 2018 From: andrey.x.nazarov at oracle.com (Andrey Nazarov) Date: Wed, 21 Mar 2018 18:12:35 -0700 Subject: RFR: 8196750 [Testbug] tools/launcher tests need to tolerate unrelated warnings Message-ID: <24606B9C-62ED-47F4-9805-EA9F6EEB47CF@oracle.com> Hi, Please review fix in launcher tests. Review: http://cr.openjdk.java.net/~anazarov/JDK-8196750/webrev/ Bug: https://bugs.openjdk.java.net/browse/JDK-8196750?filter=-1 ?Thanks, Andrei From david.holmes at oracle.com Thu Mar 22 02:13:48 2018 From: david.holmes at oracle.com (David Holmes) Date: Thu, 22 Mar 2018 12:13:48 +1000 Subject: RFR: 8196750 [Testbug] tools/launcher tests need to tolerate unrelated warnings In-Reply-To: <24606B9C-62ED-47F4-9805-EA9F6EEB47CF@oracle.com> References: <24606B9C-62ED-47F4-9805-EA9F6EEB47CF@oracle.com> Message-ID: <84decb80-8b3c-bf61-d6f7-6deaa8bcb9ea@oracle.com> Hi Andrei, On 22/03/2018 11:12 AM, Andrey Nazarov wrote: > Hi, > > Please review fix in launcher tests. > > Review: http://cr.openjdk.java.net/~anazarov/JDK-8196750/webrev/ > Bug: https://bugs.openjdk.java.net/browse/JDK-8196750?filter=-1 test/jdk/tools/launcher/ToolsOpts.java I don't understand how the change fixes the problem. IIUC the problem is that the test expects the output to consist of the command-line passed to the tool. Instead if it contains a Warning from the VM, it won't match and so we fail. The new code no longer uses a String[] and no longer assumes that output[i] == args[i], but it still searches the current "output" value for a match with one of the args. But that will still fail if what we actually have is a Warning. ?? I would have expected to see the Warning strings filtered out more directly. The other test change seems reasonable. Thanks, David > ?Thanks, > Andrei > From xu.y.yin at oracle.com Thu Mar 22 03:16:49 2018 From: xu.y.yin at oracle.com (Chris Yin) Date: Thu, 22 Mar 2018 11:16:49 +0800 Subject: RFR 8198882: Add 10 JNDI tests to com/sun/jndi/dns/AttributeTests/ Message-ID: <370A8106-5EE5-4420-9C5F-F415475D2809@oracle.com> Please review the changes to add 10 JNDI tests to com/sun/jndi/dns/AttributeTests/, thanks bug: https://bugs.openjdk.java.net/browse/JDK-8198882 webrev: http://cr.openjdk.java.net/~xyin/8198882/webrev.00/ Regards, Chris From david.holmes at oracle.com Thu Mar 22 03:18:59 2018 From: david.holmes at oracle.com (David Holmes) Date: Thu, 22 Mar 2018 13:18:59 +1000 Subject: RFR: 8196750 [Testbug] tools/launcher tests need to tolerate unrelated warnings In-Reply-To: <58404584-6d18-4f87-9b80-383541240549@email.android.com> References: <58404584-6d18-4f87-9b80-383541240549@email.android.com> Message-ID: <43e4fc10-8c86-6a5b-9b27-4fd666630631@oracle.com> On 22/03/2018 12:52 PM, Andrei Nazarov wrote: > On Mar 21, 2018 19:13, David Holmes wrote: > > Hi Andrei, > > On 22/03/2018 11:12 AM, Andrey Nazarov wrote: > > Hi, > > > > Please review fix in launcher tests. > > > > Review: http://cr.openjdk.java.net/~anazarov/JDK-8196750/webrev/ > > Bug: https://bugs.openjdk.java.net/browse/JDK-8196750?filter=-1 > > test/jdk/tools/launcher/ToolsOpts.java > > I don't understand how the change fixes the problem. IIUC the > problem is > that the test expects the output to consist of the command-line passed > to the tool. Instead if it contains a Warning from the VM, it won't > match and so we fail. The new code no longer uses a String[] and no > longer assumes that output[i] == args[i], > > output now is List and > output.get(j).equals(arg[j]) has the same sematics. > The difference is that it *searches* args as a line in the output, so it > would skip any Warnings lines. So for each arg it searches the entire output. Okay I see now. Thanks, David ----- > Output is scanned once so it checks order of args as well. > > -- Andrei > > it still searches the > current "output" value for a match with one of the args. But that will > still fail if what we actually have is a Warning. ?? I would have > expected to see the Warning strings filtered out more directly. > > The other test change seems reasonable. > > Thanks, > David > > > ?Thanks, > >?? Andrei > > > > From kumar.x.srinivasan at oracle.com Thu Mar 22 14:18:24 2018 From: kumar.x.srinivasan at oracle.com (Kumar Srinivasan) Date: Thu, 22 Mar 2018 07:18:24 -0700 Subject: RFR: 8196750 [Testbug] tools/launcher tests need to tolerate unrelated warnings In-Reply-To: <84decb80-8b3c-bf61-d6f7-6deaa8bcb9ea@oracle.com> References: <24606B9C-62ED-47F4-9805-EA9F6EEB47CF@oracle.com> <84decb80-8b3c-bf61-d6f7-6deaa8bcb9ea@oracle.com> Message-ID: <5AB3BB30.3010305@oracle.com> David, Why would the VM emit these warnings if the deprecated vm flag is not being used ? Andrey, As for the reviews I am ok with InfoStreams, wrt. ToolOpts it is not at all apparent, maybe more comments explaining what is going on ? Kumar > Hi Andrei, > > On 22/03/2018 11:12 AM, Andrey Nazarov wrote: >> Hi, >> >> Please review fix in launcher tests. >> >> Review: http://cr.openjdk.java.net/~anazarov/JDK-8196750/webrev/ >> Bug: https://bugs.openjdk.java.net/browse/JDK-8196750?filter=-1 > > test/jdk/tools/launcher/ToolsOpts.java > > I don't understand how the change fixes the problem. IIUC the problem > is that the test expects the output to consist of the command-line > passed to the tool. Instead if it contains a Warning from the VM, it > won't match and so we fail. The new code no longer uses a String[] and > no longer assumes that output[i] == args[i], but it still searches the > current "output" value for a match with one of the args. But that will > still fail if what we actually have is a Warning. ?? I would have > expected to see the Warning strings filtered out more directly. > > The other test change seems reasonable. > > Thanks, > David > >> ?Thanks, >> Andrei >> From Roger.Riggs at Oracle.com Thu Mar 22 15:02:01 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 22 Mar 2018 11:02:01 -0400 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: <6AEEFE73-B143-4201-AB6F-9E2B97CB6217@oracle.com> References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> <24C4893C-DCDB-4C93-BD8A-E491F38B8BA5@oracle.com> <737113AA-08DC-4E04-A9CA-51A0A18ED970@oracle.com> <3C4A921F-F063-4A87-B65F-81E7538DD498@oracle.com> <3e48e0ea-10b2-e290-d8d5-41b404d80374@oracle.com> <0e17eb45-5284-09c4-eb53-ffb5669c372c@oracle.com> <47458469-2A63-4EA5-A5D6-CEFACC2CBA22@oracle.com> <11ad5528-588c-bfc4-cffa-85436cb94048@oracle.com> <6AEEFE73-B143-4201-AB6F-9E2B97CB6217@oracle.com> Message-ID: <98287a37-ae76-2d00-0365-6ea6903a8e9b@Oracle.com> Hi Brian, The use of the word 'equivalent' regardless of the context, only says the behavior is the same it does not mandate the implementation except that it behaves the same. Since the behavior of the method is already specified, adding the 'equivalent' statement only makes it easier for the developer to understand the behavior so it would be fine in an apiNote or just part of the description.? Either way, from a conformance point of view, the statement should be ignored. If it was in an @implSpec clause, then I'd expect to be able to write a test that checks that the behavior is the same using only the API and not making any assumption about that the API invokes. $.02, Roger On 3/21/2018 5:23 PM, Brian Burkhalter wrote: > On Mar 21, 2018, at 2:21 PM, Stuart Marks wrote: > >>>> Such a refactoring would be prohibited by an @implSpec. >>> Why then not an @implNote instead of an @apiNote? >> The statement that was proposed: >> This method is equivalent to write(b, 0, b.length). >> is a statement about the semantics of writeBytes(b). Put another way, it states that the requirements on the behavior of writeBytes(b) are equivalent to those on write(b, 0, b.length). Those are statements about the API. >> >> I don't think anything needs to be said about implementation. > I can see what you are saying now. It would be good to have comments from someone else as well. > > Thanks, > > Brian From brian.burkhalter at oracle.com Thu Mar 22 15:15:29 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Thu, 22 Mar 2018 08:15:29 -0700 Subject: RFR 8180410: ByteArrayOutputStream should not throw IOExceptions In-Reply-To: <98287a37-ae76-2d00-0365-6ea6903a8e9b@Oracle.com> References: <36627ECC-7E5E-45B3-88AA-E8581101852A@oracle.com> <199917CC-F0DE-4086-A66A-ED58E939F1A0@oracle.com> <3a138459-fc4c-f88a-6a8c-64d317f52c55@oracle.com> <6AF8335C-1905-424C-8D19-70C2DE02920C@oracle.com> <24C4893C-DCDB-4C93-BD8A-E491F38B8BA5@oracle.com> <737113AA-08DC-4E04-A9CA-51A0A18ED970@oracle.com> <3C4A921F-F063-4A87-B65F-81E7538DD498@oracle.com> <3e48e0ea-10b2-e290-d8d5-41b404d80374@oracle.com> <0e17eb45-5284-09c4-eb53-ffb5669c372c@oracle.com> <47458469-2A63-4EA5-A5D6-CEFACC2CBA22@oracle.com> <11ad5528-588c-bfc4-cffa-85436cb94048@oracle.com> <6AEEFE73-B143-4201-AB6F-9E2B97CB6217@oracle.com> <98287a37-ae76-2d00-0365-6ea6903a8e9b@Oracle.com> Message-ID: Hi Roger, Thanks for the comments. It seems like we have agreement on using @apiNote instead of @implSpec. Brian On Mar 22, 2018, at 8:02 AM, Roger Riggs wrote: > The use of the word 'equivalent' regardless of the context, only says the behavior is the same > it does not mandate the implementation except that it behaves the same. > > Since the behavior of the method is already specified, adding the 'equivalent' statement > only makes it easier for the developer to understand the behavior so it would be > fine in an apiNote or just part of the description. Either way, from a conformance point of > view, the statement should be ignored. > > If it was in an @implSpec clause, then I'd expect to be able to write a test that > checks that the behavior is the same using only the API and not making any assumption > about that the API invokes. From Roger.Riggs at Oracle.com Thu Mar 22 15:24:03 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Thu, 22 Mar 2018 11:24:03 -0400 Subject: RFR 8199756 : Simplify language, country, script, and variant property initialization In-Reply-To: References: <3fd6536d-f5d7-ff7d-106d-14eda3e72c71@oracle.com> Message-ID: <79cdebc1-c9fb-6108-e9a9-010003fe7978@Oracle.com> Hi, The webrev[1] has been updated with a new test added to verify that if a user.* property is defined on the command line, then corresponding property has the same value and correctly overrides any value from the platform. After verification, the comment (line 304) has been corrected to refer to the platform native encoding of bytes -> strings instead of the user.* I18N properties. The tests for properties and locales have been run and passed in a variety of locales. Thanks, Roger [1] http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ On 3/19/2018 6:38 PM, David Holmes wrote: > Hi Roger, > > On 19/03/2018 11:55 PM, Roger Riggs wrote: >> Hi Alan, >> >> The original changeset [1] is most easily viewed in the jdk-8u repo. >> >> The comment and placement of the removes of the properties and the >> code to re-set them >> around the call to the JVM_InitProperties (which sets properties from >> the >> -D arguments among others), seem to indicate that the previous property >> values are irrelevant. > > Not irrelevant: defaults. > >> >> The remaining question is whether there are any side effects or usage >> of those >> four property values between the time they are initially set and when >> they are removed. >> The code in System.initProperties is straightforward and the bulk of >> the code >> is simply setting property values, with one interspersed call to >> initialize the sun.jnu_encoding. >> ?From all appearances there are no side effects or uses of the >> initially set values of those four properties. > > I would have expected these values to possibly have an impact on > InitalizeEncoding and subsequent use of PUTPROP_ForPlatformNString. > Else why set them early then unset them again? Or maybe they impact > any error messages that might arise in this stage of initialization? > > I expect any issues here to be extremely subtle - as Alan indicated. > If there is any path to Java code that may try to read and use these > properties then they need to be set. > > And if these are truly unnecessary then doesn't that imply that > placing them in sprops via GetJavaProperties in the first place is > also unnecessary? > > Has this been extensively tested on a non-English Windows system? And > do we even have tests for various initialization failures? > > David > ----- > >> Thanks, Roger >> >> [1] https://bugs.openjdk.java.net/browse/JDK-4700857 >> ???? RFE: separating user locale and user interface locale >> >> On 3/17/18 5:46 AM, Alan Bateman wrote: >>> On 16/03/2018 20:32, Roger Riggs wrote: >>>> Please review a small simplification of the initialization of >>>> System properties for >>>> language, country, script, and variant.? Some steps for >>>> initializing them are unnecessary. >>>> The tests pass; a careful review would be appreciated so as to >>>> avoid breakage. >>>> >>>> Webrev: >>>> http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ >>>> >>>> Issue: >>>> ? https://bugs.openjdk.java.net/browse/JDK-8199756 >>> There are subtle interactions with how system properties are set in >>> the VM and on the command line which will take a bit effort to >>> research in order to review this and be satisfied that the change is >>> safe. Have you dug into the ancient history and bugs to see why it >>> was done this way? >>> >>> -Alan >> From claes.redestad at oracle.com Thu Mar 22 15:42:31 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 22 Mar 2018 16:42:31 +0100 Subject: [11] RFR: 8193128: Reduce number of implementation classes returned by List/Set/Map.of() In-Reply-To: <97367d24-f411-0a75-677d-93e9d213ef94@oracle.com> References: <7d367ca5-2915-bd80-8247-c748260f93c8@oracle.com> <461185061.1582235.1512601042847.JavaMail.zimbra@u-pem.fr> <8746a7ab-4c1c-98fc-a0ba-05594bce794c@oracle.com> <71b8baf0-0f4b-2e64-36d9-610e2286b59e@oracle.com> <4ec012ce-cd0c-003b-c20a-4c77e317e40f@gmail.com> <14910571-3cc8-75a5-9f80-8d633b23ac4b@oracle.com> <94ea8e2e-418c-4408-2dc2-7bea1ca099d4@gmail.com> <2845d01f-742a-bcfe-330c-5fbd586eaf88@oracle.com> <1bcb7c02-5ce0-be4f-e28c-842f229004bc@gmail.com> <98bb59c5-c091-a90d-723e-1a0ce1d6df93@oracle.com> <97367d24-f411-0a75-677d-93e9d213ef94@oracle.com> Message-ID: <11204870-baaa-214b-8667-39262d08eaf8@oracle.com> Hi Stuart, On 2018-03-22 01:51, Stuart Marks wrote: > Hi Claes, > > I'm finally finally getting back to this. I reviewed the current state > of the patch located here: > > ??? http://cr.openjdk.java.net/~redestad/8193128/open.06/ > > I think this is mostly fine as it is. thanks! > There are some things about it that could be adjusted, but none of > them stand in the way of it going in. If you want to take care of any > of these items before pushing, that'd be great, otherwise they can be > handled separately later. > > * AbstractImmutableCollection and AbstractImmutableSet are in the > "List Implementations" section of the file. Seems like AIC ought to be > moved to the top, since it's common to List and Set, and AIS ought to > be moved to the "Set Implementations" section. This is just location > in the file, not nesting level. Fixed. > > * The SubList constructors that are overloaded based on the type of > the 1st arg (List vs SubList) seems subtle and error-prone. I misread > the code the first time I saw it. Seems like it would be preferable to > have well-named static factory methods, each calling a policy-free > (private) constructor. Introduced SubList.fromList and SubList.fromSubList to make this clearer. > > * Should SubList.size be final? Should any of the SubList fields be > @Stable? Good point, this aligns the implementation more with the other immutable classes here. > > * Does the SubList class need to nested within AbstractImmutableList? > Note that it also extends AIL, so I don't think nesting gives it > access to anything that it doesn't already have. Plus it includes an > anonymous inner class based on ListIterator, which is a fourth level > of nested classes. It'd be good to flatten this out a bit if possible. Trivially flattened, done. > > * The instance returned by SubList.iterator() is also a ListIterator. > Hmmm. But I'm also wondering if SubList's iterators can be shared > somehow with AIL's Itr and ListItr. With an immutable backing store a ListIterator doesn't add any capabilities over Iterator that can be considered unsafe or unsavory - adds a few methods, no extra state - so it should be performance neutral. I actually think the Itr/ListItr also ought to be consolidated into one class implementing ListIterator, now that you made me look... I'm open to the possibility I'm wrong on this one, though. :-) Turning ListItr into a static class whose constructors take the List being iterated over is performance neutral here as we only rely on List::get(i), which enable sharing implementation with SubList. > > * Several indexOf tests are added to ListFactories.java. Are these > redundant with the indexOf tests that were added to MOAT? Right, I added the generic indexOf tests to MOAT later, and it does seem the ListFactories.indexOf test are now redundant. Removed. Webrev: http://cr.openjdk.java.net/~redestad/8193128/open.07/ Incremental: http://cr.openjdk.java.net/~redestad/8193128/open.06_to_07/ Hope these incremental changes look OK. /Claes From naoto.sato at oracle.com Thu Mar 22 15:40:00 2018 From: naoto.sato at oracle.com (Naoto Sato) Date: Thu, 22 Mar 2018 08:40:00 -0700 Subject: RFR 8199756 : Simplify language, country, script, and variant property initialization In-Reply-To: <79cdebc1-c9fb-6108-e9a9-010003fe7978@Oracle.com> References: <3fd6536d-f5d7-ff7d-106d-14eda3e72c71@oracle.com> <79cdebc1-c9fb-6108-e9a9-010003fe7978@Oracle.com> Message-ID: <8169bbfc-63fc-3756-2a68-9c1ceda2a9ac@oracle.com> Looks good. Thanks Roger for the clean up. Naoto On 3/22/18 8:24 AM, Roger Riggs wrote: > Hi, > > The webrev[1] has been updated with a new test added to verify that if a > user.* property > is defined on the command line, then corresponding property has the same > value and > correctly overrides any value from the platform. > > After verification, the comment (line 304) has been corrected to refer > to the platform native > encoding of bytes -> strings instead of the user.* I18N properties. > > The tests for properties and locales have been run and passed in a > variety of locales. > > Thanks, Roger > > [1] http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ > > > On 3/19/2018 6:38 PM, David Holmes wrote: >> Hi Roger, >> >> On 19/03/2018 11:55 PM, Roger Riggs wrote: >>> Hi Alan, >>> >>> The original changeset [1] is most easily viewed in the jdk-8u repo. >>> >>> The comment and placement of the removes of the properties and the >>> code to re-set them >>> around the call to the JVM_InitProperties (which sets properties from >>> the >>> -D arguments among others), seem to indicate that the previous property >>> values are irrelevant. >> >> Not irrelevant: defaults. >> >>> >>> The remaining question is whether there are any side effects or usage >>> of those >>> four property values between the time they are initially set and when >>> they are removed. >>> The code in System.initProperties is straightforward and the bulk of >>> the code >>> is simply setting property values, with one interspersed call to >>> initialize the sun.jnu_encoding. >>> ?From all appearances there are no side effects or uses of the >>> initially set values of those four properties. >> >> I would have expected these values to possibly have an impact on >> InitalizeEncoding and subsequent use of PUTPROP_ForPlatformNString. >> Else why set them early then unset them again? Or maybe they impact >> any error messages that might arise in this stage of initialization? >> >> I expect any issues here to be extremely subtle - as Alan indicated. >> If there is any path to Java code that may try to read and use these >> properties then they need to be set. >> >> And if these are truly unnecessary then doesn't that imply that >> placing them in sprops via GetJavaProperties in the first place is >> also unnecessary? >> >> Has this been extensively tested on a non-English Windows system? And >> do we even have tests for various initialization failures? >> >> David >> ----- >> >>> Thanks, Roger >>> >>> [1] https://bugs.openjdk.java.net/browse/JDK-4700857 >>> ???? RFE: separating user locale and user interface locale >>> >>> On 3/17/18 5:46 AM, Alan Bateman wrote: >>>> On 16/03/2018 20:32, Roger Riggs wrote: >>>>> Please review a small simplification of the initialization of >>>>> System properties for >>>>> language, country, script, and variant.? Some steps for >>>>> initializing them are unnecessary. >>>>> The tests pass; a careful review would be appreciated so as to >>>>> avoid breakage. >>>>> >>>>> Webrev: >>>>> http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ >>>>> >>>>> Issue: >>>>> ? https://bugs.openjdk.java.net/browse/JDK-8199756 >>>> There are subtle interactions with how system properties are set in >>>> the VM and on the command line which will take a bit effort to >>>> research in order to review this and be satisfied that the change is >>>> safe. Have you dug into the ancient history and bugs to see why it >>>> was done this way? >>>> >>>> -Alan >>> > From dhiller at twitter.com Thu Mar 22 14:05:11 2018 From: dhiller at twitter.com (Dean Hiller) Date: Thu, 22 Mar 2018 08:05:11 -0600 Subject: revisiting MDC in slf4j broken because of CompletableFuture Message-ID: slf4j is pretty much the defacto logging standard these days allowing one to bring in libraries using any logging framework. (commons logging fell short and had classloading bugs). Summary: MDC works fine in twitter scala Futures but not java CompletableFutures. Unfortunately, one of the best features(brought over from log4j which is also broken now) is the MDC. The MDC no longer works with CompletableFutures so people will have to move to scala where it does work. Documentation on MDC if you don't know what that is.... https://logback.qos.ch/manual/mdc.html or for a more concrete example, as a developer a request comes in and you set MDC.put("requestId", requestId) and now whenever you log, that request id is added to your log line. No developer has to 'remember' to add it every time he adds a log statement. This is due to the lack of Local.java file that should exist and transfer context over the .thenApply/.thenCompose methods like twitter Futures has in scala land. (see Local.scala in twitter Futures and the twitter Future code for how this works) In scala, it works and we have all the same methods as CompletableFuture for the most part and yes, we can't transfer the context over some methods, but at least our MDC in scala servers is not broken. Lack of this feature is forcing our hand to code in scala where it is not broken. ie. we need logging and we definitely need the request id or client id or whatever attached automatically to every log(as humans have trouble remembering to add it themselves every single time). thanks for reconsidering, Dean On Tue, May 23, 2017 at 10:20 AM, Dean Hiller wrote: > All, this post is all about 3rd party code that I do not control so > therefore the solutions above do not work as those libraries may predate my > library. more specifically..... > > Martin, > If I roll my own slf4j MDC only works in my code and stops working in > 3rd party code! because the 3rd party code does not transfer the context. > > Viktor, > You hit the head on the nail with "It's easy to lose context when > intermediate libraries/Executors". This is solved on twitter futures until > we hit libraries not using twitter futures because no matter the executor, > the future transfers the context for us the way it was written. > > "It's unclear what fan-in behaviors like zip, merge etc mean in terms > of what the local values should be?" > This is a very good question. I wonder what twitter futures do here. I > would be ok with dropping the context in this case or combining it. I do > not really care yet here since I have not run into it but it is a very good > question and would need a lot of thought > > Josh, > I cannot expect all 3rd party libraries that are brought in will be > using ContextPropagatingExecutor so that solution breaks down as Viktor > eludes to. > > Alex, > tuples do not solve the issue. in fact twitter futures have a > Local.scala file that does solve the issue. The main issue is 3rd party > code and having the context continue into "unknown code" using > CompletableFuture. I cannot control that code BUT want every log.info in > that code to use and log the request id. it is awesome at twitter as I can > just follow that request id in the logs. If CompletableFuture had such a > context, I could transfer this info into it and into the 3rd party java > libraries. > > I am writing a webserver for fun based on CompletableFutures and therefore > cannot control the controllers as the app developer writes that and the > request id stops getting logged on the request path which is mostly > .thenApply and .thenCompose. even if the Controllers do you my future, > they will bring in libraries NOT using my future :( > > thanks > Dean > > > > > > On Tue, May 23, 2017 at 3:12 AM, Alex Otenko > wrote: > >> Why would someone want to rely on state they cannot control? >> >> Is the idea to subvert some API that does not provide a way to pass >> state? This is strange especially in the context of Scala, where you can >> easily form tuples. >> >> Alex >> >> On 22 May 2017, at 20:44, Martin Buchholz wrote: >> >> There's not likely to be any support for local context anywhere in >> java.util.concurrent, but it seems not too hard to roll your own support >> with a custom executor to be used with CompletableFuture that kept track of >> any local context. >> >> On Fri, May 19, 2017 at 1:16 PM, Pavel Rappo >> wrote: >> >>> General questions on concurrency in Java should be asked here: >>> >>> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest >>> >>> > On 18 May 2017, at 21:57, Dean Hiller wrote: >>> > >>> > Way more detail here... >>> > >>> > http://stackoverflow.com/questions/37933713/does-completable >>> future-have-a-corresponding-local-context >>> > >>> > So I was wondering if this was going to be added at some point to the >>> jdk >>> > as I could not figure out how to set something so it was still >>> available on >>> > the thread at a later time when traversing async thenCompose, >>> thenAccept. >>> > >>> > thanks, >>> > Dean >>> >>> >> _______________________________________________ >> Concurrency-interest mailing list >> Concurrency-interest at cs.oswego.edu >> http://cs.oswego.edu/mailman/listinfo/concurrency-interest >> >> >> > From ralph.goers at dslextreme.com Thu Mar 22 17:13:28 2018 From: ralph.goers at dslextreme.com (Ralph Goers) Date: Thu, 22 Mar 2018 10:13:28 -0700 Subject: revisiting MDC in slf4j broken because of CompletableFuture In-Reply-To: References: Message-ID: Log4j 2 supports a ThreadContext which is analogous to the SLF4J MDC. Both are based on ThreadLocal variables. If I understand what you are saying, the problem is that ThreadLocals do not work as you you would expect when using CompleteableFutures? Ralph > On Mar 22, 2018, at 7:05 AM, Dean Hiller wrote: > > slf4j is pretty much the defacto logging standard these days allowing one > to bring in libraries using any logging framework. (commons logging fell > short and had classloading bugs). > > Summary: MDC works fine in twitter scala Futures but not java > CompletableFutures. > > Unfortunately, one of the best features(brought over from log4j which is > also broken now) is the MDC. The MDC no longer works with > CompletableFutures so people will have to move to scala where it does work. > > Documentation on MDC if you don't know what that is.... > https://logback.qos.ch/manual/mdc.html > > or for a more concrete example, as a developer a request comes in and you > set MDC.put("requestId", requestId) and now whenever you log, that request > id is added to your log line. No developer has to 'remember' to add it > every time he adds a log statement. > > This is due to the lack of Local.java file that should exist and transfer > context over the .thenApply/.thenCompose methods like twitter Futures has > in scala land. (see Local.scala in twitter Futures and the twitter Future > code for how this works) > > In scala, it works and we have all the same methods as CompletableFuture > for the most part and yes, we can't transfer the context over some methods, > but at least our MDC in scala servers is not broken. > > Lack of this feature is forcing our hand to code in scala where it is not > broken. ie. we need logging and we definitely need the request id or > client id or whatever attached automatically to every log(as humans have > trouble remembering to add it themselves every single time). > > thanks for reconsidering, > Dean > > On Tue, May 23, 2017 at 10:20 AM, Dean Hiller wrote: > >> All, this post is all about 3rd party code that I do not control so >> therefore the solutions above do not work as those libraries may predate my >> library. more specifically..... >> >> Martin, >> If I roll my own slf4j MDC only works in my code and stops working in >> 3rd party code! because the 3rd party code does not transfer the context. >> >> Viktor, >> You hit the head on the nail with "It's easy to lose context when >> intermediate libraries/Executors". This is solved on twitter futures until >> we hit libraries not using twitter futures because no matter the executor, >> the future transfers the context for us the way it was written. >> >> "It's unclear what fan-in behaviors like zip, merge etc mean in terms >> of what the local values should be?" >> This is a very good question. I wonder what twitter futures do here. I >> would be ok with dropping the context in this case or combining it. I do >> not really care yet here since I have not run into it but it is a very good >> question and would need a lot of thought >> >> Josh, >> I cannot expect all 3rd party libraries that are brought in will be >> using ContextPropagatingExecutor so that solution breaks down as Viktor >> eludes to. >> >> Alex, >> tuples do not solve the issue. in fact twitter futures have a >> Local.scala file that does solve the issue. The main issue is 3rd party >> code and having the context continue into "unknown code" using >> CompletableFuture. I cannot control that code BUT want every log.info in >> that code to use and log the request id. it is awesome at twitter as I can >> just follow that request id in the logs. If CompletableFuture had such a >> context, I could transfer this info into it and into the 3rd party java >> libraries. >> >> I am writing a webserver for fun based on CompletableFutures and therefore >> cannot control the controllers as the app developer writes that and the >> request id stops getting logged on the request path which is mostly >> .thenApply and .thenCompose. even if the Controllers do you my future, >> they will bring in libraries NOT using my future :( >> >> thanks >> Dean >> >> >> >> >> >> On Tue, May 23, 2017 at 3:12 AM, Alex Otenko >> wrote: >> >>> Why would someone want to rely on state they cannot control? >>> >>> Is the idea to subvert some API that does not provide a way to pass >>> state? This is strange especially in the context of Scala, where you can >>> easily form tuples. >>> >>> Alex >>> >>> On 22 May 2017, at 20:44, Martin Buchholz wrote: >>> >>> There's not likely to be any support for local context anywhere in >>> java.util.concurrent, but it seems not too hard to roll your own support >>> with a custom executor to be used with CompletableFuture that kept track of >>> any local context. >>> >>> On Fri, May 19, 2017 at 1:16 PM, Pavel Rappo >>> wrote: >>> >>>> General questions on concurrency in Java should be asked here: >>>> >>>> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest >>>> >>>>> On 18 May 2017, at 21:57, Dean Hiller wrote: >>>>> >>>>> Way more detail here... >>>>> >>>>> http://stackoverflow.com/questions/37933713/does-completable >>>> future-have-a-corresponding-local-context >>>>> >>>>> So I was wondering if this was going to be added at some point to the >>>> jdk >>>>> as I could not figure out how to set something so it was still >>>> available on >>>>> the thread at a later time when traversing async thenCompose, >>>> thenAccept. >>>>> >>>>> thanks, >>>>> Dean >>>> >>>> >>> _______________________________________________ >>> Concurrency-interest mailing list >>> Concurrency-interest at cs.oswego.edu >>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest >>> >>> >>> >> > From martinrb at google.com Thu Mar 22 17:35:51 2018 From: martinrb at google.com (Martin Buchholz) Date: Thu, 22 Mar 2018 10:35:51 -0700 Subject: [PATCH] unnecessary null check inside of java.lang.Boolean.valueOf(String) In-Reply-To: References: <6635141521367007@web3g.yandex.ru> Message-ID: If parseBoolean is worth optimizing (barely, but only because Boolean is very popular), then let's do the usual ASCII bit-twiddling: public static boolean parseBoolean(String s) { // return "true".equalsIgnoreCase(s); return s != null && s.length() == 4 && (s.charAt(0) | 0x20) == 't' && (s.charAt(1) | 0x20) == 'r' && (s.charAt(2) | 0x20) == 'u' && (s.charAt(3) | 0x20) == 'e'; } ModuleBootstrap is not worth changing because any system property is very unlikely to be set - the null check will trip 99.9999% of the time. From ralph.goers at dslextreme.com Thu Mar 22 17:40:19 2018 From: ralph.goers at dslextreme.com (Ralph Goers) Date: Thu, 22 Mar 2018 10:40:19 -0700 Subject: revisiting MDC in slf4j broken because of CompletableFuture In-Reply-To: References: Message-ID: <85B3F22F-A5B5-42C5-AC91-7D64CF1151AF@dslextreme.com> Having read several of the threads I think I have a better understanding of the problem. This sounds similar to problems that occur with any application that has a way of doing asynchronous processing with with thread pools. Java has unfortunately not provided a good way that I know of to pass a ThreadLocal from one thread to a worker thread. I am guessing that is what you are really asking for is some sort of property on the Executor that tells it to pass the ThreadLocals from one thread to the worker that performs action on its behalf. Ralph > On Mar 22, 2018, at 10:13 AM, Ralph Goers wrote: > > Log4j 2 supports a ThreadContext which is analogous to the SLF4J MDC. Both are based on ThreadLocal variables. If I understand what you are saying, the problem is that ThreadLocals do not work as you you would expect when using CompleteableFutures? > > Ralph > >> On Mar 22, 2018, at 7:05 AM, Dean Hiller wrote: >> >> slf4j is pretty much the defacto logging standard these days allowing one >> to bring in libraries using any logging framework. (commons logging fell >> short and had classloading bugs). >> >> Summary: MDC works fine in twitter scala Futures but not java >> CompletableFutures. >> >> Unfortunately, one of the best features(brought over from log4j which is >> also broken now) is the MDC. The MDC no longer works with >> CompletableFutures so people will have to move to scala where it does work. >> >> Documentation on MDC if you don't know what that is.... >> https://logback.qos.ch/manual/mdc.html >> >> or for a more concrete example, as a developer a request comes in and you >> set MDC.put("requestId", requestId) and now whenever you log, that request >> id is added to your log line. No developer has to 'remember' to add it >> every time he adds a log statement. >> >> This is due to the lack of Local.java file that should exist and transfer >> context over the .thenApply/.thenCompose methods like twitter Futures has >> in scala land. (see Local.scala in twitter Futures and the twitter Future >> code for how this works) >> >> In scala, it works and we have all the same methods as CompletableFuture >> for the most part and yes, we can't transfer the context over some methods, >> but at least our MDC in scala servers is not broken. >> >> Lack of this feature is forcing our hand to code in scala where it is not >> broken. ie. we need logging and we definitely need the request id or >> client id or whatever attached automatically to every log(as humans have >> trouble remembering to add it themselves every single time). >> >> thanks for reconsidering, >> Dean >> >> On Tue, May 23, 2017 at 10:20 AM, Dean Hiller wrote: >> >>> All, this post is all about 3rd party code that I do not control so >>> therefore the solutions above do not work as those libraries may predate my >>> library. more specifically..... >>> >>> Martin, >>> If I roll my own slf4j MDC only works in my code and stops working in >>> 3rd party code! because the 3rd party code does not transfer the context. >>> >>> Viktor, >>> You hit the head on the nail with "It's easy to lose context when >>> intermediate libraries/Executors". This is solved on twitter futures until >>> we hit libraries not using twitter futures because no matter the executor, >>> the future transfers the context for us the way it was written. >>> >>> "It's unclear what fan-in behaviors like zip, merge etc mean in terms >>> of what the local values should be?" >>> This is a very good question. I wonder what twitter futures do here. I >>> would be ok with dropping the context in this case or combining it. I do >>> not really care yet here since I have not run into it but it is a very good >>> question and would need a lot of thought >>> >>> Josh, >>> I cannot expect all 3rd party libraries that are brought in will be >>> using ContextPropagatingExecutor so that solution breaks down as Viktor >>> eludes to. >>> >>> Alex, >>> tuples do not solve the issue. in fact twitter futures have a >>> Local.scala file that does solve the issue. The main issue is 3rd party >>> code and having the context continue into "unknown code" using >>> CompletableFuture. I cannot control that code BUT want every log.info in >>> that code to use and log the request id. it is awesome at twitter as I can >>> just follow that request id in the logs. If CompletableFuture had such a >>> context, I could transfer this info into it and into the 3rd party java >>> libraries. >>> >>> I am writing a webserver for fun based on CompletableFutures and therefore >>> cannot control the controllers as the app developer writes that and the >>> request id stops getting logged on the request path which is mostly >>> .thenApply and .thenCompose. even if the Controllers do you my future, >>> they will bring in libraries NOT using my future :( >>> >>> thanks >>> Dean >>> >>> >>> >>> >>> >>> On Tue, May 23, 2017 at 3:12 AM, Alex Otenko >>> wrote: >>> >>>> Why would someone want to rely on state they cannot control? >>>> >>>> Is the idea to subvert some API that does not provide a way to pass >>>> state? This is strange especially in the context of Scala, where you can >>>> easily form tuples. >>>> >>>> Alex >>>> >>>> On 22 May 2017, at 20:44, Martin Buchholz wrote: >>>> >>>> There's not likely to be any support for local context anywhere in >>>> java.util.concurrent, but it seems not too hard to roll your own support >>>> with a custom executor to be used with CompletableFuture that kept track of >>>> any local context. >>>> >>>> On Fri, May 19, 2017 at 1:16 PM, Pavel Rappo >>>> wrote: >>>> >>>>> General questions on concurrency in Java should be asked here: >>>>> >>>>> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest >>>>> >>>>>> On 18 May 2017, at 21:57, Dean Hiller wrote: >>>>>> >>>>>> Way more detail here... >>>>>> >>>>>> http://stackoverflow.com/questions/37933713/does-completable >>>>> future-have-a-corresponding-local-context >>>>>> >>>>>> So I was wondering if this was going to be added at some point to the >>>>> jdk >>>>>> as I could not figure out how to set something so it was still >>>>> available on >>>>>> the thread at a later time when traversing async thenCompose, >>>>> thenAccept. >>>>>> >>>>>> thanks, >>>>>> Dean >>>>> >>>>> >>>> _______________________________________________ >>>> Concurrency-interest mailing list >>>> Concurrency-interest at cs.oswego.edu >>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest >>>> >>>> >>>> >>> >> > > > From philip.race at oracle.com Thu Mar 22 17:41:09 2018 From: philip.race at oracle.com (Phil Race) Date: Thu, 22 Mar 2018 10:41:09 -0700 Subject: RFR: 8200072: Remove un-needed qualified export from java.base to java.desktop Message-ID: <3e7b9daa-246b-e3ef-4c15-52a6e0969c18@oracle.com> Bug: https://bugs.openjdk.java.net/browse/JDK-8200072 webrev: http://cr.openjdk.java.net/~prr/8200072/ jdk.internal.math is exported to java.desktop but it has never been needed, except briefly, in the jake forest during JDK 9 development. History is in the bug. -phil. From Alan.Bateman at oracle.com Thu Mar 22 17:44:07 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 22 Mar 2018 17:44:07 +0000 Subject: RFR: 8200072: Remove un-needed qualified export from java.base to java.desktop In-Reply-To: <3e7b9daa-246b-e3ef-4c15-52a6e0969c18@oracle.com> References: <3e7b9daa-246b-e3ef-4c15-52a6e0969c18@oracle.com> Message-ID: On 22/03/2018 17:41, Phil Race wrote: > Bug: https://bugs.openjdk.java.net/browse/JDK-8200072 > webrev: http://cr.openjdk.java.net/~prr/8200072/ > > jdk.internal.math is exported to java.desktop but it has never been > needed, > except briefly, in the jake forest during JDK 9 development. > History is in the bug. Looks good. We should run jdeps periodically to catch these. -Alan From mandy.chung at oracle.com Thu Mar 22 17:54:46 2018 From: mandy.chung at oracle.com (mandy chung) Date: Thu, 22 Mar 2018 10:54:46 -0700 Subject: RFR: 8200072: Remove un-needed qualified export from java.base to java.desktop In-Reply-To: <3e7b9daa-246b-e3ef-4c15-52a6e0969c18@oracle.com> References: <3e7b9daa-246b-e3ef-4c15-52a6e0969c18@oracle.com> Message-ID: <824b02ea-d1d9-c640-265d-1ecddf0f5223@oracle.com> +1 Mandy On 3/22/18 10:41 AM, Phil Race wrote: > Bug: https://bugs.openjdk.java.net/browse/JDK-8200072 > webrev: http://cr.openjdk.java.net/~prr/8200072/ > > jdk.internal.math is exported to java.desktop but it has never been > needed, > except briefly, in the jake forest during JDK 9 development. > History is in the bug. > > -phil. From shade at redhat.com Thu Mar 22 17:56:04 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Thu, 22 Mar 2018 18:56:04 +0100 Subject: RFR 8200118: [test] String concat tests should test toString() application order Message-ID: <41637232-1c8f-f465-cf18-2f99f6d9df45@redhat.com> Bug: https://bugs.openjdk.java.net/browse/JDK-8200118 Webrev: http://cr.openjdk.java.net/~shade/8200118/webrev.01/ This adds the relevant test to StringConcat family of tests, which asserts all strategies do the right thing. There was a bug in MH_* strategies caused by the already fixed bug in filterArguments [1], which this test was supposed to find, if existed before. Testing: run-test with jdk/jdk, run-test before/after filterArguments fix in jdk-updates/jdk10u Thanks, -Aleksey [1] https://bugs.openjdk.java.net/browse/JDK-8194554 From mandy.chung at oracle.com Thu Mar 22 18:01:39 2018 From: mandy.chung at oracle.com (mandy chung) Date: Thu, 22 Mar 2018 11:01:39 -0700 Subject: RFR: 8200072: Remove un-needed qualified export from java.base to java.desktop In-Reply-To: References: <3e7b9daa-246b-e3ef-4c15-52a6e0969c18@oracle.com> Message-ID: <3f3a9424-22a9-e1d4-ff6f-14c67d0f35c1@oracle.com> On 3/22/18 10:44 AM, Alan Bateman wrote: > > > On 22/03/2018 17:41, Phil Race wrote: >> Bug: https://bugs.openjdk.java.net/browse/JDK-8200072 >> webrev: http://cr.openjdk.java.net/~prr/8200072/ >> >> jdk.internal.math is exported to java.desktop but it has never been >> needed, >> except briefly, in the jake forest during JDK 9 development. >> History is in the bug. > Looks good. We should run jdeps periodically to catch these. > Yes we should set up such automated task.? jdeps --check $MODULE will find unused qualified exports. $ jdeps --check java.base java.base (jrt:/java.base) ? [Unused qualified exports in java.base] ??? exports jdk.internal.math to java.desktop ??? exports jdk.internal.misc to java.sql,jdk.jdeps ??? exports jdk.internal.org.objectweb.asm to jdk.internal.vm.ci ??? exports jdk.internal.perf to java.desktop ??? exports jdk.internal.vm.annotation to jdk.internal.vm.ci ??? exports sun.net.www to jdk.incubator.httpclient ??? exports sun.nio.ch to jdk.sctp ??? exports sun.nio.cs to java.desktop ??? exports sun.reflect.misc to java.xml ??? exports sun.security.x509 to jdk.security.auth ??? exports sun.text.resources to jdk.localedata We will have to go through them if any package is accessed through reflection.?? I create JDK-8200121 to track this. Mandy From stuart.marks at oracle.com Thu Mar 22 18:03:38 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 22 Mar 2018 11:03:38 -0700 Subject: [11] RFR: 8193128: Reduce number of implementation classes returned by List/Set/Map.of() In-Reply-To: <11204870-baaa-214b-8667-39262d08eaf8@oracle.com> References: <7d367ca5-2915-bd80-8247-c748260f93c8@oracle.com> <8746a7ab-4c1c-98fc-a0ba-05594bce794c@oracle.com> <71b8baf0-0f4b-2e64-36d9-610e2286b59e@oracle.com> <4ec012ce-cd0c-003b-c20a-4c77e317e40f@gmail.com> <14910571-3cc8-75a5-9f80-8d633b23ac4b@oracle.com> <94ea8e2e-418c-4408-2dc2-7bea1ca099d4@gmail.com> <2845d01f-742a-bcfe-330c-5fbd586eaf88@oracle.com> <1bcb7c02-5ce0-be4f-e28c-842f229004bc@gmail.com> <98bb59c5-c091-a90d-723e-1a0ce1d6df93@oracle.com> <97367d24-f411-0a75-677d-93e9d213ef94@oracle.com> <11204870-baaa-214b-8667-39262d08eaf8@oracle.com> Message-ID: <01bac684-e8f8-9bdb-6670-2903eefa19a6@oracle.com> Great, thanks for doing those cleanups! They're small, but I think they make a big difference in the comprehensibility of the code, because of all the little classes in this file. Looks like you went ahead and consolidated everything into ListItr, which is used by the iterator() and listIterator() methods of both AIL and SubList. Seems reasonable. The mutator methods are all blocked, so this should be fine. One small issue is with this comment: 295 * Constructs a sublist of an arbitrary AbstractList, which is 296 * not a SubList itself. This supports sublists of an arbitrary AbstractImmutableList, not AbstractList. Other than this, I think you're good to go! Thanks, s'marks On 3/22/18 8:42 AM, Claes Redestad wrote: > Hi Stuart, > > On 2018-03-22 01:51, Stuart Marks wrote: >> Hi Claes, >> >> I'm finally finally getting back to this. I reviewed the current state of the >> patch located here: >> >> ??? http://cr.openjdk.java.net/~redestad/8193128/open.06/ >> >> I think this is mostly fine as it is. > > thanks! > >> There are some things about it that could be adjusted, but none of them stand >> in the way of it going in. If you want to take care of any of these items >> before pushing, that'd be great, otherwise they can be handled separately later. >> >> * AbstractImmutableCollection and AbstractImmutableSet are in the "List >> Implementations" section of the file. Seems like AIC ought to be moved to the >> top, since it's common to List and Set, and AIS ought to be moved to the "Set >> Implementations" section. This is just location in the file, not nesting level. > > Fixed. > >> >> * The SubList constructors that are overloaded based on the type of the 1st >> arg (List vs SubList) seems subtle and error-prone. I misread the code the >> first time I saw it. Seems like it would be preferable to have well-named >> static factory methods, each calling a policy-free (private) constructor. > > Introduced SubList.fromList and SubList.fromSubList to make this clearer. > >> >> * Should SubList.size be final? Should any of the SubList fields be @Stable? > > Good point, this aligns the implementation more with the other immutable classes > here. > >> >> * Does the SubList class need to nested within AbstractImmutableList? Note >> that it also extends AIL, so I don't think nesting gives it access to anything >> that it doesn't already have. Plus it includes an anonymous inner class based >> on ListIterator, which is a fourth level of nested classes. It'd be good to >> flatten this out a bit if possible. > > Trivially flattened, done. > >> >> * The instance returned by SubList.iterator() is also a ListIterator. Hmmm. >> But I'm also wondering if SubList's iterators can be shared somehow with AIL's >> Itr and ListItr. > > With an immutable backing store a ListIterator doesn't add any capabilities over > Iterator that can be considered unsafe or unsavory - adds a few methods, no > extra state - so it should be performance neutral. I actually think the > Itr/ListItr also ought to be consolidated into one class implementing > ListIterator, now that you made me look... I'm open to the possibility I'm wrong > on this one, though. :-) > > Turning ListItr into a static class whose constructors take the List being > iterated over is performance neutral here as we only rely on List::get(i), which > enable sharing implementation with SubList. > >> >> * Several indexOf tests are added to ListFactories.java. Are these redundant >> with the indexOf tests that were added to MOAT? > > Right, I added the generic indexOf tests to MOAT later, and it does seem the > ListFactories.indexOf test are now redundant. Removed. > > Webrev: http://cr.openjdk.java.net/~redestad/8193128/open.07/ > Incremental: http://cr.openjdk.java.net/~redestad/8193128/open.06_to_07/ > > Hope these incremental changes look OK. > > /Claes From mandy.chung at oracle.com Thu Mar 22 18:19:24 2018 From: mandy.chung at oracle.com (mandy chung) Date: Thu, 22 Mar 2018 11:19:24 -0700 Subject: RFR 8199756 : Simplify language, country, script, and variant property initialization In-Reply-To: <79cdebc1-c9fb-6108-e9a9-010003fe7978@Oracle.com> References: <3fd6536d-f5d7-ff7d-106d-14eda3e72c71@oracle.com> <79cdebc1-c9fb-6108-e9a9-010003fe7978@Oracle.com> Message-ID: <96968660-6b6e-ad2a-0f9e-94551af2c0c5@oracle.com> Hi Roger, Thanks for adding the test that should have created when JDK-4700857 was resolved. Since this fix changes the setting of those i18n properties to later after JVM_InitProperties is called, it would be a good opportunity to set these properties in Java and remove the native fillI18nProps method.? What it needs from Java is to get the value of sprops->display_XXX, one option is to define a Java class holding these displayXXX fields that are set by initProperties directly. What do you think? Mandy On 3/22/18 8:24 AM, Roger Riggs wrote: > Hi, > > The webrev[1] has been updated with a new test added to verify that if > a user.* property > is defined on the command line, then corresponding property has the > same value and > correctly overrides any value from the platform. > > After verification, the comment (line 304) has been corrected to refer > to the platform native > encoding of bytes -> strings instead of the user.* I18N properties. > > The tests for properties and locales have been run and passed in a > variety of locales. > > Thanks, Roger > > [1] http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ > > > On 3/19/2018 6:38 PM, David Holmes wrote: >> Hi Roger, >> >> On 19/03/2018 11:55 PM, Roger Riggs wrote: >>> Hi Alan, >>> >>> The original changeset [1] is most easily viewed in the jdk-8u repo. >>> >>> The comment and placement of the removes of the properties and the >>> code to re-set them >>> around the call to the JVM_InitProperties (which sets properties >>> from the >>> -D arguments among others), seem to indicate that the previous property >>> values are irrelevant. >> >> Not irrelevant: defaults. >> >>> >>> The remaining question is whether there are any side effects or >>> usage of those >>> four property values between the time they are initially set and >>> when they are removed. >>> The code in System.initProperties is straightforward and the bulk of >>> the code >>> is simply setting property values, with one interspersed call to >>> initialize the sun.jnu_encoding. >>> ?From all appearances there are no side effects or uses of the >>> initially set values of those four properties. >> >> I would have expected these values to possibly have an impact on >> InitalizeEncoding and subsequent use of PUTPROP_ForPlatformNString. >> Else why set them early then unset them again? Or maybe they impact >> any error messages that might arise in this stage of initialization? >> >> I expect any issues here to be extremely subtle - as Alan indicated. >> If there is any path to Java code that may try to read and use these >> properties then they need to be set. >> >> And if these are truly unnecessary then doesn't that imply that >> placing them in sprops via GetJavaProperties in the first place is >> also unnecessary? >> >> Has this been extensively tested on a non-English Windows system? And >> do we even have tests for various initialization failures? >> >> David >> ----- >> >>> Thanks, Roger >>> >>> [1] https://bugs.openjdk.java.net/browse/JDK-4700857 >>> ???? RFE: separating user locale and user interface locale >>> >>> On 3/17/18 5:46 AM, Alan Bateman wrote: >>>> On 16/03/2018 20:32, Roger Riggs wrote: >>>>> Please review a small simplification of the initialization of >>>>> System properties for >>>>> language, country, script, and variant.? Some steps for >>>>> initializing them are unnecessary. >>>>> The tests pass; a careful review would be appreciated so as to >>>>> avoid breakage. >>>>> >>>>> Webrev: >>>>> http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ >>>>> >>>>> Issue: >>>>> ? https://bugs.openjdk.java.net/browse/JDK-8199756 >>>> There are subtle interactions with how system properties are set in >>>> the VM and on the command line which will take a bit effort to >>>> research in order to review this and be satisfied that the change >>>> is safe. Have you dug into the ancient history and bugs to see why >>>> it was done this way? >>>> >>>> -Alan >>> > From ralph.goers at dslextreme.com Thu Mar 22 18:27:07 2018 From: ralph.goers at dslextreme.com (Ralph Goers) Date: Thu, 22 Mar 2018 11:27:07 -0700 Subject: revisiting MDC in slf4j broken because of CompletableFuture In-Reply-To: References: <85B3F22F-A5B5-42C5-AC91-7D64CF1151AF@dslextreme.com> Message-ID: <6B4E025A-8CF3-4DAA-A265-518D2C67EA8B@dslextreme.com> My point is that I don?t think this is the only place the problem occurs. I have seen similar questions on the Log4j mailing list where users want to be able to do this for thread pools they create via Executors and don?t want to have to do the ThreadLocal propagation themselves. If a CompleteableFuture uses an Executor under the covers then it could leverage the same solution. Ralph > On Mar 22, 2018, at 11:21 AM, Dean Hiller wrote: > > I am basically asking for someone to copy the solution in twitter Future.scala(which uses Local.scala) into CompletableFuture.java, yes. > > ie. I should be able to say Local.set("something", value) and in CompletableFuture when .map is called, it will ensure the key/values are transferred across threads. Local.scala internally uses a ThreadLocal up into the point of .map/.flatMap (ie. thenApply/.thenCompose). At that point, it transfers it across threads into a new ThreadLocal. > > ie. the answer on how to do it exists here(search on Locals and see it in the respond method which is called by map and flatMap).. > > https://github.com/simonratner/twitter-util/blob/master/util-core/src/main/scala/com/twitter/util/Future.scala > > Here is the Local class that clients use and the Future uses to transfer contexts across map/flatMap > https://github.com/simonratner/twitter-util/blob/master/util-core/src/main/scala/com/twitter/util/Local.scala > > (I do apologize if you do not read scala code, but the answer is there and just in a different language) > > later, > Dean > > > On Thu, Mar 22, 2018 at 11:40 AM, Ralph Goers > wrote: > Having read several of the threads I think I have a better understanding of the problem. This sounds similar to problems that occur with any application that has a way of doing asynchronous processing with with thread pools. Java has unfortunately not provided a good way that I know of to pass a ThreadLocal from one thread to a worker thread. I am guessing that is what you are really asking for is some sort of property on the Executor that tells it to pass the ThreadLocals from one thread to the worker that performs action on its behalf. > > Ralph > > > On Mar 22, 2018, at 10:13 AM, Ralph Goers > wrote: > > > > Log4j 2 supports a ThreadContext which is analogous to the SLF4J MDC. Both are based on ThreadLocal variables. If I understand what you are saying, the problem is that ThreadLocals do not work as you you would expect when using CompleteableFutures? > > > > Ralph > > > >> On Mar 22, 2018, at 7:05 AM, Dean Hiller > wrote: > >> > >> slf4j is pretty much the defacto logging standard these days allowing one > >> to bring in libraries using any logging framework. (commons logging fell > >> short and had classloading bugs). > >> > >> Summary: MDC works fine in twitter scala Futures but not java > >> CompletableFutures. > >> > >> Unfortunately, one of the best features(brought over from log4j which is > >> also broken now) is the MDC. The MDC no longer works with > >> CompletableFutures so people will have to move to scala where it does work. > >> > >> Documentation on MDC if you don't know what that is.... > >> https://logback.qos.ch/manual/mdc.html > >> > >> or for a more concrete example, as a developer a request comes in and you > >> set MDC.put("requestId", requestId) and now whenever you log, that request > >> id is added to your log line. No developer has to 'remember' to add it > >> every time he adds a log statement. > >> > >> This is due to the lack of Local.java file that should exist and transfer > >> context over the .thenApply/.thenCompose methods like twitter Futures has > >> in scala land. (see Local.scala in twitter Futures and the twitter Future > >> code for how this works) > >> > >> In scala, it works and we have all the same methods as CompletableFuture > >> for the most part and yes, we can't transfer the context over some methods, > >> but at least our MDC in scala servers is not broken. > >> > >> Lack of this feature is forcing our hand to code in scala where it is not > >> broken. ie. we need logging and we definitely need the request id or > >> client id or whatever attached automatically to every log(as humans have > >> trouble remembering to add it themselves every single time). > >> > >> thanks for reconsidering, > >> Dean > >> > >> On Tue, May 23, 2017 at 10:20 AM, Dean Hiller > wrote: > >> > >>> All, this post is all about 3rd party code that I do not control so > >>> therefore the solutions above do not work as those libraries may predate my > >>> library. more specifically..... > >>> > >>> Martin, > >>> If I roll my own slf4j MDC only works in my code and stops working in > >>> 3rd party code! because the 3rd party code does not transfer the context. > >>> > >>> Viktor, > >>> You hit the head on the nail with "It's easy to lose context when > >>> intermediate libraries/Executors". This is solved on twitter futures until > >>> we hit libraries not using twitter futures because no matter the executor, > >>> the future transfers the context for us the way it was written. > >>> > >>> "It's unclear what fan-in behaviors like zip, merge etc mean in terms > >>> of what the local values should be?" > >>> This is a very good question. I wonder what twitter futures do here. I > >>> would be ok with dropping the context in this case or combining it. I do > >>> not really care yet here since I have not run into it but it is a very good > >>> question and would need a lot of thought > >>> > >>> Josh, > >>> I cannot expect all 3rd party libraries that are brought in will be > >>> using ContextPropagatingExecutor so that solution breaks down as Viktor > >>> eludes to. > >>> > >>> Alex, > >>> tuples do not solve the issue. in fact twitter futures have a > >>> Local.scala file that does solve the issue. The main issue is 3rd party > >>> code and having the context continue into "unknown code" using > >>> CompletableFuture. I cannot control that code BUT want every log.info in > >>> that code to use and log the request id. it is awesome at twitter as I can > >>> just follow that request id in the logs. If CompletableFuture had such a > >>> context, I could transfer this info into it and into the 3rd party java > >>> libraries. > >>> > >>> I am writing a webserver for fun based on CompletableFutures and therefore > >>> cannot control the controllers as the app developer writes that and the > >>> request id stops getting logged on the request path which is mostly > >>> .thenApply and .thenCompose. even if the Controllers do you my future, > >>> they will bring in libraries NOT using my future :( > >>> > >>> thanks > >>> Dean > >>> > >>> > >>> > >>> > >>> > >>> On Tue, May 23, 2017 at 3:12 AM, Alex Otenko > > >>> wrote: > >>> > >>>> Why would someone want to rely on state they cannot control? > >>>> > >>>> Is the idea to subvert some API that does not provide a way to pass > >>>> state? This is strange especially in the context of Scala, where you can > >>>> easily form tuples. > >>>> > >>>> Alex > >>>> > >>>> On 22 May 2017, at 20:44, Martin Buchholz > wrote: > >>>> > >>>> There's not likely to be any support for local context anywhere in > >>>> java.util.concurrent, but it seems not too hard to roll your own support > >>>> with a custom executor to be used with CompletableFuture that kept track of > >>>> any local context. > >>>> > >>>> On Fri, May 19, 2017 at 1:16 PM, Pavel Rappo > > >>>> wrote: > >>>> > >>>>> General questions on concurrency in Java should be asked here: > >>>>> > >>>>> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest > >>>>> > >>>>>> On 18 May 2017, at 21:57, Dean Hiller > wrote: > >>>>>> > >>>>>> Way more detail here... > >>>>>> > >>>>>> http://stackoverflow.com/questions/37933713/does-completable > >>>>> future-have-a-corresponding-local-context > >>>>>> > >>>>>> So I was wondering if this was going to be added at some point to the > >>>>> jdk > >>>>>> as I could not figure out how to set something so it was still > >>>>> available on > >>>>>> the thread at a later time when traversing async thenCompose, > >>>>> thenAccept. > >>>>>> > >>>>>> thanks, > >>>>>> Dean > >>>>> > >>>>> > >>>> _______________________________________________ > >>>> Concurrency-interest mailing list > >>>> Concurrency-interest at cs.oswego.edu > >>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest > >>>> > >>>> > >>>> > >>> > >> > > > > > > > > > From mandy.chung at oracle.com Thu Mar 22 18:28:10 2018 From: mandy.chung at oracle.com (mandy chung) Date: Thu, 22 Mar 2018 11:28:10 -0700 Subject: RFR: 8200072: Remove un-needed qualified export from java.base to java.desktop In-Reply-To: <570c04a1-8d6b-0b1c-1d3b-6e1e55602c0c@oracle.com> References: <3e7b9daa-246b-e3ef-4c15-52a6e0969c18@oracle.com> <3f3a9424-22a9-e1d4-ff6f-14c67d0f35c1@oracle.com> <570c04a1-8d6b-0b1c-1d3b-6e1e55602c0c@oracle.com> Message-ID: <2851234c-ba67-514b-cd48-94535deb97c7@oracle.com> Yes it needs to run all platforms because some qualified exports are platform-specific. On 3/22/18 11:22 AM, Phil Race wrote: > Seems you need to run it on all platforms to be sure. > > This one is used on Windows : > ??? exports jdk.internal.perf to java.desktop > > This one is used on Linux + Solaris : > ??? exports sun.nio.cs to java.desktop > These qualified exports should be moved to src/java.base/$OS/classes/module-info.java.extra.? Maybe you can fix this as part of JDK-8200072? Mandy > -phil. > > On 03/22/2018 11:01 AM, mandy chung wrote: >> >> >> On 3/22/18 10:44 AM, Alan Bateman wrote: >>> >>> >>> On 22/03/2018 17:41, Phil Race wrote: >>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8200072 >>>> webrev: http://cr.openjdk.java.net/~prr/8200072/ >>>> >>>> jdk.internal.math is exported to java.desktop but it has never been >>>> needed, >>>> except briefly, in the jake forest during JDK 9 development. >>>> History is in the bug. >>> Looks good. We should run jdeps periodically to catch these. >>> >> >> Yes we should set up such automated task.? jdeps --check $MODULE will >> find unused qualified exports. >> >> $ jdeps --check java.base >> java.base (jrt:/java.base) >> ? [Unused qualified exports in java.base] >> ??? exports jdk.internal.math to java.desktop >> ??? exports jdk.internal.misc to java.sql,jdk.jdeps >> ??? exports jdk.internal.org.objectweb.asm to jdk.internal.vm.ci >> ??? exports jdk.internal.perf to java.desktop >> ??? exports jdk.internal.vm.annotation to jdk.internal.vm.ci >> ??? exports sun.net.www to jdk.incubator.httpclient >> ??? exports sun.nio.ch to jdk.sctp >> ??? exports sun.nio.cs to java.desktop >> ??? exports sun.reflect.misc to java.xml >> ??? exports sun.security.x509 to jdk.security.auth >> ??? exports sun.text.resources to jdk.localedata >> >> We will have to go through them if any package is accessed through >> reflection.?? I create JDK-8200121 to track this. >> >> Mandy > From philip.race at oracle.com Thu Mar 22 18:22:48 2018 From: philip.race at oracle.com (Phil Race) Date: Thu, 22 Mar 2018 11:22:48 -0700 Subject: RFR: 8200072: Remove un-needed qualified export from java.base to java.desktop In-Reply-To: <3f3a9424-22a9-e1d4-ff6f-14c67d0f35c1@oracle.com> References: <3e7b9daa-246b-e3ef-4c15-52a6e0969c18@oracle.com> <3f3a9424-22a9-e1d4-ff6f-14c67d0f35c1@oracle.com> Message-ID: <570c04a1-8d6b-0b1c-1d3b-6e1e55602c0c@oracle.com> Seems you need to run it on all platforms to be sure. This one is used on Windows : exports jdk.internal.perf to java.desktop This one is used on Linux + Solaris : exports sun.nio.cs to java.desktop -phil. On 03/22/2018 11:01 AM, mandy chung wrote: > > > On 3/22/18 10:44 AM, Alan Bateman wrote: >> >> >> On 22/03/2018 17:41, Phil Race wrote: >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8200072 >>> webrev: http://cr.openjdk.java.net/~prr/8200072/ >>> >>> jdk.internal.math is exported to java.desktop but it has never been >>> needed, >>> except briefly, in the jake forest during JDK 9 development. >>> History is in the bug. >> Looks good. We should run jdeps periodically to catch these. >> > > Yes we should set up such automated task. jdeps --check $MODULE will > find unused qualified exports. > > $ jdeps --check java.base > java.base (jrt:/java.base) > [Unused qualified exports in java.base] > exports jdk.internal.math to java.desktop > exports jdk.internal.misc to java.sql,jdk.jdeps > exports jdk.internal.org.objectweb.asm to jdk.internal.vm.ci > exports jdk.internal.perf to java.desktop > exports jdk.internal.vm.annotation to jdk.internal.vm.ci > exports sun.net.www to jdk.incubator.httpclient > exports sun.nio.ch to jdk.sctp > exports sun.nio.cs to java.desktop > exports sun.reflect.misc to java.xml > exports sun.security.x509 to jdk.security.auth > exports sun.text.resources to jdk.localedata > > We will have to go through them if any package is accessed through > reflection. I create JDK-8200121 to track this. > > Mandy From philip.race at oracle.com Thu Mar 22 18:32:15 2018 From: philip.race at oracle.com (Phil Race) Date: Thu, 22 Mar 2018 11:32:15 -0700 Subject: RFR: 8200072: Remove un-needed qualified export from java.base to java.desktop In-Reply-To: <2851234c-ba67-514b-cd48-94535deb97c7@oracle.com> References: <3e7b9daa-246b-e3ef-4c15-52a6e0969c18@oracle.com> <3f3a9424-22a9-e1d4-ff6f-14c67d0f35c1@oracle.com> <570c04a1-8d6b-0b1c-1d3b-6e1e55602c0c@oracle.com> <2851234c-ba67-514b-cd48-94535deb97c7@oracle.com> Message-ID: <94b91058-aee7-81e7-7806-f7c6b1905bc1@oracle.com> I already pushed 8200072 but I'll file a new bug. -phil. On 03/22/2018 11:28 AM, mandy chung wrote: > Yes it needs to run all platforms because some qualified exports are > platform-specific. > > > On 3/22/18 11:22 AM, Phil Race wrote: >> Seems you need to run it on all platforms to be sure. >> >> This one is used on Windows : >> exports jdk.internal.perf to java.desktop >> >> This one is used on Linux + Solaris : >> exports sun.nio.cs to java.desktop >> > > These qualified exports should be moved to > src/java.base/$OS/classes/module-info.java.extra. Maybe you can fix > this as part of JDK-8200072? > > Mandy > >> -phil. >> >> On 03/22/2018 11:01 AM, mandy chung wrote: >>> >>> >>> On 3/22/18 10:44 AM, Alan Bateman wrote: >>>> >>>> >>>> On 22/03/2018 17:41, Phil Race wrote: >>>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8200072 >>>>> webrev: http://cr.openjdk.java.net/~prr/8200072/ >>>>> >>>>> jdk.internal.math is exported to java.desktop but it has never >>>>> been needed, >>>>> except briefly, in the jake forest during JDK 9 development. >>>>> History is in the bug. >>>> Looks good. We should run jdeps periodically to catch these. >>>> >>> >>> Yes we should set up such automated task. jdeps --check $MODULE >>> will find unused qualified exports. >>> >>> $ jdeps --check java.base >>> java.base (jrt:/java.base) >>> [Unused qualified exports in java.base] >>> exports jdk.internal.math to java.desktop >>> exports jdk.internal.misc to java.sql,jdk.jdeps >>> exports jdk.internal.org.objectweb.asm to jdk.internal.vm.ci >>> exports jdk.internal.perf to java.desktop >>> exports jdk.internal.vm.annotation to jdk.internal.vm.ci >>> exports sun.net.www to jdk.incubator.httpclient >>> exports sun.nio.ch to jdk.sctp >>> exports sun.nio.cs to java.desktop >>> exports sun.reflect.misc to java.xml >>> exports sun.security.x509 to jdk.security.auth >>> exports sun.text.resources to jdk.localedata >>> >>> We will have to go through them if any package is accessed through >>> reflection. I create JDK-8200121 to track this. >>> >>> Mandy >> > From ralph.goers at dslextreme.com Thu Mar 22 18:38:14 2018 From: ralph.goers at dslextreme.com (Ralph Goers) Date: Thu, 22 Mar 2018 11:38:14 -0700 Subject: revisiting MDC in slf4j broken because of CompletableFuture In-Reply-To: References: <85B3F22F-A5B5-42C5-AC91-7D64CF1151AF@dslextreme.com> <6B4E025A-8CF3-4DAA-A265-518D2C67EA8B@dslextreme.com> Message-ID: <74981FE3-4D87-4DE3-B98E-FB5FB3A6177C@dslextreme.com> To be clear, SLF4J only provides an MDC API and doesn?t implement the MDC. It delegates that to an implementation - Log4j 2 or Logback. Obviously, my concern would be to get Log4j 2 to work the way it needs to. If it requires additional help from the JDK library then there is only so much I can do. But if work is being asked of the JDK then, IMO, it should be general enough that it can be used for more than just CompleteableFuture. Ralph > On Mar 22, 2018, at 11:32 AM, Dean Hiller wrote: > > oh, I see > > yes, that code could be done in CompletableFuture though...Executor does not have to be touched based on the scala code I read. ie. you create a new Runnable that reads the last Local context transferring into a ThreadLocal until the next transfer is needed(at each .thenApply/.thenCompose boundaries). > > There are weird methods and I would just not worry about those except as it relates mostly to getting slf4j's MDC to work. > > On Thu, Mar 22, 2018 at 12:27 PM, Ralph Goers > wrote: > My point is that I don?t think this is the only place the problem occurs. I have seen similar questions on the Log4j mailing list where users want to be able to do this for thread pools they create via Executors and don?t want to have to do the ThreadLocal propagation themselves. If a CompleteableFuture uses an Executor under the covers then it could leverage the same solution. > > Ralph > > >> On Mar 22, 2018, at 11:21 AM, Dean Hiller > wrote: >> >> I am basically asking for someone to copy the solution in twitter Future.scala(which uses Local.scala) into CompletableFuture.java, yes. >> >> ie. I should be able to say Local.set("something", value) and in CompletableFuture when .map is called, it will ensure the key/values are transferred across threads. Local.scala internally uses a ThreadLocal up into the point of .map/.flatMap (ie. thenApply/.thenCompose). At that point, it transfers it across threads into a new ThreadLocal. >> >> ie. the answer on how to do it exists here(search on Locals and see it in the respond method which is called by map and flatMap).. >> >> https://github.com/simonratner/twitter-util/blob/master/util-core/src/main/scala/com/twitter/util/Future.scala >> >> Here is the Local class that clients use and the Future uses to transfer contexts across map/flatMap >> https://github.com/simonratner/twitter-util/blob/master/util-core/src/main/scala/com/twitter/util/Local.scala >> >> (I do apologize if you do not read scala code, but the answer is there and just in a different language) >> >> later, >> Dean >> >> >> On Thu, Mar 22, 2018 at 11:40 AM, Ralph Goers > wrote: >> Having read several of the threads I think I have a better understanding of the problem. This sounds similar to problems that occur with any application that has a way of doing asynchronous processing with with thread pools. Java has unfortunately not provided a good way that I know of to pass a ThreadLocal from one thread to a worker thread. I am guessing that is what you are really asking for is some sort of property on the Executor that tells it to pass the ThreadLocals from one thread to the worker that performs action on its behalf. >> >> Ralph >> >> > On Mar 22, 2018, at 10:13 AM, Ralph Goers > wrote: >> > >> > Log4j 2 supports a ThreadContext which is analogous to the SLF4J MDC. Both are based on ThreadLocal variables. If I understand what you are saying, the problem is that ThreadLocals do not work as you you would expect when using CompleteableFutures? >> > >> > Ralph >> > >> >> On Mar 22, 2018, at 7:05 AM, Dean Hiller > wrote: >> >> >> >> slf4j is pretty much the defacto logging standard these days allowing one >> >> to bring in libraries using any logging framework. (commons logging fell >> >> short and had classloading bugs). >> >> >> >> Summary: MDC works fine in twitter scala Futures but not java >> >> CompletableFutures. >> >> >> >> Unfortunately, one of the best features(brought over from log4j which is >> >> also broken now) is the MDC. The MDC no longer works with >> >> CompletableFutures so people will have to move to scala where it does work. >> >> >> >> Documentation on MDC if you don't know what that is.... >> >> https://logback.qos.ch/manual/mdc.html >> >> >> >> or for a more concrete example, as a developer a request comes in and you >> >> set MDC.put("requestId", requestId) and now whenever you log, that request >> >> id is added to your log line. No developer has to 'remember' to add it >> >> every time he adds a log statement. >> >> >> >> This is due to the lack of Local.java file that should exist and transfer >> >> context over the .thenApply/.thenCompose methods like twitter Futures has >> >> in scala land. (see Local.scala in twitter Futures and the twitter Future >> >> code for how this works) >> >> >> >> In scala, it works and we have all the same methods as CompletableFuture >> >> for the most part and yes, we can't transfer the context over some methods, >> >> but at least our MDC in scala servers is not broken. >> >> >> >> Lack of this feature is forcing our hand to code in scala where it is not >> >> broken. ie. we need logging and we definitely need the request id or >> >> client id or whatever attached automatically to every log(as humans have >> >> trouble remembering to add it themselves every single time). >> >> >> >> thanks for reconsidering, >> >> Dean >> >> >> >> On Tue, May 23, 2017 at 10:20 AM, Dean Hiller > wrote: >> >> >> >>> All, this post is all about 3rd party code that I do not control so >> >>> therefore the solutions above do not work as those libraries may predate my >> >>> library. more specifically..... >> >>> >> >>> Martin, >> >>> If I roll my own slf4j MDC only works in my code and stops working in >> >>> 3rd party code! because the 3rd party code does not transfer the context. >> >>> >> >>> Viktor, >> >>> You hit the head on the nail with "It's easy to lose context when >> >>> intermediate libraries/Executors". This is solved on twitter futures until >> >>> we hit libraries not using twitter futures because no matter the executor, >> >>> the future transfers the context for us the way it was written. >> >>> >> >>> "It's unclear what fan-in behaviors like zip, merge etc mean in terms >> >>> of what the local values should be?" >> >>> This is a very good question. I wonder what twitter futures do here. I >> >>> would be ok with dropping the context in this case or combining it. I do >> >>> not really care yet here since I have not run into it but it is a very good >> >>> question and would need a lot of thought >> >>> >> >>> Josh, >> >>> I cannot expect all 3rd party libraries that are brought in will be >> >>> using ContextPropagatingExecutor so that solution breaks down as Viktor >> >>> eludes to. >> >>> >> >>> Alex, >> >>> tuples do not solve the issue. in fact twitter futures have a >> >>> Local.scala file that does solve the issue. The main issue is 3rd party >> >>> code and having the context continue into "unknown code" using >> >>> CompletableFuture. I cannot control that code BUT want every log.info in >> >>> that code to use and log the request id. it is awesome at twitter as I can >> >>> just follow that request id in the logs. If CompletableFuture had such a >> >>> context, I could transfer this info into it and into the 3rd party java >> >>> libraries. >> >>> >> >>> I am writing a webserver for fun based on CompletableFutures and therefore >> >>> cannot control the controllers as the app developer writes that and the >> >>> request id stops getting logged on the request path which is mostly >> >>> .thenApply and .thenCompose. even if the Controllers do you my future, >> >>> they will bring in libraries NOT using my future :( >> >>> >> >>> thanks >> >>> Dean >> >>> >> >>> >> >>> >> >>> >> >>> >> >>> On Tue, May 23, 2017 at 3:12 AM, Alex Otenko > >> >>> wrote: >> >>> >> >>>> Why would someone want to rely on state they cannot control? >> >>>> >> >>>> Is the idea to subvert some API that does not provide a way to pass >> >>>> state? This is strange especially in the context of Scala, where you can >> >>>> easily form tuples. >> >>>> >> >>>> Alex >> >>>> >> >>>> On 22 May 2017, at 20:44, Martin Buchholz > wrote: >> >>>> >> >>>> There's not likely to be any support for local context anywhere in >> >>>> java.util.concurrent, but it seems not too hard to roll your own support >> >>>> with a custom executor to be used with CompletableFuture that kept track of >> >>>> any local context. >> >>>> >> >>>> On Fri, May 19, 2017 at 1:16 PM, Pavel Rappo > >> >>>> wrote: >> >>>> >> >>>>> General questions on concurrency in Java should be asked here: >> >>>>> >> >>>>> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest >> >>>>> >> >>>>>> On 18 May 2017, at 21:57, Dean Hiller > wrote: >> >>>>>> >> >>>>>> Way more detail here... >> >>>>>> >> >>>>>> http://stackoverflow.com/questions/37933713/does-completable >> >>>>> future-have-a-corresponding-local-context >> >>>>>> >> >>>>>> So I was wondering if this was going to be added at some point to the >> >>>>> jdk >> >>>>>> as I could not figure out how to set something so it was still >> >>>>> available on >> >>>>>> the thread at a later time when traversing async thenCompose, >> >>>>> thenAccept. >> >>>>>> >> >>>>>> thanks, >> >>>>>> Dean >> >>>>> >> >>>>> >> >>>> _______________________________________________ >> >>>> Concurrency-interest mailing list >> >>>> Concurrency-interest at cs.oswego.edu >> >>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest >> >>>> >> >>>> >> >>>> >> >>> >> >> >> > >> > >> > >> >> >> > > From roger.riggs at oracle.com Thu Mar 22 19:01:45 2018 From: roger.riggs at oracle.com (Roger Riggs) Date: Thu, 22 Mar 2018 15:01:45 -0400 Subject: RFR 8199756 : Simplify language, country, script, and variant property initialization In-Reply-To: <96968660-6b6e-ad2a-0f9e-94551af2c0c5@oracle.com> References: <3fd6536d-f5d7-ff7d-106d-14eda3e72c71@oracle.com> <79cdebc1-c9fb-6108-e9a9-010003fe7978@Oracle.com> <96968660-6b6e-ad2a-0f9e-94551af2c0c5@oracle.com> Message-ID: Hi Mandy, This is just one step in untangling and improving property initialization. I'm also working on a change similar to what you suggest to remove some/more of the upcalls and replace them with setting fields. In that case, the adjustments to the values would be handled in java. I have performance concern (as yet unmeasured)? that moving from using a mostly native encoding function (JNU_NewStringPlatform) to a Java based encoding will hurt startup performance. (its too early to be compiled). So for now, I'd like to commit this as is and work on the next step separately. Thanks, Roger On 3/22/18 2:19 PM, mandy chung wrote: > Hi Roger, > > Thanks for adding the test that should have created when JDK-4700857 > was resolved. > > Since this fix changes the setting of those i18n properties to later > after JVM_InitProperties is called, it would be a good opportunity to > set these properties in Java and remove the native fillI18nProps > method.? What it needs from Java is to get the value of > sprops->display_XXX, one option is to define a Java class holding > these displayXXX fields that are set by initProperties directly. > > What do you think? > > Mandy > > On 3/22/18 8:24 AM, Roger Riggs wrote: >> Hi, >> >> The webrev[1] has been updated with a new test added to verify that >> if a user.* property >> is defined on the command line, then corresponding property has the >> same value and >> correctly overrides any value from the platform. >> >> After verification, the comment (line 304) has been corrected to >> refer to the platform native >> encoding of bytes -> strings instead of the user.* I18N properties. >> >> The tests for properties and locales have been run and passed in a >> variety of locales. >> >> Thanks, Roger >> >> [1] http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ >> >> >> On 3/19/2018 6:38 PM, David Holmes wrote: >>> Hi Roger, >>> >>> On 19/03/2018 11:55 PM, Roger Riggs wrote: >>>> Hi Alan, >>>> >>>> The original changeset [1] is most easily viewed in the jdk-8u repo. >>>> >>>> The comment and placement of the removes of the properties and the >>>> code to re-set them >>>> around the call to the JVM_InitProperties (which sets properties >>>> from the >>>> -D arguments among others), seem to indicate that the previous >>>> property >>>> values are irrelevant. >>> >>> Not irrelevant: defaults. >>> >>>> >>>> The remaining question is whether there are any side effects or >>>> usage of those >>>> four property values between the time they are initially set and >>>> when they are removed. >>>> The code in System.initProperties is straightforward and the bulk >>>> of the code >>>> is simply setting property values, with one interspersed call to >>>> initialize the sun.jnu_encoding. >>>> ?From all appearances there are no side effects or uses of the >>>> initially set values of those four properties. >>> >>> I would have expected these values to possibly have an impact on >>> InitalizeEncoding and subsequent use of PUTPROP_ForPlatformNString. >>> Else why set them early then unset them again? Or maybe they impact >>> any error messages that might arise in this stage of initialization? >>> >>> I expect any issues here to be extremely subtle - as Alan indicated. >>> If there is any path to Java code that may try to read and use these >>> properties then they need to be set. >>> >>> And if these are truly unnecessary then doesn't that imply that >>> placing them in sprops via GetJavaProperties in the first place is >>> also unnecessary? >>> >>> Has this been extensively tested on a non-English Windows system? >>> And do we even have tests for various initialization failures? >>> >>> David >>> ----- >>> >>>> Thanks, Roger >>>> >>>> [1] https://bugs.openjdk.java.net/browse/JDK-4700857 >>>> ???? RFE: separating user locale and user interface locale >>>> >>>> On 3/17/18 5:46 AM, Alan Bateman wrote: >>>>> On 16/03/2018 20:32, Roger Riggs wrote: >>>>>> Please review a small simplification of the initialization of >>>>>> System properties for >>>>>> language, country, script, and variant.? Some steps for >>>>>> initializing them are unnecessary. >>>>>> The tests pass; a careful review would be appreciated so as to >>>>>> avoid breakage. >>>>>> >>>>>> Webrev: >>>>>> http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ >>>>>> >>>>>> Issue: >>>>>> https://bugs.openjdk.java.net/browse/JDK-8199756 >>>>> There are subtle interactions with how system properties are set >>>>> in the VM and on the command line which will take a bit effort to >>>>> research in order to review this and be satisfied that the change >>>>> is safe. Have you dug into the ancient history and bugs to see why >>>>> it was done this way? >>>>> >>>>> -Alan >>>> >> > From mandy.chung at oracle.com Thu Mar 22 19:10:59 2018 From: mandy.chung at oracle.com (mandy chung) Date: Thu, 22 Mar 2018 12:10:59 -0700 Subject: RFR 8199756 : Simplify language, country, script, and variant property initialization In-Reply-To: References: <3fd6536d-f5d7-ff7d-106d-14eda3e72c71@oracle.com> <79cdebc1-c9fb-6108-e9a9-010003fe7978@Oracle.com> <96968660-6b6e-ad2a-0f9e-94551af2c0c5@oracle.com> Message-ID: <862f5195-dd74-9ad9-7225-adc0f4f19ae2@oracle.com> The performance concern is a fair point and it'll need the benchmark and proper perf measurement.? It's okay with me to follow up as a separate clean up and you already have the work started any way. Mandy On 3/22/18 12:01 PM, Roger Riggs wrote: > Hi Mandy, > > This is just one step in untangling and improving property > initialization. > > I'm also working on a change similar to what you suggest to remove > some/more of the upcalls > and replace them with setting fields. In that case, the adjustments to > the values would be handled in java. > > I have performance concern (as yet unmeasured)? that moving from using > a mostly native encoding function > (JNU_NewStringPlatform) to a Java based encoding will hurt startup > performance. (its too early to be compiled). > > So for now, I'd like to commit this as is and work on the next step > separately. > > Thanks, Roger > > On 3/22/18 2:19 PM, mandy chung wrote: >> Hi Roger, >> >> Thanks for adding the test that should have created when JDK-4700857 >> was resolved. >> >> Since this fix changes the setting of those i18n properties to later >> after JVM_InitProperties is called, it would be a good opportunity to >> set these properties in Java and remove the native fillI18nProps >> method.? What it needs from Java is to get the value of >> sprops->display_XXX, one option is to define a Java class holding >> these displayXXX fields that are set by initProperties directly. >> >> What do you think? >> >> Mandy >> >> On 3/22/18 8:24 AM, Roger Riggs wrote: >>> Hi, >>> >>> The webrev[1] has been updated with a new test added to verify that >>> if a user.* property >>> is defined on the command line, then corresponding property has the >>> same value and >>> correctly overrides any value from the platform. >>> >>> After verification, the comment (line 304) has been corrected to >>> refer to the platform native >>> encoding of bytes -> strings instead of the user.* I18N properties. >>> >>> The tests for properties and locales have been run and passed in a >>> variety of locales. >>> >>> Thanks, Roger >>> >>> [1] http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ >>> >>> >>> On 3/19/2018 6:38 PM, David Holmes wrote: >>>> Hi Roger, >>>> >>>> On 19/03/2018 11:55 PM, Roger Riggs wrote: >>>>> Hi Alan, >>>>> >>>>> The original changeset [1] is most easily viewed in the jdk-8u repo. >>>>> >>>>> The comment and placement of the removes of the properties and the >>>>> code to re-set them >>>>> around the call to the JVM_InitProperties (which sets properties >>>>> from the >>>>> -D arguments among others), seem to indicate that the previous >>>>> property >>>>> values are irrelevant. >>>> >>>> Not irrelevant: defaults. >>>> >>>>> >>>>> The remaining question is whether there are any side effects or >>>>> usage of those >>>>> four property values between the time they are initially set and >>>>> when they are removed. >>>>> The code in System.initProperties is straightforward and the bulk >>>>> of the code >>>>> is simply setting property values, with one interspersed call to >>>>> initialize the sun.jnu_encoding. >>>>> ?From all appearances there are no side effects or uses of the >>>>> initially set values of those four properties. >>>> >>>> I would have expected these values to possibly have an impact on >>>> InitalizeEncoding and subsequent use of PUTPROP_ForPlatformNString. >>>> Else why set them early then unset them again? Or maybe they impact >>>> any error messages that might arise in this stage of initialization? >>>> >>>> I expect any issues here to be extremely subtle - as Alan >>>> indicated. If there is any path to Java code that may try to read >>>> and use these properties then they need to be set. >>>> >>>> And if these are truly unnecessary then doesn't that imply that >>>> placing them in sprops via GetJavaProperties in the first place is >>>> also unnecessary? >>>> >>>> Has this been extensively tested on a non-English Windows system? >>>> And do we even have tests for various initialization failures? >>>> >>>> David >>>> ----- >>>> >>>>> Thanks, Roger >>>>> >>>>> [1] https://bugs.openjdk.java.net/browse/JDK-4700857 >>>>> ???? RFE: separating user locale and user interface locale >>>>> >>>>> On 3/17/18 5:46 AM, Alan Bateman wrote: >>>>>> On 16/03/2018 20:32, Roger Riggs wrote: >>>>>>> Please review a small simplification of the initialization of >>>>>>> System properties for >>>>>>> language, country, script, and variant.? Some steps for >>>>>>> initializing them are unnecessary. >>>>>>> The tests pass; a careful review would be appreciated so as to >>>>>>> avoid breakage. >>>>>>> >>>>>>> Webrev: >>>>>>> http://cr.openjdk.java.net/~rriggs/webrev-prop-simplify-8199756/ >>>>>>> >>>>>>> Issue: >>>>>>> https://bugs.openjdk.java.net/browse/JDK-8199756 >>>>>> There are subtle interactions with how system properties are set >>>>>> in the VM and on the command line which will take a bit effort to >>>>>> research in order to review this and be satisfied that the change >>>>>> is safe. Have you dug into the ancient history and bugs to see >>>>>> why it was done this way? >>>>>> >>>>>> -Alan >>>>> >>> >> > From claes.redestad at oracle.com Thu Mar 22 19:18:11 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 22 Mar 2018 20:18:11 +0100 Subject: [11] RFR: 8193128: Reduce number of implementation classes returned by List/Set/Map.of() In-Reply-To: <01bac684-e8f8-9bdb-6670-2903eefa19a6@oracle.com> References: <7d367ca5-2915-bd80-8247-c748260f93c8@oracle.com> <8746a7ab-4c1c-98fc-a0ba-05594bce794c@oracle.com> <71b8baf0-0f4b-2e64-36d9-610e2286b59e@oracle.com> <4ec012ce-cd0c-003b-c20a-4c77e317e40f@gmail.com> <14910571-3cc8-75a5-9f80-8d633b23ac4b@oracle.com> <94ea8e2e-418c-4408-2dc2-7bea1ca099d4@gmail.com> <2845d01f-742a-bcfe-330c-5fbd586eaf88@oracle.com> <1bcb7c02-5ce0-be4f-e28c-842f229004bc@gmail.com> <98bb59c5-c091-a90d-723e-1a0ce1d6df93@oracle.com> <97367d24-f411-0a75-677d-93e9d213ef94@oracle.com> <11204870-baaa-214b-8667-39262d08eaf8@oracle.com> <01bac684-e8f8-9bdb-6670-2903eefa19a6@oracle.com> Message-ID: On 2018-03-22 19:03, Stuart Marks wrote: > > One small issue is with this comment: > > ?295????????? * Constructs a sublist of an arbitrary AbstractList, > which is > ?296????????? * not a SubList itself. > > This supports sublists of an arbitrary AbstractImmutableList, not > AbstractList. > > Other than this, I think you're good to go! I will update the comment and push, thanks! /Claes From martinrb at google.com Thu Mar 22 20:26:25 2018 From: martinrb at google.com (Martin Buchholz) Date: Thu, 22 Mar 2018 13:26:25 -0700 Subject: [PATCH] unnecessary null check inside of java.lang.Boolean.valueOf(String) In-Reply-To: <9819331521748940@web45g.yandex.ru> References: <6635141521367007@web3g.yandex.ru> <9819331521748940@web45g.yandex.ru> Message-ID: ??????: Thanks for the benchmarking. I would always do benchmarking with latest available jdk, i.e. jdk11. You don't say which variant is better and which is best! But the difference is small enough we should go with the simpler one you originally suggested return "true".equalsIgnoreCase(s); I suspect hotspot uses the fact that the receiver is a constant. On Thu, Mar 22, 2018 at 1:02 PM, ?????? ??????? wrote: > I've measured performance of suggested code comparing with previous > variants (5 forks, 5 warmup and 10 measurement iterations, 1 s each). > Here's the output for JDK 9.0.4: > > Benchmark (str) Mode Cnt Score Error > Thanks for the benchmarking. > I would always do benchmarking with latest available jdk, i.e. jdk11. > You don't say which variant is better and which is best! > But the difference is small enough we should go with the simpler one you > originally suggested > > eturn "true".equalsIgnoreCase(s); > > On Thu, Mar 22, 2018 at 1:02 PM, ?????? ??????? > wrote: > I've measured performance of suggested code comparing with previous > variants (5 forks, 5 warmup and 10 measurement iterations, 1 s each). > Here's the output for JDK 9.0.4: > > Benchmark (str) Mode Cnt Score Error > Units > EqualsIgnoreCaseBenchmark.bestMethod true avgt 50 5,552 ? 0,070 > ns/op > EqualsIgnoreCaseBenchmark.bestMethod false avgt 50 2,703 ? 0,054 > ns/op > EqualsIgnoreCaseBenchmark.bestMethod null avgt 50 2,248 ? 0,076 > ns/op > > EqualsIgnoreCaseBenchmark.betterMethod true avgt 50 5,072 ? 0,626 > ns/op > EqualsIgnoreCaseBenchmark.betterMethod false avgt 50 2,955 ? 0,072 > ns/op > EqualsIgnoreCaseBenchmark.betterMethod null avgt 50 2,416 ? 0,040 > ns/op > > EqualsIgnoreCaseBenchmark.defaultMethod true avgt 50 8,986 ? 0,159 > ns/op > EqualsIgnoreCaseBenchmark.defaultMethod false avgt 50 2,912 ? 0,162 > ns/op > EqualsIgnoreCaseBenchmark.defaultMethod null avgt 50 2,186 ? 0,027 > ns/op > > and for JDK 10 > > Benchmark (str) Mode Cnt Score Error > Units > EqualsIgnoreCaseBenchmark.bestMethod true avgt 50 5,672 ? 0,071 > ns/op > EqualsIgnoreCaseBenchmark.bestMethod false avgt 50 3,120 ? 0,040 > ns/op > EqualsIgnoreCaseBenchmark.bestMethod null avgt 50 2,705 ? 0,060 > ns/op > > EqualsIgnoreCaseBenchmark.betterMethod true avgt 50 5,141 ? 0,080 > ns/op > EqualsIgnoreCaseBenchmark.betterMethod false avgt 50 3,436 ? 0,049 > ns/op > EqualsIgnoreCaseBenchmark.betterMethod null avgt 50 3,085 ? 0,048 > ns/op > > EqualsIgnoreCaseBenchmark.defaultMethod true avgt 50 9,931 ? 0,257 > ns/op > EqualsIgnoreCaseBenchmark.defaultMethod false avgt 50 3,367 ? 0,003 > ns/op > EqualsIgnoreCaseBenchmark.defaultMethod null avgt 50 2,631 ? 0,002 > ns/op > > 22.03.2018, 19:35, "Martin Buchholz" : > If parseBoolean is worth optimizing (barely, but only because Boolean is > very popular), then let's do the usual ASCII bit-twiddling: > > public static boolean parseBoolean(String s) { > // return "true".equalsIgnoreCase(s); > return s != null > && s.length() == 4 > && (s.charAt(0) | 0x20) == 't' > && (s.charAt(1) | 0x20) == 'r' > && (s.charAt(2) | 0x20) == 'u' > && (s.charAt(3) | 0x20) == 'e'; > } > > ModuleBootstrap is not worth changing because any system property is very > unlikely to be set - the null check will trip 99.9999% of the time. > > Units > EqualsIgnoreCaseBenchmark.bestMethod true avgt 50 5,552 ? 0,070 > ns/op > EqualsIgnoreCaseBenchmark.bestMethod false avgt 50 2,703 ? 0,054 > ns/op > EqualsIgnoreCaseBenchmark.bestMethod null avgt 50 2,248 ? 0,076 > ns/op > > EqualsIgnoreCaseBenchmark.betterMethod true avgt 50 5,072 ? 0,626 > ns/op > EqualsIgnoreCaseBenchmark.betterMethod false avgt 50 2,955 ? 0,072 > ns/op > EqualsIgnoreCaseBenchmark.betterMethod null avgt 50 2,416 ? 0,040 > ns/op > > EqualsIgnoreCaseBenchmark.defaultMethod true avgt 50 8,986 ? 0,159 > ns/op > EqualsIgnoreCaseBenchmark.defaultMethod false avgt 50 2,912 ? 0,162 > ns/op > EqualsIgnoreCaseBenchmark.defaultMethod null avgt 50 2,186 ? 0,027 > ns/op > > and for JDK 10 > > Benchmark (str) Mode Cnt Score Error > Units > EqualsIgnoreCaseBenchmark.bestMethod true avgt 50 5,672 ? 0,071 > ns/op > EqualsIgnoreCaseBenchmark.bestMethod false avgt 50 3,120 ? 0,040 > ns/op > EqualsIgnoreCaseBenchmark.bestMethod null avgt 50 2,705 ? 0,060 > ns/op > > EqualsIgnoreCaseBenchmark.betterMethod true avgt 50 5,141 ? 0,080 > ns/op > EqualsIgnoreCaseBenchmark.betterMethod false avgt 50 3,436 ? 0,049 > ns/op > EqualsIgnoreCaseBenchmark.betterMethod null avgt 50 3,085 ? 0,048 > ns/op > > EqualsIgnoreCaseBenchmark.defaultMethod true avgt 50 9,931 ? 0,257 > ns/op > EqualsIgnoreCaseBenchmark.defaultMethod false avgt 50 3,367 ? 0,003 > ns/op > EqualsIgnoreCaseBenchmark.defaultMethod null avgt 50 2,631 ? 0,002 > ns/op > > 22.03.2018, 19:35, "Martin Buchholz" : > > If parseBoolean is worth optimizing (barely, but only because Boolean is > very popular), then let's do the usual ASCII bit-twiddling: > > public static boolean parseBoolean(String s) { > // return "true".equalsIgnoreCase(s); > return s != null > && s.length() == 4 > && (s.charAt(0) | 0x20) == 't' > && (s.charAt(1) | 0x20) == 'r' > && (s.charAt(2) | 0x20) == 'u' > && (s.charAt(3) | 0x20) == 'e'; > } > > ModuleBootstrap is not worth changing because any system property is very > unlikely to be set - the null check will trip 99.9999% of the time. > > > From philip.race at oracle.com Thu Mar 22 20:33:21 2018 From: philip.race at oracle.com (Phil Race) Date: Thu, 22 Mar 2018 13:33:21 -0700 Subject: RFR: 8200129 : Remove D3D Performance Counter. Message-ID: <3db6c9cd-c68f-d44a-8240-485afc05e905@oracle.com> bug: https://bugs.openjdk.java.net/browse/JDK-8200129 webrev: http://cr.openjdk.java.net/~prr/8200129/ It was noted in another thread [1] that we had a couple of qualified exports from java.base to java.desktop that are platform-specific but are in the main module-info.java. It was suggested to move these to platform-specific locations. But one of them doesn't seem to be at all important and we can just remove it. It is a "counter" that basically tells you if D3D was used but I don't see any standard tools that support it and I was able to build + run just fine. The other platform-specific export is moved here as suggested since it can't be just removed without some alternative. NB I did build all platforms. -phil. [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-March/052198.html From Sergey.Bylokhov at oracle.com Thu Mar 22 20:52:49 2018 From: Sergey.Bylokhov at oracle.com (Sergey Bylokhov) Date: Thu, 22 Mar 2018 13:52:49 -0700 Subject: RFR: 8200129 : Remove D3D Performance Counter. In-Reply-To: <3db6c9cd-c68f-d44a-8240-485afc05e905@oracle.com> References: <3db6c9cd-c68f-d44a-8240-485afc05e905@oracle.com> Message-ID: <90947040-38bd-43b5-53b3-d27065e2b9b4@oracle.com> Looks fine. On 22/03/2018 13:33, Phil Race wrote: > bug: https://bugs.openjdk.java.net/browse/JDK-8200129 > webrev: http://cr.openjdk.java.net/~prr/8200129/ > > It was noted in another thread [1] that we had a couple of qualified > exports > from java.base to java.desktop that are platform-specific but are in the > main module-info.java. > > It was suggested to move these to platform-specific locations. > But one of them doesn't seem to be at all important and we can just > remove it. > It is a "counter" that basically tells you if D3D was used but I don't > see any > standard tools that support it and I was able to build + run just fine. > > The other platform-specific export is moved here as suggested since > it can't be just removed without some alternative. > > NB I did build all platforms. > > -phil. > > [1] > http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-March/052198.html -- Best regards, Sergey. From Alan.Bateman at oracle.com Thu Mar 22 20:55:19 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 22 Mar 2018 20:55:19 +0000 Subject: RFR: 8200129 : Remove D3D Performance Counter. In-Reply-To: <3db6c9cd-c68f-d44a-8240-485afc05e905@oracle.com> References: <3db6c9cd-c68f-d44a-8240-485afc05e905@oracle.com> Message-ID: <11c255aa-498f-367a-1be9-892316198254@oracle.com> On 22/03/2018 20:33, Phil Race wrote: > bug: https://bugs.openjdk.java.net/browse/JDK-8200129 > webrev: http://cr.openjdk.java.net/~prr/8200129/ > This looks okay to me. -Alan From david.holmes at oracle.com Thu Mar 22 21:36:07 2018 From: david.holmes at oracle.com (David Holmes) Date: Fri, 23 Mar 2018 07:36:07 +1000 Subject: RFR: 8196750 [Testbug] tools/launcher tests need to tolerate unrelated warnings In-Reply-To: <5AB3BB30.3010305@oracle.com> References: <24606B9C-62ED-47F4-9805-EA9F6EEB47CF@oracle.com> <84decb80-8b3c-bf61-d6f7-6deaa8bcb9ea@oracle.com> <5AB3BB30.3010305@oracle.com> Message-ID: <63784b3b-7943-785e-8a16-844aa1968c50@oracle.com> On 23/03/2018 12:18 AM, Kumar Srinivasan wrote: > David, > > Why would the VM emit these warnings if the deprecated vm flag > is not being used ? The warnings are not deprecation warnings. The warnings are for flags that should have been made obsolete in this version but are still present. It is a reminder to make updates when the version ticks over such that a deprecated flag should now be obsolete or expired. But more generally the VM can issue runtime warnings for a variety of environmental issues. David > Andrey, > As for the reviews I am ok with InfoStreams, wrt. ToolOpts it is not at > all apparent, > maybe more comments explaining what is going on ? > > Kumar > > >> Hi Andrei, >> >> On 22/03/2018 11:12 AM, Andrey Nazarov wrote: >>> Hi, >>> >>> Please review fix in launcher tests. >>> >>> Review: http://cr.openjdk.java.net/~anazarov/JDK-8196750/webrev/ >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8196750?filter=-1 >> >> test/jdk/tools/launcher/ToolsOpts.java >> >> I don't understand how the change fixes the problem. IIUC the problem >> is that the test expects the output to consist of the command-line >> passed to the tool. Instead if it contains a Warning from the VM, it >> won't match and so we fail. The new code no longer uses a String[] and >> no longer assumes that output[i] == args[i], but it still searches the >> current "output" value for a match with one of the args. But that will >> still fail if what we actually have is a Warning. ?? I would have >> expected to see the Warning strings filtered out more directly. >> >> The other test change seems reasonable. >> >> Thanks, >> David >> >>> ?Thanks, >>> ? Andrei >>> > From paul.sandoz at oracle.com Thu Mar 22 21:37:18 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 22 Mar 2018 14:37:18 -0700 Subject: RFR 8200118: [test] String concat tests should test toString() application order In-Reply-To: <41637232-1c8f-f465-cf18-2f99f6d9df45@redhat.com> References: <41637232-1c8f-f465-cf18-2f99f6d9df45@redhat.com> Message-ID: <9B28F02C-5C50-423D-A615-1A274FEDF3BB@oracle.com> Test looks good, but do you need to declare the source/target for compilation? Paul. > On Mar 22, 2018, at 10:56 AM, Aleksey Shipilev wrote: > > Bug: > https://bugs.openjdk.java.net/browse/JDK-8200118 > > Webrev: > http://cr.openjdk.java.net/~shade/8200118/webrev.01/ > > This adds the relevant test to StringConcat family of tests, which asserts all strategies do the > right thing. There was a bug in MH_* strategies caused by the already fixed bug in filterArguments > [1], which this test was supposed to find, if existed before. > > Testing: run-test with jdk/jdk, run-test before/after filterArguments fix in jdk-updates/jdk10u > > Thanks, > -Aleksey > > [1] https://bugs.openjdk.java.net/browse/JDK-8194554 > From shade at redhat.com Thu Mar 22 21:46:30 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Thu, 22 Mar 2018 22:46:30 +0100 Subject: RFR 8200118: [test] String concat tests should test toString() application order In-Reply-To: <9B28F02C-5C50-423D-A615-1A274FEDF3BB@oracle.com> References: <41637232-1c8f-f465-cf18-2f99f6d9df45@redhat.com> <9B28F02C-5C50-423D-A615-1A274FEDF3BB@oracle.com> Message-ID: <1b6d702e-8370-dca4-8b6c-6264a647536e@redhat.com> On 03/22/2018 10:37 PM, Paul Sandoz wrote: > Test looks good, but do you need to declare the source/target for compilation? Thanks! source/target are from the times when default source/target was not 9, all other tests have it (I copypasted the test from the existing ones). We should probably ditch those source/target-s all at once soon. Thanks, -Aleksey From paul.sandoz at oracle.com Thu Mar 22 22:05:35 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 22 Mar 2018 15:05:35 -0700 Subject: RFR 8200118: [test] String concat tests should test toString() application order In-Reply-To: <1b6d702e-8370-dca4-8b6c-6264a647536e@redhat.com> References: <41637232-1c8f-f465-cf18-2f99f6d9df45@redhat.com> <9B28F02C-5C50-423D-A615-1A274FEDF3BB@oracle.com> <1b6d702e-8370-dca4-8b6c-6264a647536e@redhat.com> Message-ID: <8B88B4E9-A811-49B3-B268-DE3F7B15CEA9@oracle.com> > On Mar 22, 2018, at 2:46 PM, Aleksey Shipilev wrote: > > On 03/22/2018 10:37 PM, Paul Sandoz wrote: >> Test looks good, but do you need to declare the source/target for compilation? > > Thanks! source/target are from the times when default source/target was not 9, all other tests have > it (I copypasted the test from the existing ones). We should probably ditch those source/target-s > all at once soon. > Ok, Paul. From mandy.chung at oracle.com Thu Mar 22 22:39:44 2018 From: mandy.chung at oracle.com (mandy chung) Date: Thu, 22 Mar 2018 15:39:44 -0700 Subject: RFR: 8200129 : Remove D3D Performance Counter. In-Reply-To: <3db6c9cd-c68f-d44a-8240-485afc05e905@oracle.com> References: <3db6c9cd-c68f-d44a-8240-485afc05e905@oracle.com> Message-ID: <1a5a54ce-21c0-3c58-a543-47a625d7fb48@oracle.com> +1 Mandy On 3/22/18 1:33 PM, Phil Race wrote: > bug: https://bugs.openjdk.java.net/browse/JDK-8200129 > webrev: http://cr.openjdk.java.net/~prr/8200129/ > > It was noted in another thread [1] that we had a couple of qualified > exports > from java.base to java.desktop that are platform-specific but are in the > main module-info.java. > > It was suggested to move these to platform-specific locations. > But one of them doesn't seem to be at all important and we can just > remove it. > It is a "counter" that basically tells you if D3D was used but I don't > see any > standard tools that support it and I was able to build + run just fine. > > The other platform-specific export is moved here as suggested since > it can't be just removed without some alternative. > > NB I did build all platforms. > > -phil. > > [1] > http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-March/052198.html From sergei.tsypanov at yandex.ru Fri Mar 23 06:04:25 2018 From: sergei.tsypanov at yandex.ru (=?utf-8?B?0KHQtdGA0LPQtdC5INCm0YvQv9Cw0L3QvtCy?=) Date: Fri, 23 Mar 2018 08:04:25 +0200 Subject: Inefficient indexOf called inside of CopyOnWriteArrayList$COWSubList.remove(Object) Message-ID: <3867991521785065@web23g.yandex.ru> Hi, on the 10th of March I wrote here about duplicated code of idnexOf/lastIndexOf methods in array-based collections. http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-March/051968.html Later I've found one more related issue. Here's the code of CopyOnWriteArrayList$COWSubList.remove(Object) as of JDK 9/10/11: public boolean remove(Object o) { synchronized (l.lock) { checkForComodification(); int index = indexOf(o); if (index == -1) return false; remove(index); return true; } } Here indexOf() is inherited from j.u.AbstractList and allocates an instance of ListIterator then using hasNext()/next() to iterate over it. However, CopyOnWriteArrayList itself has private static indexOf(Object o, Object[] elements, int index, int fence) which can do the search with simple counter loop. But COWSubList is static and has no access to the methods of enclosing class. So to get rid of calling inherited method we can either override indexOf() in COWSubList and copy-paste the contents of CopyOnWriteArrayList.indexOf(Object o, Object[] elements, int index, int fence) into it (introducing more duplicated code into JDK), or extract the code into utility method of j.u.Arrays as it's suggested in my patch above. I used the second approach and patched COWSubList like this: CopyOnWriteArrayList$COWSubList { //... public boolean remove(Object o) { synchronized (l.lock) { checkForComodification(); int index = indexOf(o); if (index == -1) return false; remove(index); return true; } } public int indexOf(Object o) { return Arrays.indexOf(o, expectedArray, offset, size); //method in my patched JDK similar to what we have in CopyOnWriteArrayList.indexOf(Object o, Object[] elements, int index, int fence) } //... } Then I compared the performance of COWSubList.remove(Object) with benchmark below. It deliberately removes no element in order to measure only the cost of finding element to be removed in CopyOnWriteArrayList$COWSubList. @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @Fork(jvmArgsAppend = {"-XX:+UseParallelGC", "-Xms1g", "-Xmx1g"}) public class CowSubListRemoveBenchmark { @Benchmark public boolean removeFromJdkCowSubList(Data data) { return data.subListFromJdkCowList.remove(data.integer); } @Benchmark public boolean removeFromPatchedCowSubList(Data data) { return data.subListFromPatchedJdkCowList.remove(data.integer); } @State(Scope.Thread) public static class Data { @Param({"10", "100", "1000"}) private int size; private List subListFromJdkCowList; private List subListFromPatchedJdkCowList; private Integer integer = -1; //element is always missing from the list, so we iterate over it up to the end @Setup public void setup() { Integer[] integers = IntStream.range(0, size).boxed().toArray(Integer[]::new); subListFromJdkCowList = new CopyOnWriteArrayList<>(integers).subList(0, size / 2); subListFromPatchedJdkCowList = new PatchedCopyOnWriteArrayList<>(integers).subList(0, size / 2); //patched by overriding indexOf() right after remove(Object) } } } Output for JDK 10 (release), 5 forks, 5 warmup and 10 measurement iterations 1 s each: Benchmark (size) Mode Cnt Score Error Units CowSubListRemoveBenchmark.removeFromJdkCowSubList 10 avgt 50 43,585 ? 12,385 ns/op CowSubListRemoveBenchmark.removeFromJdkCowSubList 100 avgt 50 169,230 ? 13,360 ns/op CowSubListRemoveBenchmark.removeFromJdkCowSubList 1000 avgt 50 1167,155 ? 92,585 ns/op CowSubListRemoveBenchmark.removeFromPatchedCowSubList 10 avgt 50 13,101 ? 0,271 ns/op CowSubListRemoveBenchmark.removeFromPatchedCowSubList 100 avgt 50 47,641 ? 0,609 ns/op CowSubListRemoveBenchmark.removeFromPatchedCowSubList 1000 avgt 50 479,789 ? 38,448 ns/op Same for JDK 11 (build 11-ea+5): Benchmark (size) Mode Cnt Score Error Units CowSubListRemoveBenchmark.removeFromJdkCowSubList 10 avgt 50 34,510 ? 3,236 ns/op CowSubListRemoveBenchmark.removeFromJdkCowSubList 100 avgt 50 203,669 ? 12,882 ns/op CowSubListRemoveBenchmark.removeFromJdkCowSubList 1000 avgt 50 1194,524 ? 91,524 ns/op CowSubListRemoveBenchmark.removeFromPatchedCowSubList 10 avgt 50 13,551 ? 0,724 ns/op CowSubListRemoveBenchmark.removeFromPatchedCowSubList 100 avgt 50 54,565 ? 5,679 ns/op CowSubListRemoveBenchmark.removeFromPatchedCowSubList 1000 avgt 50 425,273 ? 24,665 ns/op So, my proposal is the same: duplicated code of indexOf()/lastIndexOf() should be moved into static utility methods of j.u.Arrays. Regards, Sergey Tsypanov From orionllmain at gmail.com Fri Mar 23 06:50:23 2018 From: orionllmain at gmail.com (Zheka Kozlov) Date: Fri, 23 Mar 2018 13:50:23 +0700 Subject: [11] RFR: 8193128: Reduce number of implementation classes returned by List/Set/Map.of() In-Reply-To: <97367d24-f411-0a75-677d-93e9d213ef94@oracle.com> References: <7d367ca5-2915-bd80-8247-c748260f93c8@oracle.com> <461185061.1582235.1512601042847.JavaMail.zimbra@u-pem.fr> <8746a7ab-4c1c-98fc-a0ba-05594bce794c@oracle.com> <71b8baf0-0f4b-2e64-36d9-610e2286b59e@oracle.com> <4ec012ce-cd0c-003b-c20a-4c77e317e40f@gmail.com> <14910571-3cc8-75a5-9f80-8d633b23ac4b@oracle.com> <94ea8e2e-418c-4408-2dc2-7bea1ca099d4@gmail.com> <2845d01f-742a-bcfe-330c-5fbd586eaf88@oracle.com> <1bcb7c02-5ce0-be4f-e28c-842f229004bc@gmail.com> <98bb59c5-c091-a90d-723e-1a0ce1d6df93@oracle.com> <97367d24-f411-0a75-677d-93e9d213ef94@oracle.com> Message-ID: I noticed that List.copyOf() allocates an array twice. The first allocation is coll.toArray(), the second one is in ListN constructor. Can we do something with it? 2018-03-22 7:51 GMT+07:00 Stuart Marks : > Hi Claes, > > I'm finally finally getting back to this. I reviewed the current state of > the patch located here: > > http://cr.openjdk.java.net/~redestad/8193128/open.06/ > > I think this is mostly fine as it is. There are some things about it that > could be adjusted, but none of them stand in the way of it going in. If you > want to take care of any of these items before pushing, that'd be great, > otherwise they can be handled separately later. > > * AbstractImmutableCollection and AbstractImmutableSet are in the "List > Implementations" section of the file. Seems like AIC ought to be moved to > the top, since it's common to List and Set, and AIS ought to be moved to > the "Set Implementations" section. This is just location in the file, not > nesting level. > > * The SubList constructors that are overloaded based on the type of the > 1st arg (List vs SubList) seems subtle and error-prone. I misread the code > the first time I saw it. Seems like it would be preferable to have > well-named static factory methods, each calling a policy-free (private) > constructor. > > * Should SubList.size be final? Should any of the SubList fields be > @Stable? > > * Does the SubList class need to nested within AbstractImmutableList? Note > that it also extends AIL, so I don't think nesting gives it access to > anything that it doesn't already have. Plus it includes an anonymous inner > class based on ListIterator, which is a fourth level of nested classes. > It'd be good to flatten this out a bit if possible. > > * The instance returned by SubList.iterator() is also a ListIterator. > Hmmm. But I'm also wondering if SubList's iterators can be shared somehow > with AIL's Itr and ListItr. > > * Several indexOf tests are added to ListFactories.java. Are these > redundant with the indexOf tests that were added to MOAT? > > Let me know what, if any, you fix up before pushing, and I'll track the > rest. > > Thanks, > > s'marks > From magnus.ihse.bursie at oracle.com Fri Mar 23 13:56:34 2018 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Fri, 23 Mar 2018 14:56:34 +0100 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries Message-ID: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> With modern compilers, we can use compiler directives (such as _attribute__((visibility("default"))), or __declspec(dllexport)) to control symbol visibility, directly in the source code. This has historically not been present on all compilers, so we had to resort to using mapfiles (also known as linker scripts). This is no longer the case. Now all compilers we use support symbol visibility directives, in one form or another. We should start using this. Since this has been the only way to control symbol visibility on Windows, for most of the shared code, we already have proper JNIEXPORT decorations in place. If we fix the remaining platform-specific files to have proper JNIEXPORT tagging, then we can finally get rid of mapfiles. This fix removed mapfiles for all JDK libraries. It does not touch hotspot libraries nor JDK executables; they will have to wait for a future fix -- this was complex enough. This change will not have any impact on macosx, since we do not use mapfiles there, but instead export all symbols. (This is not a good idea, but I'll address that separately.) This change will also have a minimal impact on Windows. The only reason Windows is impacted at all, is that some changes needed by Solaris and Linux were simpler to fix for all platforms. I have strived for this change to have no impact on the actual generated code. Unfortunately, this was not possible to fully achieve. I do not believe that these changes will have any actual impact on the product, though. I will present the differences more in detail further down. Those who are not interested can probably skip that. The patch has passed tier1 testing and is currently running tier2 and tier3. Since the running code is more or less (see caveat below) unmodified, I don't expect any testing issues. Bug: https://bugs.openjdk.java.net/browse/JDK-8200178 WebRev: http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01 Details on changes: Most of the source code changes are (unsurprisingly) in java.base and java.desktop. Remaining changes are in jdk.crypto.ucrypto, jdk.hotspot.agent, jdk.jdi and jdk.jdwp.agent. Source code changes does almost to 100% consists in decorating an exported function with JNIEXPORT. I have also followed the long-standing convention of adding JNICALL. This is a no-op on non-Windows platforms, so for most of the changes this is purely cosmetic (and possibly adding in robustness, should the function ever be used on Windows in the future). I have also followed the stylistic convention of putting "JNIEXPORT JNICALL" on a separate line. For some functions, however, this might cause a change in calling convention on Windows. Since this can not apply to exported functions on Windows (otherwise they would already have had JNIEXPORT), I do not think this matters anything. A few libraries did not have a mapfile, on Linux and/or Solaris. This actually meant that all symbols were exported. It is highly unclear if this was known and intended by the original make rule writer. I have emulated this by adding the flag $(EXPORT_ALL_SYMBOLS) to these libraries. Hopefully, we can remove this flag and fix proper exported symbols in the future. I have run the complete build using COMPARE_BUILD, and made a thourough analysis of the differences for Linux and Solaris. All native libraries have symbol differences, but most of them are trivial and/or harmless. As a result, most libraries have disasm differences as well, but these too seem trivial and harmless. The differences in symbols that are common to all libraries include: ?* Internal symbols such as __bss_start, _edata, _end and _fini are now global. (They are imported as such from the compiler libraries/archives, and we have no linker script to override this behavior). ?* The versioning tag SUNWprivate_1.1 is not included, and thus neither the .gnu.version_d symbol. ?* There are a few differences in the symbol and/or mangling of some local functions. I'm not sure what's causing this, but it's unlikely to have any effect on the product. Another common source for change in symbols is due to previous platform differences. For instance, if we had "JNIEXPORT int JNICALL do_foo() { ... }", but do_foo was not in the mapfile, the symbol was exported on Windows but not on Linux and Solaris. (Presumable since it was not needed there, even though it was compiled for those platforms as well.) Now, with the mapfiles gone, do_foo() will be exported on all platforms. And contrary, functions that are compiled on all platforms, and were exported in mapfiles, but now have gotten an JNIEXPORT decoration, will now be visible even on Windows. (This accounts for half of the noticed symbol differences on Windows.) I could have made the JNIEXPORT conditional on OS, but I didn't think the mess in source code were worth the keeping of binary confidence with the old build. A third common source for change in symbols is due to exported functions "leaking" across library borders. For instance, some functions in java.desktop is compiled in both libawt_xawt and libawt_headless, but they were previously only included in the mapfile for one of these libraries. Now, since the visibility is determined by the source code itself, it gets exported in both libraries. A variant of this is when a library depends on another JDK library, and includes the header file from that other library, which in turn declares a function as JNIEXPORT. This will cause the including library to also export the function. This accounts for the other half of the changes on Windows. A typical example of this is that multiple libraries now re-export hotspot symbols from libjvm.so, like jio_fprintf. (I have not listed the libjvm re-exports below.) Note that? Java_java_io_FileOutputStream_close0 in java.base/unix/native/libjava/FileOutputStream_md.c is no longer exported, and can probably be removed. Here is a detailed table showing and accounting for all the remaining differences found on Linux and Solaris: java.base/unix/native/libjava: Java_java_io_FileOutputStream_close0 is now also exported on unix platforms due to JNIEXPORT. java.base/jspawnlauncher: On solaris, we also include libjava/childproc.o, which now exports less functions than it used to (it used to export all functions, now it is compiled with visibility=hidden). java.base/java(w).exe: Is now also exporting the following symbols due to added JNIEXPORT in libjli on Windows: (Yes, executables can export symbols on Windows. Confusing, I know.) ?JLI_AddArgsFromEnvVar ?JLI_CmdToArgs ?JLI_GetAppArgIndex ?JLI_GetStdArgc ?JLI_GetStdArgs ?JLI_InitArgProcessing ?JLI_Launch ?JLI_List_add ?JLI_List_new ?JLI_ManifestIterate ?JLI_MemAlloc ?JLI_MemFree ?JLI_PreprocessArg ?JLI_ReportErrorMessage ?JLI_ReportErrorMessageSys ?JLI_ReportExceptionDescription ?JLI_ReportMessage ?JLI_SetTraceLauncher ?JLI_StringDup java.desktop:/libawt_xawt: The following symbols are now also exported on linux and solaris due to JNIEXPORT: ?awt_DrawingSurface_FreeDrawingSurfaceInfo ?awt_DrawingSurface_GetDrawingSurfaceInfo ?awt_DrawingSurface_Lock ?awt_DrawingSurface_Unlock ?awt_GetColor The following symbols are now also exported on linux and solaris due to JNIEXPORT (they were previously ?exported only in libawt): ?Java_sun_awt_DebugSettings_setCTracingOn__Z ?Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2 ?Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2I ?Java_sun_awt_X11GraphicsConfig_getNumColors java.desktop:/libawt_headless: The following symbols are now also exported due to JNIEXPORT (they were previously ?exported only in libawt_xawt and/or libawt): ?Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo ?Java_sun_java2d_opengl_GLXGraphicsConfig_getOGLCapabilities ?Java_sun_java2d_x11_X11PMBlitLoops_updateBitmask ?Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable ?X11SurfaceData_GetOps java.desktop/libawt: The following symbols are now also exported on Windows, due to added JNIEXPORT: ?SurfaceData_InitOps ?mul8table ?div8table ?doDrawPath ?doFillPath ?g_CMpDataID ?initInverseGrayLut ?make_dither_arrays ?make_uns_ordered_dither_array ?path2DFloatCoordsID ?path2DNumTypesID ?path2DTypesID ?path2DWindingRuleID ?sg2dStrokeHintID ?std_img_oda_blue ?std_img_oda_green ?std_img_oda_red ?std_odas_computed ?sunHints_INTVAL_STROKE_PURE java.desktop/libawt on solaris: A number of "#pragma weak" directives was previously overridden by the mapfile. Now these directives are respected, so these symbols are now weak instead of local: ?ByteGrayToIntArgbPreConvert_F ?ByteGrayToIntArgbPreScaleConvert_F ?IntArgbBmToFourByteAbgrPreScaleXparOver_F ?IntArgbToIntRgbXorBlit_F ?IntBgrToIntBgrAlphaMaskBlit_F java.desktop/libawt on solaris: These are now also exported due to JNIEXPORT in libmlib_image. ?j2d_mlib_ImageCreate ?j2d_mlib_ImageCreateStruct ?j2d_mlib_ImageDelete java.desktop/libawt on solaris: This is now also exported due to JNIEXPORT: ?GrPrim_CompGetXorColor ?SurfaceData_GetOpsNoSetup ?SurfaceData_IntersectBoundsXYWH ?SurfaceData_SetOps ?Transform_GetInfo ?Transform_transform java.desktop/libsplashscreen: JNI_OnLoad is now exported on linux and solaris due to JNIEXPORT. libspashscreen also had JNIEXPORT (actually a pure _declspec(dllexport)) but no JNICALL, which I added as a part of converting to JNIEXPORT. The same goes for libmlib_image . jdk.sctp/libsctp: handleSocketError is now exported on linux and solaris due to JNIEXPORT in libnio. java.instrument:/libinstrument: Agent_OnUnload is now also exported on linux and solaris platforms due to JNIEXPORT. JLI_ManifestIterate is now also exported on Windows, due to added JNIEXPORT in libjli. jdk.management/libmanagement_ext: Java_com_sun_management_internal_Flag_setDoubleValue is now also exported on linux and solaris platforms due to JNIEXPORT. /Magnus From Roger.Riggs at Oracle.com Fri Mar 23 14:12:59 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 23 Mar 2018 10:12:59 -0400 Subject: RFR 8197595: Serialization javadoc should link to security best practices Message-ID: <203836fb-abd6-1191-9499-b96e6a29ad3d@Oracle.com> Please review adding a warning and a link to the Secure Coding Guidelines and the new Serial Filter guide[2] included in the JDK 10 docs. The warnings are added to Serializable, ObjectInputStream, ObjectInputFilter and the java.io package summary. webrev: http://cr.openjdk.java.net/~rriggs/webrev-serialwarn-8197595/index.html javadoc: http://cr.openjdk.java.net/~rriggs/serialwarn/api/java.base/java/io/package-summary.html Thanks, Roger [2] https://docs.oracle.com/javase/10/core/serialization-filtering1.htm#JSCOR-GUID-3ECB288D-E5BD-4412-892F-E9BB11D4C98A From erik.joelsson at oracle.com Fri Mar 23 14:30:14 2018 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Fri, 23 Mar 2018 07:30:14 -0700 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> Message-ID: <86488d2c-61e3-e489-d9fc-976178c35775@oracle.com> I have looked at the build changes and they look good. Will you file followups for each component team to look over their exported symbols, at least for the libraries with $(EXPORT_ALL_SYMBOLS)? It sure looks like there is some technical debt laying around here. /Erik On 2018-03-23 06:56, Magnus Ihse Bursie wrote: > With modern compilers, we can use compiler directives (such as > _attribute__((visibility("default"))), or __declspec(dllexport)) to > control symbol visibility, directly in the source code. This has > historically not been present on all compilers, so we had to resort to > using mapfiles (also known as linker scripts). > > This is no longer the case. Now all compilers we use support symbol > visibility directives, in one form or another. We should start using > this. Since this has been the only way to control symbol visibility on > Windows, for most of the shared code, we already have proper JNIEXPORT > decorations in place. > > If we fix the remaining platform-specific files to have proper > JNIEXPORT tagging, then we can finally get rid of mapfiles. > > This fix removed mapfiles for all JDK libraries. It does not touch > hotspot libraries nor JDK executables; they will have to wait for a > future fix -- this was complex enough. This change will not have any > impact on macosx, since we do not use mapfiles there, but instead > export all symbols. (This is not a good idea, but I'll address that > separately.) This change will also have a minimal impact on Windows. > The only reason Windows is impacted at all, is that some changes > needed by Solaris and Linux were simpler to fix for all platforms. > > I have strived for this change to have no impact on the actual > generated code. Unfortunately, this was not possible to fully achieve. > I do not believe that these changes will have any actual impact on the > product, though. I will present the differences more in detail further > down. Those who are not interested can probably skip that. > > The patch has passed tier1 testing and is currently running tier2 and > tier3. Since the running code is more or less (see caveat below) > unmodified, I don't expect any testing issues. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8200178 > WebRev: > http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01 > > Details on changes: > Most of the source code changes are (unsurprisingly) in java.base and > java.desktop. Remaining changes are in jdk.crypto.ucrypto, > jdk.hotspot.agent, jdk.jdi and jdk.jdwp.agent. > > Source code changes does almost to 100% consists in decorating an > exported function with JNIEXPORT. I have also followed the > long-standing convention of adding JNICALL. This is a no-op on > non-Windows platforms, so for most of the changes this is purely > cosmetic (and possibly adding in robustness, should the function ever > be used on Windows in the future). I have also followed the stylistic > convention of putting "JNIEXPORT JNICALL" on a separate > line. For some functions, however, this might cause a change in > calling convention on Windows. Since this can not apply to exported > functions on Windows (otherwise they would already have had > JNIEXPORT), I do not think this matters anything. > > A few libraries did not have a mapfile, on Linux and/or Solaris. This > actually meant that all symbols were exported. It is highly unclear if > this was known and intended by the original make rule writer. I have > emulated this by adding the flag $(EXPORT_ALL_SYMBOLS) to these > libraries. Hopefully, we can remove this flag and fix proper exported > symbols in the future. > > I have run the complete build using COMPARE_BUILD, and made a > thourough analysis of the differences for Linux and Solaris. All > native libraries have symbol differences, but most of them are trivial > and/or harmless. As a result, most libraries have disasm differences > as well, but these too seem trivial and harmless. The differences in > symbols that are common to all libraries include: > ?* Internal symbols such as __bss_start, _edata, _end and _fini are > now global. (They are imported as such from the compiler > libraries/archives, and we have no linker script to override this > behavior). > ?* The versioning tag SUNWprivate_1.1 is not included, and thus > neither the .gnu.version_d symbol. > ?* There are a few differences in the symbol and/or mangling of some > local functions. I'm not sure what's causing this, > but it's unlikely to have any effect on the product. > > Another common source for change in symbols is due to previous > platform differences. For instance, if we had "JNIEXPORT int JNICALL > do_foo() { ... }", but do_foo was not in the mapfile, the symbol was > exported on Windows but not on Linux and Solaris. (Presumable since it > was not needed there, even though it was compiled for those platforms > as well.) Now, with the mapfiles gone, do_foo() will be exported on > all platforms. And contrary, functions that are compiled on all > platforms, and were exported in mapfiles, but now have gotten an > JNIEXPORT decoration, will now be visible even on Windows. (This > accounts for half of the noticed symbol differences on Windows.) I > could have made the JNIEXPORT conditional on OS, but I didn't think > the mess in source code were worth the keeping of binary confidence > with the old build. > > A third common source for change in symbols is due to exported > functions "leaking" across library borders. For instance, some > functions in java.desktop is compiled in both libawt_xawt and > libawt_headless, but they were previously only included in the mapfile > for one of these libraries. Now, since the visibility is determined by > the source code itself, it gets exported in both libraries. A variant > of this is when a library depends on another JDK library, and includes > the header file from that other library, which in turn declares a > function as JNIEXPORT. This will cause the including library to also > export the function. This accounts for the other half of the changes > on Windows. A typical example of this is that multiple libraries now > re-export hotspot symbols from libjvm.so, like jio_fprintf. (I have > not listed the libjvm re-exports below.) > > Note that? Java_java_io_FileOutputStream_close0 in > java.base/unix/native/libjava/FileOutputStream_md.c is no longer > exported, > and can probably be removed. > > Here is a detailed table showing and accounting for all the remaining > differences found on Linux and Solaris: > java.base/unix/native/libjava: Java_java_io_FileOutputStream_close0 is > now also exported on unix platforms due to JNIEXPORT. > > java.base/jspawnlauncher: On solaris, we also include > libjava/childproc.o, which > now exports less functions than it used to (it used to export all > functions, now it is compiled with visibility=hidden). > > java.base/java(w).exe: Is now also exporting the following symbols due > to added JNIEXPORT in libjli on Windows: > (Yes, executables can export symbols on Windows. Confusing, I know.) > ?JLI_AddArgsFromEnvVar > ?JLI_CmdToArgs > ?JLI_GetAppArgIndex > ?JLI_GetStdArgc > ?JLI_GetStdArgs > ?JLI_InitArgProcessing > ?JLI_Launch > ?JLI_List_add > ?JLI_List_new > ?JLI_ManifestIterate > ?JLI_MemAlloc > ?JLI_MemFree > ?JLI_PreprocessArg > ?JLI_ReportErrorMessage > ?JLI_ReportErrorMessageSys > ?JLI_ReportExceptionDescription > ?JLI_ReportMessage > ?JLI_SetTraceLauncher > ?JLI_StringDup > > java.desktop:/libawt_xawt: The following symbols are now also exported > on linux and solaris due to JNIEXPORT: > ?awt_DrawingSurface_FreeDrawingSurfaceInfo > ?awt_DrawingSurface_GetDrawingSurfaceInfo > ?awt_DrawingSurface_Lock > ?awt_DrawingSurface_Unlock > ?awt_GetColor > > The following symbols are now also exported on linux and solaris due > to JNIEXPORT (they were previously > ?exported only in libawt): > ?Java_sun_awt_DebugSettings_setCTracingOn__Z > ?Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2 > ?Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2I > ?Java_sun_awt_X11GraphicsConfig_getNumColors > > java.desktop:/libawt_headless: The following symbols are now also > exported due to JNIEXPORT (they were previously > ?exported only in libawt_xawt and/or libawt): > ?Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo > ?Java_sun_java2d_opengl_GLXGraphicsConfig_getOGLCapabilities > ?Java_sun_java2d_x11_X11PMBlitLoops_updateBitmask > ?Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable > ?X11SurfaceData_GetOps > > java.desktop/libawt: The following symbols are now also exported on > Windows, due to added > JNIEXPORT: > ?SurfaceData_InitOps > ?mul8table > ?div8table > ?doDrawPath > ?doFillPath > ?g_CMpDataID > ?initInverseGrayLut > ?make_dither_arrays > ?make_uns_ordered_dither_array > ?path2DFloatCoordsID > ?path2DNumTypesID > ?path2DTypesID > ?path2DWindingRuleID > ?sg2dStrokeHintID > ?std_img_oda_blue > ?std_img_oda_green > ?std_img_oda_red > ?std_odas_computed > ?sunHints_INTVAL_STROKE_PURE > > java.desktop/libawt on solaris: > A number of "#pragma weak" directives was previously overridden by the > mapfile. > Now these directives are respected, so these symbols are now weak > instead of local: > ?ByteGrayToIntArgbPreConvert_F > ?ByteGrayToIntArgbPreScaleConvert_F > ?IntArgbBmToFourByteAbgrPreScaleXparOver_F > ?IntArgbToIntRgbXorBlit_F > ?IntBgrToIntBgrAlphaMaskBlit_F > > java.desktop/libawt on solaris: These are now also exported due to > JNIEXPORT in libmlib_image. > ?j2d_mlib_ImageCreate > ?j2d_mlib_ImageCreateStruct > ?j2d_mlib_ImageDelete > > java.desktop/libawt on solaris: This is now also exported due to > JNIEXPORT: > ?GrPrim_CompGetXorColor > ?SurfaceData_GetOpsNoSetup > ?SurfaceData_IntersectBoundsXYWH > ?SurfaceData_SetOps > ?Transform_GetInfo > ?Transform_transform > > java.desktop/libsplashscreen: JNI_OnLoad is now exported on linux and > solaris due to JNIEXPORT. > libspashscreen also had JNIEXPORT (actually a pure > _declspec(dllexport)) but no JNICALL, which I added as > a part of converting to JNIEXPORT. The same goes for libmlib_image . > > jdk.sctp/libsctp: handleSocketError is now exported on linux and > solaris due to JNIEXPORT in libnio. > > java.instrument:/libinstrument: Agent_OnUnload is now also exported on > linux and solaris platforms due to JNIEXPORT. > JLI_ManifestIterate is now also exported on Windows, due to added > JNIEXPORT in libjli. > > jdk.management/libmanagement_ext: > Java_com_sun_management_internal_Flag_setDoubleValue is now also > exported on linux and solaris platforms due to JNIEXPORT. > > /Magnus > > From sean.mullan at oracle.com Fri Mar 23 14:33:00 2018 From: sean.mullan at oracle.com (Sean Mullan) Date: Fri, 23 Mar 2018 10:33:00 -0400 Subject: RFR 8197595: Serialization javadoc should link to security best practices In-Reply-To: <203836fb-abd6-1191-9499-b96e6a29ad3d@Oracle.com> References: <203836fb-abd6-1191-9499-b96e6a29ad3d@Oracle.com> Message-ID: Looks good to me. Minor nit, I would add "the" before "Secure Coding Guidelines for Java SE". I would also change "must" to "should" as these are recommended best practices, and not requirements that we can enforce. --Sean On 3/23/18 10:12 AM, Roger Riggs wrote: > Please review adding a warning and a link to the Secure Coding Guidelines > and the new Serial Filter guide[2] included in the JDK 10 docs. > The warnings are added to Serializable, ObjectInputStream, > ObjectInputFilter and > the java.io package summary. > > webrev: > http://cr.openjdk.java.net/~rriggs/webrev-serialwarn-8197595/index.html > > javadoc: > http://cr.openjdk.java.net/~rriggs/serialwarn/api/java.base/java/io/package-summary.html > > > Thanks, Roger > > [2] > https://docs.oracle.com/javase/10/core/serialization-filtering1.htm#JSCOR-GUID-3ECB288D-E5BD-4412-892F-E9BB11D4C98A > > > From Alan.Bateman at oracle.com Fri Mar 23 14:45:09 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 23 Mar 2018 14:45:09 +0000 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> Message-ID: <16419c9d-df6a-c6cb-8357-470643d99cb3@oracle.com> On 23/03/2018 13:56, Magnus Ihse Bursie wrote: > With modern compilers, we can use compiler directives (such as > _attribute__((visibility("default"))), or __declspec(dllexport)) to > control symbol visibility, directly in the source code. This has > historically not been present on all compilers, so we had to resort to > using mapfiles (also known as linker scripts). > > This is no longer the case. Now all compilers we use support symbol > visibility directives, in one form or another. We should start using > this. Since this has been the only way to control symbol visibility on > Windows, for most of the shared code, we already have proper JNIEXPORT > decorations in place. > > If we fix the remaining platform-specific files to have proper > JNIEXPORT tagging, then we can finally get rid of mapfiles. This seems like a great cleanup as the mapfile have always been a pain to maintain. Also shines a light on some technical debt too. handleSocketError in libnio is a surprise, this should not be exported and should not have been in the map file.? I suspect the issue is that jdk.sctp is missing a function prototype from its header file (it has its own handleSocketError in SctpNet.c). NET_Wait in libnet is another one, I can't tell why this was listed in the map file. I'm also surprised with java.dll exporting handleRead, winHandleRead, and handleLSeek. I didn't see them mentioned in your mail so I'm curious what might be using those. -Alan From magnus.ihse.bursie at oracle.com Fri Mar 23 15:15:35 2018 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Fri, 23 Mar 2018 16:15:35 +0100 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <16419c9d-df6a-c6cb-8357-470643d99cb3@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> <16419c9d-df6a-c6cb-8357-470643d99cb3@oracle.com> Message-ID: > 23 mars 2018 kl. 15:45 skrev Alan Bateman : > >> On 23/03/2018 13:56, Magnus Ihse Bursie wrote: >> With modern compilers, we can use compiler directives (such as _attribute__((visibility("default"))), or __declspec(dllexport)) to control symbol visibility, directly in the source code. This has historically not been present on all compilers, so we had to resort to using mapfiles (also known as linker scripts). >> >> This is no longer the case. Now all compilers we use support symbol visibility directives, in one form or another. We should start using this. Since this has been the only way to control symbol visibility on Windows, for most of the shared code, we already have proper JNIEXPORT decorations in place. >> >> If we fix the remaining platform-specific files to have proper JNIEXPORT tagging, then we can finally get rid of mapfiles. > This seems like a great cleanup as the mapfile have always been a pain to maintain. Also shines a light on some technical debt too. Very much so, yes. I've found a lot of dubious exports, everything from global variables (yuck!) to functions that does not seem to be used anymore, to lots of strange exports. > handleSocketError in libnio is a surprise, this should not be exported and should not have been in the map file. I suspect the issue is that jdk.sctp is missing a function prototype from its header file (it has its own handleSocketError in SctpNet.c). That might be so, yes. > NET_Wait in libnet is another one, I can't tell why this was listed in the map file. Neither can I. :-) Once again, my goal with this patch was to keep the produced binaries as similar to before with the mapfiles. I'll be happy to file follow-up bugs listing all suspicious symbol handling I've encountered, but I'd rather not change anything about that in this patch. > I'm also surprised with java.dll exporting handleRead, winHandleRead, and handleLSeek. I didn't see them mentioned in your mail so I'm curious what might be using those. They were previously exported using -export: on the command line for the Microsoft linker. This was the case for a couple other libraries as well. Yeah, I forgot to write about that, sorry. :( Been a lot to keep track of, and it went away when I cleaned up my notes. Can I consider this a review? /Magnus > > -Alan From david.lloyd at redhat.com Fri Mar 23 15:18:53 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Fri, 23 Mar 2018 10:18:53 -0500 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> Message-ID: Are there any further comments on this? If not, would it be possible to get a sponsor for this change? Sorry again for the detached email threads; I've learned my GMail lesson well... Thanks. On Fri, Mar 16, 2018 at 8:25 AM, David Lloyd wrote: > Sorry, that was an error on my part, caused by too much context > switching. I've posted an update at > https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v13 which is > also attached. > > On Wed, Mar 14, 2018 at 8:53 PM, Xueming Shen wrote: >> Hi David, >> >> https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v12 >> >> Should we start to review the changes included in above link, or we should >> wait ? It appears >> the API is being updated but some implementation have not been updated to >> follow the spec >> yet, especially the piece that deals with the output buffer/byteWritten when >> DataFormatException >> is raised, for example >> >> (1) the "outputConsumedID" is defined but never used to update the >> corresponding java field >> in Inflater.c and >> >> (2) the "outputConsumed" is used to update the output ByteBuffer when DFE >> raised (in Java), but >> the corresponding "byteWritten" is not being updated before the >> exception is thrown. >> >> -Sherman >> >> >> >> >> On 3/13/18, 10:46 AM, David Lloyd wrote: >>> >>> Sorry all, it looks like GMail doesn't know how to keep replies with >>> the thread when you change the subject line. The follow-up to this >>> thread is >>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-March/051960.html >>> with only a few small changes as discussed above. >>> >>> On Fri, Mar 2, 2018 at 2:36 PM, David Lloyd >>> wrote: >>>> >>>> On Fri, Mar 2, 2018 at 2:34 PM, David Lloyd >>>> wrote: >>>>> >>>>> On Fri, Mar 2, 2018 at 12:49 PM, Xueming Shen >>>>> wrote: >>>>>> >>>>>> Hi David, >>>>>> >>>>>> (1) Deflater.deflate(Bytebuffer) >>>>>> the api doc regarding "no_flush" appears to be the copy/paste of >>>>>> the >>>>>> byte[] version >>>>>> without being updated to the corresponding ByteBuffer? >>>>> >>>>> You're right, I missed that one. I've incorporated this fix locally: >>>> >>>> Oops, this should have been: >>>> >>>> --- 8< --- cut here --- 8< --- >>>> >>>> diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java >>>> b/src/java.base/share/classes/java/util/zip/Deflater.java >>>> index 524125787a8..40f0d9736e2 100644 >>>> --- a/src/java.base/share/classes/java/util/zip/Deflater.java >>>> +++ b/src/java.base/share/classes/java/util/zip/Deflater.java >>>> @@ -481,9 +481,9 @@ public class Deflater { >>>> * in order to determine if more input data is required. >>>> * >>>> *

This method uses {@link #NO_FLUSH} as its compression flush >>>> mode. >>>> - * An invocation of this method of the form {@code >>>> deflater.deflate(b)} >>>> + * An invocation of this method of the form {@code >>>> deflater.deflate(output)} >>>> * yields the same result as the invocation of >>>> - * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. >>>> + * {@code deflater.deflate(output, Deflater.NO_FLUSH)}. >>>> * >>>> * @param output the buffer for the compressed data >>>> * @return the actual number of bytes of compressed data written to >>>> the >>>> >>>> --- 8< --- cut here --- 8< --- >>>> >>>> -- >>>> - DML >>> >>> >>> >> > > > > -- > - DML -- - DML From Roger.Riggs at Oracle.com Fri Mar 23 15:35:05 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 23 Mar 2018 11:35:05 -0400 Subject: RFR of 8180451: ByteArrayInputStream should override readAllBytes, readNBytes, and transferTo In-Reply-To: References: <09F39E3A-76B0-4D36-98F3-78AD246B91A7@oracle.com> <37818C83-0741-42EE-AD95-6259695E2DF9@oracle.com> <50B3A2D3-82B0-48DB-95D9-6318F1491725@oracle.com> Message-ID: <8b8ca5fe-d6ae-8483-589c-d339b0777696@Oracle.com> Hi Brian, Looks fine. Cosmetically, you could join some of the lines in ByteArrayInputStream 153-164. In the test, ReadAllReadNTransferTo.java 53-54:? spaces around "/" and before "-" No further review needed. Thanks, Roger On 3/21/2018 2:01 PM, Brian Burkhalter wrote: > This is still in need of final approval, assuming it is OK. > > Thanks, > > Brian > > On Mar 14, 2018, at 10:50 AM, Brian Burkhalter wrote: > >> On Mar 14, 2018, at 9:27 AM, David Lloyd wrote: >> >>> @@ -196,14 +194,32 @@ >>> return len; >>> } >>> >>> + public synchronized byte[] readAllBytes() { >>> + byte[] result = Arrays.copyOfRange(buf, pos, count); >>> + pos = count; >>> + return result; >>> + } >>> + >>> + public synchronized int readNBytes(byte[] b, int off, int len) { >>> + int n = read(b, off, len); >>> + return n == -1 ? 0 : n; >>> + } >>> >>> This probably doesn't need to be synchronized, though I imagine the >>> difference would be minimal. >> You are correct, it does not. >> >>> + public synchronized long transferTo(OutputStream out) throws IOException { >>> + int len = count - pos >>> + out.write(but, pos, len); >>> >>> s/but/buf/ I guess? >> Webrevs corrected in place: >> >> http://cr.openjdk.java.net/~bpb/8180451/webrev.00-01/ >> http://cr.openjdk.java.net/~bpb/8180451/webrev.01/ From brian.burkhalter at oracle.com Fri Mar 23 15:39:30 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Fri, 23 Mar 2018 08:39:30 -0700 Subject: RFR of 8180451: ByteArrayInputStream should override readAllBytes, readNBytes, and transferTo In-Reply-To: <8b8ca5fe-d6ae-8483-589c-d339b0777696@Oracle.com> References: <09F39E3A-76B0-4D36-98F3-78AD246B91A7@oracle.com> <37818C83-0741-42EE-AD95-6259695E2DF9@oracle.com> <50B3A2D3-82B0-48DB-95D9-6318F1491725@oracle.com> <8b8ca5fe-d6ae-8483-589c-d339b0777696@Oracle.com> Message-ID: <84A3DEA5-EA5A-4F0B-9FE7-34A05B914F01@oracle.com> Hi Roger, Thanks for the review. I?ll update it prior to checking it in. Brian On Mar 23, 2018, at 8:35 AM, Roger Riggs wrote: > Looks fine. > > Cosmetically, you could join some of the lines in ByteArrayInputStream 153-164. > > In the test, ReadAllReadNTransferTo.java > 53-54: spaces around "/" and before "-" > > No further review needed. From Alan.Bateman at oracle.com Fri Mar 23 16:04:12 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 23 Mar 2018 16:04:12 +0000 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> <16419c9d-df6a-c6cb-8357-470643d99cb3@oracle.com> Message-ID: <810a6225-15af-6858-8bea-2c3122ac1c5d@oracle.com> On 23/03/2018 15:15, Magnus Ihse Bursie wrote: > : > Very much so, yes. I've found a lot of dubious exports, everything from global variables (yuck!) to functions that does not seem to be used anymore, to lots of strange exports. The changes looks good to me and I think we should follow this up with a few JIRA issues (as you suggested) for the symbols that don't make sense to export. -Alan From mandy.chung at oracle.com Fri Mar 23 16:05:23 2018 From: mandy.chung at oracle.com (mandy chung) Date: Fri, 23 Mar 2018 09:05:23 -0700 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <86488d2c-61e3-e489-d9fc-976178c35775@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> <86488d2c-61e3-e489-d9fc-976178c35775@oracle.com> Message-ID: <2329dea1-a75e-bb70-95a6-242a93006c6d@oracle.com> This is a very good change and no more mapfile to maintain!! Please do file JBS issues for the component teams to clean up their exports. Mandy On 3/23/18 7:30 AM, Erik Joelsson wrote: > I have looked at the build changes and they look good. > > Will you file followups for each component team to look over their > exported symbols, at least for the libraries with > $(EXPORT_ALL_SYMBOLS)? It sure looks like there is some technical debt > laying around here. > > /Erik > > > On 2018-03-23 06:56, Magnus Ihse Bursie wrote: >> With modern compilers, we can use compiler directives (such as >> _attribute__((visibility("default"))), or __declspec(dllexport)) to >> control symbol visibility, directly in the source code. This has >> historically not been present on all compilers, so we had to resort >> to using mapfiles (also known as linker scripts). >> >> This is no longer the case. Now all compilers we use support symbol >> visibility directives, in one form or another. We should start using >> this. Since this has been the only way to control symbol visibility >> on Windows, for most of the shared code, we already have proper >> JNIEXPORT decorations in place. >> >> If we fix the remaining platform-specific files to have proper >> JNIEXPORT tagging, then we can finally get rid of mapfiles. >> >> This fix removed mapfiles for all JDK libraries. It does not touch >> hotspot libraries nor JDK executables; they will have to wait for a >> future fix -- this was complex enough. This change will not have any >> impact on macosx, since we do not use mapfiles there, but instead >> export all symbols. (This is not a good idea, but I'll address that >> separately.) This change will also have a minimal impact on Windows. >> The only reason Windows is impacted at all, is that some changes >> needed by Solaris and Linux were simpler to fix for all platforms. >> >> I have strived for this change to have no impact on the actual >> generated code. Unfortunately, this was not possible to fully >> achieve. I do not believe that these changes will have any actual >> impact on the product, though. I will present the differences more in >> detail further down. Those who are not interested can probably skip >> that. >> >> The patch has passed tier1 testing and is currently running tier2 and >> tier3. Since the running code is more or less (see caveat below) >> unmodified, I don't expect any testing issues. >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8200178 >> WebRev: >> http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01 >> >> Details on changes: >> Most of the source code changes are (unsurprisingly) in java.base and >> java.desktop. Remaining changes are in jdk.crypto.ucrypto, >> jdk.hotspot.agent, jdk.jdi and jdk.jdwp.agent. >> >> Source code changes does almost to 100% consists in decorating an >> exported function with JNIEXPORT. I have also followed the >> long-standing convention of adding JNICALL. This is a no-op on >> non-Windows platforms, so for most of the changes this is purely >> cosmetic (and possibly adding in robustness, should the function ever >> be used on Windows in the future). I have also followed the stylistic >> convention of putting "JNIEXPORT JNICALL" on a separate >> line. For some functions, however, this might cause a change in >> calling convention on Windows. Since this can not apply to exported >> functions on Windows (otherwise they would already have had >> JNIEXPORT), I do not think this matters anything. >> >> A few libraries did not have a mapfile, on Linux and/or Solaris. This >> actually meant that all symbols were exported. It is highly unclear >> if this was known and intended by the original make rule writer. I >> have emulated this by adding the flag $(EXPORT_ALL_SYMBOLS) to these >> libraries. Hopefully, we can remove this flag and fix proper exported >> symbols in the future. >> >> I have run the complete build using COMPARE_BUILD, and made a >> thourough analysis of the differences for Linux and Solaris. All >> native libraries have symbol differences, but most of them are >> trivial and/or harmless. As a result, most libraries have disasm >> differences as well, but these too seem trivial and harmless. The >> differences in symbols that are common to all libraries include: >> ?* Internal symbols such as __bss_start, _edata, _end and _fini are >> now global. (They are imported as such from the compiler >> libraries/archives, and we have no linker script to override this >> behavior). >> ?* The versioning tag SUNWprivate_1.1 is not included, and thus >> neither the .gnu.version_d symbol. >> ?* There are a few differences in the symbol and/or mangling of some >> local functions. I'm not sure what's causing this, >> but it's unlikely to have any effect on the product. >> >> Another common source for change in symbols is due to previous >> platform differences. For instance, if we had "JNIEXPORT int JNICALL >> do_foo() { ... }", but do_foo was not in the mapfile, the symbol was >> exported on Windows but not on Linux and Solaris. (Presumable since >> it was not needed there, even though it was compiled for those >> platforms as well.) Now, with the mapfiles gone, do_foo() will be >> exported on all platforms. And contrary, functions that are compiled >> on all platforms, and were exported in mapfiles, but now have gotten >> an JNIEXPORT decoration, will now be visible even on Windows. (This >> accounts for half of the noticed symbol differences on Windows.) I >> could have made the JNIEXPORT conditional on OS, but I didn't think >> the mess in source code were worth the keeping of binary confidence >> with the old build. >> >> A third common source for change in symbols is due to exported >> functions "leaking" across library borders. For instance, some >> functions in java.desktop is compiled in both libawt_xawt and >> libawt_headless, but they were previously only included in the >> mapfile for one of these libraries. Now, since the visibility is >> determined by the source code itself, it gets exported in both >> libraries. A variant of this is when a library depends on another JDK >> library, and includes the header file from that other library, which >> in turn declares a function as JNIEXPORT. This will cause the >> including library to also export the function. This accounts for the >> other half of the changes on Windows. A typical example of this is >> that multiple libraries now re-export hotspot symbols from libjvm.so, >> like jio_fprintf. (I have not listed the libjvm re-exports below.) >> >> Note that? Java_java_io_FileOutputStream_close0 in >> java.base/unix/native/libjava/FileOutputStream_md.c is no longer >> exported, >> and can probably be removed. >> >> Here is a detailed table showing and accounting for all the remaining >> differences found on Linux and Solaris: >> java.base/unix/native/libjava: Java_java_io_FileOutputStream_close0 >> is now also exported on unix platforms due to JNIEXPORT. >> >> java.base/jspawnlauncher: On solaris, we also include >> libjava/childproc.o, which >> now exports less functions than it used to (it used to export all >> functions, now it is compiled with visibility=hidden). >> >> java.base/java(w).exe: Is now also exporting the following symbols >> due to added JNIEXPORT in libjli on Windows: >> (Yes, executables can export symbols on Windows. Confusing, I know.) >> ?JLI_AddArgsFromEnvVar >> ?JLI_CmdToArgs >> ?JLI_GetAppArgIndex >> ?JLI_GetStdArgc >> ?JLI_GetStdArgs >> ?JLI_InitArgProcessing >> ?JLI_Launch >> ?JLI_List_add >> ?JLI_List_new >> ?JLI_ManifestIterate >> ?JLI_MemAlloc >> ?JLI_MemFree >> ?JLI_PreprocessArg >> ?JLI_ReportErrorMessage >> ?JLI_ReportErrorMessageSys >> ?JLI_ReportExceptionDescription >> ?JLI_ReportMessage >> ?JLI_SetTraceLauncher >> ?JLI_StringDup >> >> java.desktop:/libawt_xawt: The following symbols are now also >> exported on linux and solaris due to JNIEXPORT: >> ?awt_DrawingSurface_FreeDrawingSurfaceInfo >> ?awt_DrawingSurface_GetDrawingSurfaceInfo >> ?awt_DrawingSurface_Lock >> ?awt_DrawingSurface_Unlock >> ?awt_GetColor >> >> The following symbols are now also exported on linux and solaris due >> to JNIEXPORT (they were previously >> ?exported only in libawt): >> ?Java_sun_awt_DebugSettings_setCTracingOn__Z >> ?Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2 >> ?Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2I >> ?Java_sun_awt_X11GraphicsConfig_getNumColors >> >> java.desktop:/libawt_headless: The following symbols are now also >> exported due to JNIEXPORT (they were previously >> ?exported only in libawt_xawt and/or libawt): >> ?Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo >> ?Java_sun_java2d_opengl_GLXGraphicsConfig_getOGLCapabilities >> ?Java_sun_java2d_x11_X11PMBlitLoops_updateBitmask >> ?Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable >> ?X11SurfaceData_GetOps >> >> java.desktop/libawt: The following symbols are now also exported on >> Windows, due to added >> JNIEXPORT: >> ?SurfaceData_InitOps >> ?mul8table >> ?div8table >> ?doDrawPath >> ?doFillPath >> ?g_CMpDataID >> ?initInverseGrayLut >> ?make_dither_arrays >> ?make_uns_ordered_dither_array >> ?path2DFloatCoordsID >> ?path2DNumTypesID >> ?path2DTypesID >> ?path2DWindingRuleID >> ?sg2dStrokeHintID >> ?std_img_oda_blue >> ?std_img_oda_green >> ?std_img_oda_red >> ?std_odas_computed >> ?sunHints_INTVAL_STROKE_PURE >> >> java.desktop/libawt on solaris: >> A number of "#pragma weak" directives was previously overridden by >> the mapfile. >> Now these directives are respected, so these symbols are now weak >> instead of local: >> ?ByteGrayToIntArgbPreConvert_F >> ?ByteGrayToIntArgbPreScaleConvert_F >> ?IntArgbBmToFourByteAbgrPreScaleXparOver_F >> ?IntArgbToIntRgbXorBlit_F >> ?IntBgrToIntBgrAlphaMaskBlit_F >> >> java.desktop/libawt on solaris: These are now also exported due to >> JNIEXPORT in libmlib_image. >> ?j2d_mlib_ImageCreate >> ?j2d_mlib_ImageCreateStruct >> ?j2d_mlib_ImageDelete >> >> java.desktop/libawt on solaris: This is now also exported due to >> JNIEXPORT: >> ?GrPrim_CompGetXorColor >> ?SurfaceData_GetOpsNoSetup >> ?SurfaceData_IntersectBoundsXYWH >> ?SurfaceData_SetOps >> ?Transform_GetInfo >> ?Transform_transform >> >> java.desktop/libsplashscreen: JNI_OnLoad is now exported on linux and >> solaris due to JNIEXPORT. >> libspashscreen also had JNIEXPORT (actually a pure >> _declspec(dllexport)) but no JNICALL, which I added as >> a part of converting to JNIEXPORT. The same goes for libmlib_image . >> >> jdk.sctp/libsctp: handleSocketError is now exported on linux and >> solaris due to JNIEXPORT in libnio. >> >> java.instrument:/libinstrument: Agent_OnUnload is now also exported >> on linux and solaris platforms due to JNIEXPORT. >> JLI_ManifestIterate is now also exported on Windows, due to added >> JNIEXPORT in libjli. >> >> jdk.management/libmanagement_ext: >> Java_com_sun_management_internal_Flag_setDoubleValue is now also >> exported on linux and solaris platforms due to JNIEXPORT. >> >> /Magnus >> >> > From dhiller at twitter.com Thu Mar 22 18:21:46 2018 From: dhiller at twitter.com (Dean Hiller) Date: Thu, 22 Mar 2018 12:21:46 -0600 Subject: revisiting MDC in slf4j broken because of CompletableFuture In-Reply-To: <85B3F22F-A5B5-42C5-AC91-7D64CF1151AF@dslextreme.com> References: <85B3F22F-A5B5-42C5-AC91-7D64CF1151AF@dslextreme.com> Message-ID: I am basically asking for someone to copy the solution in twitter Future.scala(which uses Local.scala) into CompletableFuture.java, yes. ie. I should be able to say Local.set("something", value) and in CompletableFuture when .map is called, it will ensure the key/values are transferred across threads. Local.scala internally uses a ThreadLocal up into the point of .map/.flatMap (ie. thenApply/.thenCompose). At that point, it transfers it across threads into a new ThreadLocal. ie. the answer on how to do it exists here(search on Locals and see it in the respond method which is called by map and flatMap).. https://github.com/simonratner/twitter-util/blob/master/util-core/src/main/scala/com/twitter/util/Future.scala Here is the Local class that clients use and the Future uses to transfer contexts across map/flatMap https://github.com/simonratner/twitter-util/blob/master/util-core/src/main/scala/com/twitter/util/Local.scala (I do apologize if you do not read scala code, but the answer is there and just in a different language) later, Dean On Thu, Mar 22, 2018 at 11:40 AM, Ralph Goers wrote: > Having read several of the threads I think I have a better understanding > of the problem. This sounds similar to problems that occur with any > application that has a way of doing asynchronous processing with with > thread pools. Java has unfortunately not provided a good way that I know of > to pass a ThreadLocal from one thread to a worker thread. I am guessing > that is what you are really asking for is some sort of property on the > Executor that tells it to pass the ThreadLocals from one thread to the > worker that performs action on its behalf. > > Ralph > > > On Mar 22, 2018, at 10:13 AM, Ralph Goers > wrote: > > > > Log4j 2 supports a ThreadContext which is analogous to the SLF4J MDC. > Both are based on ThreadLocal variables. If I understand what you are > saying, the problem is that ThreadLocals do not work as you you would > expect when using CompleteableFutures? > > > > Ralph > > > >> On Mar 22, 2018, at 7:05 AM, Dean Hiller wrote: > >> > >> slf4j is pretty much the defacto logging standard these days allowing > one > >> to bring in libraries using any logging framework. (commons logging > fell > >> short and had classloading bugs). > >> > >> Summary: MDC works fine in twitter scala Futures but not java > >> CompletableFutures. > >> > >> Unfortunately, one of the best features(brought over from log4j which is > >> also broken now) is the MDC. The MDC no longer works with > >> CompletableFutures so people will have to move to scala where it does > work. > >> > >> Documentation on MDC if you don't know what that is.... > >> https://logback.qos.ch/manual/mdc.html > >> > >> or for a more concrete example, as a developer a request comes in and > you > >> set MDC.put("requestId", requestId) and now whenever you log, that > request > >> id is added to your log line. No developer has to 'remember' to add it > >> every time he adds a log statement. > >> > >> This is due to the lack of Local.java file that should exist and > transfer > >> context over the .thenApply/.thenCompose methods like twitter Futures > has > >> in scala land. (see Local.scala in twitter Futures and the twitter > Future > >> code for how this works) > >> > >> In scala, it works and we have all the same methods as CompletableFuture > >> for the most part and yes, we can't transfer the context over some > methods, > >> but at least our MDC in scala servers is not broken. > >> > >> Lack of this feature is forcing our hand to code in scala where it is > not > >> broken. ie. we need logging and we definitely need the request id or > >> client id or whatever attached automatically to every log(as humans have > >> trouble remembering to add it themselves every single time). > >> > >> thanks for reconsidering, > >> Dean > >> > >> On Tue, May 23, 2017 at 10:20 AM, Dean Hiller > wrote: > >> > >>> All, this post is all about 3rd party code that I do not control so > >>> therefore the solutions above do not work as those libraries may > predate my > >>> library. more specifically..... > >>> > >>> Martin, > >>> If I roll my own slf4j MDC only works in my code and stops working in > >>> 3rd party code! because the 3rd party code does not transfer the > context. > >>> > >>> Viktor, > >>> You hit the head on the nail with "It's easy to lose context when > >>> intermediate libraries/Executors". This is solved on twitter futures > until > >>> we hit libraries not using twitter futures because no matter the > executor, > >>> the future transfers the context for us the way it was written. > >>> > >>> "It's unclear what fan-in behaviors like zip, merge etc mean in terms > >>> of what the local values should be?" > >>> This is a very good question. I wonder what twitter futures do here. > I > >>> would be ok with dropping the context in this case or combining it. I > do > >>> not really care yet here since I have not run into it but it is a very > good > >>> question and would need a lot of thought > >>> > >>> Josh, > >>> I cannot expect all 3rd party libraries that are brought in will be > >>> using ContextPropagatingExecutor so that solution breaks down as Viktor > >>> eludes to. > >>> > >>> Alex, > >>> tuples do not solve the issue. in fact twitter futures have a > >>> Local.scala file that does solve the issue. The main issue is 3rd > party > >>> code and having the context continue into "unknown code" using > >>> CompletableFuture. I cannot control that code BUT want every log.info > in > >>> that code to use and log the request id. it is awesome at twitter as > I can > >>> just follow that request id in the logs. If CompletableFuture had > such a > >>> context, I could transfer this info into it and into the 3rd party java > >>> libraries. > >>> > >>> I am writing a webserver for fun based on CompletableFutures and > therefore > >>> cannot control the controllers as the app developer writes that and the > >>> request id stops getting logged on the request path which is mostly > >>> .thenApply and .thenCompose. even if the Controllers do you my future, > >>> they will bring in libraries NOT using my future :( > >>> > >>> thanks > >>> Dean > >>> > >>> > >>> > >>> > >>> > >>> On Tue, May 23, 2017 at 3:12 AM, Alex Otenko < > oleksandr.otenko at gmail.com> > >>> wrote: > >>> > >>>> Why would someone want to rely on state they cannot control? > >>>> > >>>> Is the idea to subvert some API that does not provide a way to pass > >>>> state? This is strange especially in the context of Scala, where you > can > >>>> easily form tuples. > >>>> > >>>> Alex > >>>> > >>>> On 22 May 2017, at 20:44, Martin Buchholz > wrote: > >>>> > >>>> There's not likely to be any support for local context anywhere in > >>>> java.util.concurrent, but it seems not too hard to roll your own > support > >>>> with a custom executor to be used with CompletableFuture that kept > track of > >>>> any local context. > >>>> > >>>> On Fri, May 19, 2017 at 1:16 PM, Pavel Rappo > >>>> wrote: > >>>> > >>>>> General questions on concurrency in Java should be asked here: > >>>>> > >>>>> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest > >>>>> > >>>>>> On 18 May 2017, at 21:57, Dean Hiller wrote: > >>>>>> > >>>>>> Way more detail here... > >>>>>> > >>>>>> http://stackoverflow.com/questions/37933713/does-completable > >>>>> future-have-a-corresponding-local-context > >>>>>> > >>>>>> So I was wondering if this was going to be added at some point to > the > >>>>> jdk > >>>>>> as I could not figure out how to set something so it was still > >>>>> available on > >>>>>> the thread at a later time when traversing async thenCompose, > >>>>> thenAccept. > >>>>>> > >>>>>> thanks, > >>>>>> Dean > >>>>> > >>>>> > >>>> _______________________________________________ > >>>> Concurrency-interest mailing list > >>>> Concurrency-interest at cs.oswego.edu > >>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest > >>>> > >>>> > >>>> > >>> > >> > > > > > > > > > From dhiller at twitter.com Thu Mar 22 18:32:27 2018 From: dhiller at twitter.com (Dean Hiller) Date: Thu, 22 Mar 2018 12:32:27 -0600 Subject: revisiting MDC in slf4j broken because of CompletableFuture In-Reply-To: <6B4E025A-8CF3-4DAA-A265-518D2C67EA8B@dslextreme.com> References: <85B3F22F-A5B5-42C5-AC91-7D64CF1151AF@dslextreme.com> <6B4E025A-8CF3-4DAA-A265-518D2C67EA8B@dslextreme.com> Message-ID: oh, I see yes, that code could be done in CompletableFuture though...Executor does not have to be touched based on the scala code I read. ie. you create a new Runnable that reads the last Local context transferring into a ThreadLocal until the next transfer is needed(at each .thenApply/.thenCompose boundaries). There are weird methods and I would just not worry about those except as it relates mostly to getting slf4j's MDC to work. On Thu, Mar 22, 2018 at 12:27 PM, Ralph Goers wrote: > My point is that I don?t think this is the only place the problem occurs. > I have seen similar questions on the Log4j mailing list where users want to > be able to do this for thread pools they create via Executors and don?t > want to have to do the ThreadLocal propagation themselves. If a > CompleteableFuture uses an Executor under the covers then it could leverage > the same solution. > > Ralph > > > On Mar 22, 2018, at 11:21 AM, Dean Hiller wrote: > > I am basically asking for someone to copy the solution in twitter > Future.scala(which uses Local.scala) into CompletableFuture.java, yes. > > ie. I should be able to say Local.set("something", value) and in > CompletableFuture when .map is called, it will ensure the key/values are > transferred across threads. Local.scala internally uses a ThreadLocal up > into the point of .map/.flatMap (ie. thenApply/.thenCompose). At that > point, it transfers it across threads into a new ThreadLocal. > > ie. the answer on how to do it exists here(search on Locals and see it in > the respond method which is called by map and flatMap).. > > https://github.com/simonratner/twitter-util/blob/ > master/util-core/src/main/scala/com/twitter/util/Future.scala > > Here is the Local class that clients use and the Future uses to transfer > contexts across map/flatMap > https://github.com/simonratner/twitter-util/blob/ > master/util-core/src/main/scala/com/twitter/util/Local.scala > > (I do apologize if you do not read scala code, but the answer is there and > just in a different language) > > later, > Dean > > > On Thu, Mar 22, 2018 at 11:40 AM, Ralph Goers > wrote: > >> Having read several of the threads I think I have a better understanding >> of the problem. This sounds similar to problems that occur with any >> application that has a way of doing asynchronous processing with with >> thread pools. Java has unfortunately not provided a good way that I know of >> to pass a ThreadLocal from one thread to a worker thread. I am guessing >> that is what you are really asking for is some sort of property on the >> Executor that tells it to pass the ThreadLocals from one thread to the >> worker that performs action on its behalf. >> >> Ralph >> >> > On Mar 22, 2018, at 10:13 AM, Ralph Goers >> wrote: >> > >> > Log4j 2 supports a ThreadContext which is analogous to the SLF4J MDC. >> Both are based on ThreadLocal variables. If I understand what you are >> saying, the problem is that ThreadLocals do not work as you you would >> expect when using CompleteableFutures? >> > >> > Ralph >> > >> >> On Mar 22, 2018, at 7:05 AM, Dean Hiller wrote: >> >> >> >> slf4j is pretty much the defacto logging standard these days allowing >> one >> >> to bring in libraries using any logging framework. (commons logging >> fell >> >> short and had classloading bugs). >> >> >> >> Summary: MDC works fine in twitter scala Futures but not java >> >> CompletableFutures. >> >> >> >> Unfortunately, one of the best features(brought over from log4j which >> is >> >> also broken now) is the MDC. The MDC no longer works with >> >> CompletableFutures so people will have to move to scala where it does >> work. >> >> >> >> Documentation on MDC if you don't know what that is.... >> >> https://logback.qos.ch/manual/mdc.html >> >> >> >> or for a more concrete example, as a developer a request comes in and >> you >> >> set MDC.put("requestId", requestId) and now whenever you log, that >> request >> >> id is added to your log line. No developer has to 'remember' to add it >> >> every time he adds a log statement. >> >> >> >> This is due to the lack of Local.java file that should exist and >> transfer >> >> context over the .thenApply/.thenCompose methods like twitter Futures >> has >> >> in scala land. (see Local.scala in twitter Futures and the twitter >> Future >> >> code for how this works) >> >> >> >> In scala, it works and we have all the same methods as >> CompletableFuture >> >> for the most part and yes, we can't transfer the context over some >> methods, >> >> but at least our MDC in scala servers is not broken. >> >> >> >> Lack of this feature is forcing our hand to code in scala where it is >> not >> >> broken. ie. we need logging and we definitely need the request id or >> >> client id or whatever attached automatically to every log(as humans >> have >> >> trouble remembering to add it themselves every single time). >> >> >> >> thanks for reconsidering, >> >> Dean >> >> >> >> On Tue, May 23, 2017 at 10:20 AM, Dean Hiller >> wrote: >> >> >> >>> All, this post is all about 3rd party code that I do not control so >> >>> therefore the solutions above do not work as those libraries may >> predate my >> >>> library. more specifically..... >> >>> >> >>> Martin, >> >>> If I roll my own slf4j MDC only works in my code and stops working in >> >>> 3rd party code! because the 3rd party code does not transfer the >> context. >> >>> >> >>> Viktor, >> >>> You hit the head on the nail with "It's easy to lose context when >> >>> intermediate libraries/Executors". This is solved on twitter futures >> until >> >>> we hit libraries not using twitter futures because no matter the >> executor, >> >>> the future transfers the context for us the way it was written. >> >>> >> >>> "It's unclear what fan-in behaviors like zip, merge etc mean in terms >> >>> of what the local values should be?" >> >>> This is a very good question. I wonder what twitter futures do >> here. I >> >>> would be ok with dropping the context in this case or combining it. >> I do >> >>> not really care yet here since I have not run into it but it is a >> very good >> >>> question and would need a lot of thought >> >>> >> >>> Josh, >> >>> I cannot expect all 3rd party libraries that are brought in will be >> >>> using ContextPropagatingExecutor so that solution breaks down as >> Viktor >> >>> eludes to. >> >>> >> >>> Alex, >> >>> tuples do not solve the issue. in fact twitter futures have a >> >>> Local.scala file that does solve the issue. The main issue is 3rd >> party >> >>> code and having the context continue into "unknown code" using >> >>> CompletableFuture. I cannot control that code BUT want every >> log.info in >> >>> that code to use and log the request id. it is awesome at twitter as >> I can >> >>> just follow that request id in the logs. If CompletableFuture had >> such a >> >>> context, I could transfer this info into it and into the 3rd party >> java >> >>> libraries. >> >>> >> >>> I am writing a webserver for fun based on CompletableFutures and >> therefore >> >>> cannot control the controllers as the app developer writes that and >> the >> >>> request id stops getting logged on the request path which is mostly >> >>> .thenApply and .thenCompose. even if the Controllers do you my >> future, >> >>> they will bring in libraries NOT using my future :( >> >>> >> >>> thanks >> >>> Dean >> >>> >> >>> >> >>> >> >>> >> >>> >> >>> On Tue, May 23, 2017 at 3:12 AM, Alex Otenko < >> oleksandr.otenko at gmail.com> >> >>> wrote: >> >>> >> >>>> Why would someone want to rely on state they cannot control? >> >>>> >> >>>> Is the idea to subvert some API that does not provide a way to pass >> >>>> state? This is strange especially in the context of Scala, where you >> can >> >>>> easily form tuples. >> >>>> >> >>>> Alex >> >>>> >> >>>> On 22 May 2017, at 20:44, Martin Buchholz >> wrote: >> >>>> >> >>>> There's not likely to be any support for local context anywhere in >> >>>> java.util.concurrent, but it seems not too hard to roll your own >> support >> >>>> with a custom executor to be used with CompletableFuture that kept >> track of >> >>>> any local context. >> >>>> >> >>>> On Fri, May 19, 2017 at 1:16 PM, Pavel Rappo > > >> >>>> wrote: >> >>>> >> >>>>> General questions on concurrency in Java should be asked here: >> >>>>> >> >>>>> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest >> >>>>> >> >>>>>> On 18 May 2017, at 21:57, Dean Hiller wrote: >> >>>>>> >> >>>>>> Way more detail here... >> >>>>>> >> >>>>>> http://stackoverflow.com/questions/37933713/does-completable >> >>>>> future-have-a-corresponding-local-context >> >>>>>> >> >>>>>> So I was wondering if this was going to be added at some point to >> the >> >>>>> jdk >> >>>>>> as I could not figure out how to set something so it was still >> >>>>> available on >> >>>>>> the thread at a later time when traversing async thenCompose, >> >>>>> thenAccept. >> >>>>>> >> >>>>>> thanks, >> >>>>>> Dean >> >>>>> >> >>>>> >> >>>> _______________________________________________ >> >>>> Concurrency-interest mailing list >> >>>> Concurrency-interest at cs.oswego.edu >> >>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest >> >>>> >> >>>> >> >>>> >> >>> >> >> >> > >> > >> > >> >> >> > > From dhiller at twitter.com Thu Mar 22 18:43:30 2018 From: dhiller at twitter.com (Dean Hiller) Date: Thu, 22 Mar 2018 12:43:30 -0600 Subject: revisiting MDC in slf4j broken because of CompletableFuture In-Reply-To: <74981FE3-4D87-4DE3-B98E-FB5FB3A6177C@dslextreme.com> References: <85B3F22F-A5B5-42C5-AC91-7D64CF1151AF@dslextreme.com> <6B4E025A-8CF3-4DAA-A265-518D2C67EA8B@dslextreme.com> <74981FE3-4D87-4DE3-B98E-FB5FB3A6177C@dslextreme.com> Message-ID: sure, I 100% agree. ("it should be general enough that it can be used for more than just CompleteableFuture"). yes, I could see someone doing a executorService.run() and it transferring that context as well....that would be kind of really nice actually!!! and you do have to swap out the logback MDC impl with your own(we did at twitter), and then it works like a charm. ie. we only need jdk work since logback let's you swap the MDC. Dean On Thu, Mar 22, 2018 at 12:38 PM, Ralph Goers wrote: > To be clear, SLF4J only provides an MDC API and doesn?t implement the MDC. > It delegates that to an implementation - Log4j 2 or Logback. Obviously, my > concern would be to get Log4j 2 to work the way it needs to. If it requires > additional help from the JDK library then there is only so much I can do. > But if work is being asked of the JDK then, IMO, it should be general > enough that it can be used for more than just CompleteableFuture. > > Ralph > > > On Mar 22, 2018, at 11:32 AM, Dean Hiller wrote: > > oh, I see > > yes, that code could be done in CompletableFuture though...Executor does > not have to be touched based on the scala code I read. ie. you create a > new Runnable that reads the last Local context transferring into a > ThreadLocal until the next transfer is needed(at each > .thenApply/.thenCompose boundaries). > > There are weird methods and I would just not worry about those except as > it relates mostly to getting slf4j's MDC to work. > > On Thu, Mar 22, 2018 at 12:27 PM, Ralph Goers > wrote: > >> My point is that I don?t think this is the only place the problem occurs. >> I have seen similar questions on the Log4j mailing list where users want to >> be able to do this for thread pools they create via Executors and don?t >> want to have to do the ThreadLocal propagation themselves. If a >> CompleteableFuture uses an Executor under the covers then it could leverage >> the same solution. >> >> Ralph >> >> >> On Mar 22, 2018, at 11:21 AM, Dean Hiller wrote: >> >> I am basically asking for someone to copy the solution in twitter >> Future.scala(which uses Local.scala) into CompletableFuture.java, yes. >> >> ie. I should be able to say Local.set("something", value) and in >> CompletableFuture when .map is called, it will ensure the key/values are >> transferred across threads. Local.scala internally uses a ThreadLocal up >> into the point of .map/.flatMap (ie. thenApply/.thenCompose). At that >> point, it transfers it across threads into a new ThreadLocal. >> >> ie. the answer on how to do it exists here(search on Locals and see it in >> the respond method which is called by map and flatMap).. >> >> https://github.com/simonratner/twitter-util/blob/master/ >> util-core/src/main/scala/com/twitter/util/Future.scala >> >> Here is the Local class that clients use and the Future uses to transfer >> contexts across map/flatMap >> https://github.com/simonratner/twitter-util/blob/master/ >> util-core/src/main/scala/com/twitter/util/Local.scala >> >> (I do apologize if you do not read scala code, but the answer is there >> and just in a different language) >> >> later, >> Dean >> >> >> On Thu, Mar 22, 2018 at 11:40 AM, Ralph Goers > > wrote: >> >>> Having read several of the threads I think I have a better understanding >>> of the problem. This sounds similar to problems that occur with any >>> application that has a way of doing asynchronous processing with with >>> thread pools. Java has unfortunately not provided a good way that I know of >>> to pass a ThreadLocal from one thread to a worker thread. I am guessing >>> that is what you are really asking for is some sort of property on the >>> Executor that tells it to pass the ThreadLocals from one thread to the >>> worker that performs action on its behalf. >>> >>> Ralph >>> >>> > On Mar 22, 2018, at 10:13 AM, Ralph Goers >>> wrote: >>> > >>> > Log4j 2 supports a ThreadContext which is analogous to the SLF4J MDC. >>> Both are based on ThreadLocal variables. If I understand what you are >>> saying, the problem is that ThreadLocals do not work as you you would >>> expect when using CompleteableFutures? >>> > >>> > Ralph >>> > >>> >> On Mar 22, 2018, at 7:05 AM, Dean Hiller wrote: >>> >> >>> >> slf4j is pretty much the defacto logging standard these days allowing >>> one >>> >> to bring in libraries using any logging framework. (commons logging >>> fell >>> >> short and had classloading bugs). >>> >> >>> >> Summary: MDC works fine in twitter scala Futures but not java >>> >> CompletableFutures. >>> >> >>> >> Unfortunately, one of the best features(brought over from log4j which >>> is >>> >> also broken now) is the MDC. The MDC no longer works with >>> >> CompletableFutures so people will have to move to scala where it does >>> work. >>> >> >>> >> Documentation on MDC if you don't know what that is.... >>> >> https://logback.qos.ch/manual/mdc.html >>> >> >>> >> or for a more concrete example, as a developer a request comes in and >>> you >>> >> set MDC.put("requestId", requestId) and now whenever you log, that >>> request >>> >> id is added to your log line. No developer has to 'remember' to add >>> it >>> >> every time he adds a log statement. >>> >> >>> >> This is due to the lack of Local.java file that should exist and >>> transfer >>> >> context over the .thenApply/.thenCompose methods like twitter Futures >>> has >>> >> in scala land. (see Local.scala in twitter Futures and the twitter >>> Future >>> >> code for how this works) >>> >> >>> >> In scala, it works and we have all the same methods as >>> CompletableFuture >>> >> for the most part and yes, we can't transfer the context over some >>> methods, >>> >> but at least our MDC in scala servers is not broken. >>> >> >>> >> Lack of this feature is forcing our hand to code in scala where it is >>> not >>> >> broken. ie. we need logging and we definitely need the request id or >>> >> client id or whatever attached automatically to every log(as humans >>> have >>> >> trouble remembering to add it themselves every single time). >>> >> >>> >> thanks for reconsidering, >>> >> Dean >>> >> >>> >> On Tue, May 23, 2017 at 10:20 AM, Dean Hiller >>> wrote: >>> >> >>> >>> All, this post is all about 3rd party code that I do not control so >>> >>> therefore the solutions above do not work as those libraries may >>> predate my >>> >>> library. more specifically..... >>> >>> >>> >>> Martin, >>> >>> If I roll my own slf4j MDC only works in my code and stops working >>> in >>> >>> 3rd party code! because the 3rd party code does not transfer the >>> context. >>> >>> >>> >>> Viktor, >>> >>> You hit the head on the nail with "It's easy to lose context when >>> >>> intermediate libraries/Executors". This is solved on twitter >>> futures until >>> >>> we hit libraries not using twitter futures because no matter the >>> executor, >>> >>> the future transfers the context for us the way it was written. >>> >>> >>> >>> "It's unclear what fan-in behaviors like zip, merge etc mean in >>> terms >>> >>> of what the local values should be?" >>> >>> This is a very good question. I wonder what twitter futures do >>> here. I >>> >>> would be ok with dropping the context in this case or combining it. >>> I do >>> >>> not really care yet here since I have not run into it but it is a >>> very good >>> >>> question and would need a lot of thought >>> >>> >>> >>> Josh, >>> >>> I cannot expect all 3rd party libraries that are brought in will be >>> >>> using ContextPropagatingExecutor so that solution breaks down as >>> Viktor >>> >>> eludes to. >>> >>> >>> >>> Alex, >>> >>> tuples do not solve the issue. in fact twitter futures have a >>> >>> Local.scala file that does solve the issue. The main issue is 3rd >>> party >>> >>> code and having the context continue into "unknown code" using >>> >>> CompletableFuture. I cannot control that code BUT want every >>> log.info in >>> >>> that code to use and log the request id. it is awesome at twitter >>> as I can >>> >>> just follow that request id in the logs. If CompletableFuture had >>> such a >>> >>> context, I could transfer this info into it and into the 3rd party >>> java >>> >>> libraries. >>> >>> >>> >>> I am writing a webserver for fun based on CompletableFutures and >>> therefore >>> >>> cannot control the controllers as the app developer writes that and >>> the >>> >>> request id stops getting logged on the request path which is mostly >>> >>> .thenApply and .thenCompose. even if the Controllers do you my >>> future, >>> >>> they will bring in libraries NOT using my future :( >>> >>> >>> >>> thanks >>> >>> Dean >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> On Tue, May 23, 2017 at 3:12 AM, Alex Otenko < >>> oleksandr.otenko at gmail.com> >>> >>> wrote: >>> >>> >>> >>>> Why would someone want to rely on state they cannot control? >>> >>>> >>> >>>> Is the idea to subvert some API that does not provide a way to pass >>> >>>> state? This is strange especially in the context of Scala, where >>> you can >>> >>>> easily form tuples. >>> >>>> >>> >>>> Alex >>> >>>> >>> >>>> On 22 May 2017, at 20:44, Martin Buchholz >>> wrote: >>> >>>> >>> >>>> There's not likely to be any support for local context anywhere in >>> >>>> java.util.concurrent, but it seems not too hard to roll your own >>> support >>> >>>> with a custom executor to be used with CompletableFuture that kept >>> track of >>> >>>> any local context. >>> >>>> >>> >>>> On Fri, May 19, 2017 at 1:16 PM, Pavel Rappo < >>> pavel.rappo at oracle.com> >>> >>>> wrote: >>> >>>> >>> >>>>> General questions on concurrency in Java should be asked here: >>> >>>>> >>> >>>>> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest >>> >>>>> >>> >>>>>> On 18 May 2017, at 21:57, Dean Hiller >>> wrote: >>> >>>>>> >>> >>>>>> Way more detail here... >>> >>>>>> >>> >>>>>> http://stackoverflow.com/questions/37933713/does-completable >>> >>>>> future-have-a-corresponding-local-context >>> >>>>>> >>> >>>>>> So I was wondering if this was going to be added at some point to >>> the >>> >>>>> jdk >>> >>>>>> as I could not figure out how to set something so it was still >>> >>>>> available on >>> >>>>>> the thread at a later time when traversing async thenCompose, >>> >>>>> thenAccept. >>> >>>>>> >>> >>>>>> thanks, >>> >>>>>> Dean >>> >>>>> >>> >>>>> >>> >>>> _______________________________________________ >>> >>>> Concurrency-interest mailing list >>> >>>> Concurrency-interest at cs.oswego.edu >>> >>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest >>> >>>> >>> >>>> >>> >>>> >>> >>> >>> >> >>> > >>> > >>> > >>> >>> >>> >> >> > > From lance.andersen at oracle.com Fri Mar 23 16:57:46 2018 From: lance.andersen at oracle.com (Lance Andersen) Date: Fri, 23 Mar 2018 12:57:46 -0400 Subject: RFR 8197595: Serialization javadoc should link to security best practices In-Reply-To: <203836fb-abd6-1191-9499-b96e6a29ad3d@Oracle.com> References: <203836fb-abd6-1191-9499-b96e6a29ad3d@Oracle.com> Message-ID: Looks good to me also Roger with Sean?s suggestions :-) > On Mar 23, 2018, at 10:12 AM, Roger Riggs wrote: > > Please review adding a warning and a link to the Secure Coding Guidelines > and the new Serial Filter guide[2] included in the JDK 10 docs. > The warnings are added to Serializable, ObjectInputStream, ObjectInputFilter and > the java.io package summary. > > webrev: > http://cr.openjdk.java.net/~rriggs/webrev-serialwarn-8197595/index.html > > javadoc: > http://cr.openjdk.java.net/~rriggs/serialwarn/api/java.base/java/io/package-summary.html > > Thanks, Roger > > [2] https://docs.oracle.com/javase/10/core/serialization-filtering1.htm#JSCOR-GUID-3ECB288D-E5BD-4412-892F-E9BB11D4C98A > > 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 volker.simonis at gmail.com Fri Mar 23 17:24:24 2018 From: volker.simonis at gmail.com (Volker Simonis) Date: Fri, 23 Mar 2018 18:24:24 +0100 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <2329dea1-a75e-bb70-95a6-242a93006c6d@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> <86488d2c-61e3-e489-d9fc-976178c35775@oracle.com> <2329dea1-a75e-bb70-95a6-242a93006c6d@oracle.com> Message-ID: Hi Magnus, thanks for addressing this long standing issue! I haven't looked at the changes, but just want to share some general and historical notes: - Compiling with "-fvisibility=hidden" which hides all symbols expect the ones explicitly exported with "__attribute__((visibility("default")))" has been requested by SAP back in 2007 even before we had OpenJDK (see "Use -fvisibility=hidden for gcc compiles" https://bugs.openjdk.java.net/browse/JDK-6588413) and finally pushed into the OpenJKD around 2010. - "-fvisibility=hidden" gave us performance improvements of about 5% (JBB2005) and 2% (JVM98) on Linux/IA64 and 1,5% (JBB2005) and 0,5% (JVM98) on Linux/PPC64 because the compiler could use faster calls for non exported symbols. This improvement was only very small on x86 tough. - "-fvisibility=hidden"/"__attribute__((visibility("default")))" applies BEFORE using the map files in the linking step (i.e. hidden symbols can't be exported any more even if mentioned in the map file) - because of the performance improvements we got by using "-fvisibility=hidden" it was worth while using it even though we had the mapfiles at the end of the process. Then we had several mail threads (which you probably remember because you were involved :) where we discussed to either remove the map files completely or instead generate them automatically during the build: http://mail.openjdk.java.net/pipermail/hotspot-dev/2014-February/thread.html#12412 http://mail.openjdk.java.net/pipermail/hotspot-dev/2014-February/thread.html#12628 The main arguments against removing the map files at that time were: 1. the danger to re-export all symbols of statically linked libraries (notably libstdc++ at that time) 2. loosing exports of compiler generated symbols like vtables which are required by the Serviceability Agent Point 1 is not a problem today, because I don't think we do any static linking any more. If we still do it under some circumstances, this problem should be re-evaluated. Point 2 is only relevant for HotSpot. But because of "8034065: GCC 4.3 and later doesn't export vtable symbols any more which seem to be needed by SA" (https://bugs.openjdk.java.net/browse/JDK-8034065), exporting such symbols trough a map files doesn't work any more anyway. So this isn't a problem either. So to cut a long story short - I think the time is ripe to get rid of the map files. Thumbs up from me (meant as moral support, not as a concrete review :) Regards, Volker On Fri, Mar 23, 2018 at 5:05 PM, mandy chung wrote: > This is a very good change and no more mapfile to maintain!! > > Please do file JBS issues for the component teams to clean up their exports. > > Mandy > > > On 3/23/18 7:30 AM, Erik Joelsson wrote: >> >> I have looked at the build changes and they look good. >> >> Will you file followups for each component team to look over their >> exported symbols, at least for the libraries with $(EXPORT_ALL_SYMBOLS)? It >> sure looks like there is some technical debt laying around here. >> >> /Erik >> >> >> On 2018-03-23 06:56, Magnus Ihse Bursie wrote: >>> >>> With modern compilers, we can use compiler directives (such as >>> _attribute__((visibility("default"))), or __declspec(dllexport)) to control >>> symbol visibility, directly in the source code. This has historically not >>> been present on all compilers, so we had to resort to using mapfiles (also >>> known as linker scripts). >>> >>> This is no longer the case. Now all compilers we use support symbol >>> visibility directives, in one form or another. We should start using this. >>> Since this has been the only way to control symbol visibility on Windows, >>> for most of the shared code, we already have proper JNIEXPORT decorations in >>> place. >>> >>> If we fix the remaining platform-specific files to have proper JNIEXPORT >>> tagging, then we can finally get rid of mapfiles. >>> >>> This fix removed mapfiles for all JDK libraries. It does not touch >>> hotspot libraries nor JDK executables; they will have to wait for a future >>> fix -- this was complex enough. This change will not have any impact on >>> macosx, since we do not use mapfiles there, but instead export all symbols. >>> (This is not a good idea, but I'll address that separately.) This change >>> will also have a minimal impact on Windows. The only reason Windows is >>> impacted at all, is that some changes needed by Solaris and Linux were >>> simpler to fix for all platforms. >>> >>> I have strived for this change to have no impact on the actual generated >>> code. Unfortunately, this was not possible to fully achieve. I do not >>> believe that these changes will have any actual impact on the product, >>> though. I will present the differences more in detail further down. Those >>> who are not interested can probably skip that. >>> >>> The patch has passed tier1 testing and is currently running tier2 and >>> tier3. Since the running code is more or less (see caveat below) unmodified, >>> I don't expect any testing issues. >>> >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8200178 >>> WebRev: >>> http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01 >>> >>> Details on changes: >>> Most of the source code changes are (unsurprisingly) in java.base and >>> java.desktop. Remaining changes are in jdk.crypto.ucrypto, >>> jdk.hotspot.agent, jdk.jdi and jdk.jdwp.agent. >>> >>> Source code changes does almost to 100% consists in decorating an >>> exported function with JNIEXPORT. I have also followed the long-standing >>> convention of adding JNICALL. This is a no-op on non-Windows platforms, so >>> for most of the changes this is purely cosmetic (and possibly adding in >>> robustness, should the function ever be used on Windows in the future). I >>> have also followed the stylistic convention of putting "JNIEXPORT >> type> JNICALL" on a separate line. For some functions, however, this might >>> cause a change in calling convention on Windows. Since this can not apply to >>> exported functions on Windows (otherwise they would already have had >>> JNIEXPORT), I do not think this matters anything. >>> >>> A few libraries did not have a mapfile, on Linux and/or Solaris. This >>> actually meant that all symbols were exported. It is highly unclear if this >>> was known and intended by the original make rule writer. I have emulated >>> this by adding the flag $(EXPORT_ALL_SYMBOLS) to these libraries. Hopefully, >>> we can remove this flag and fix proper exported symbols in the future. >>> >>> I have run the complete build using COMPARE_BUILD, and made a thourough >>> analysis of the differences for Linux and Solaris. All native libraries have >>> symbol differences, but most of them are trivial and/or harmless. As a >>> result, most libraries have disasm differences as well, but these too seem >>> trivial and harmless. The differences in symbols that are common to all >>> libraries include: >>> * Internal symbols such as __bss_start, _edata, _end and _fini are now >>> global. (They are imported as such from the compiler libraries/archives, and >>> we have no linker script to override this behavior). >>> * The versioning tag SUNWprivate_1.1 is not included, and thus neither >>> the .gnu.version_d symbol. >>> * There are a few differences in the symbol and/or mangling of some >>> local functions. I'm not sure what's causing this, >>> but it's unlikely to have any effect on the product. >>> >>> Another common source for change in symbols is due to previous platform >>> differences. For instance, if we had "JNIEXPORT int JNICALL do_foo() { ... >>> }", but do_foo was not in the mapfile, the symbol was exported on Windows >>> but not on Linux and Solaris. (Presumable since it was not needed there, >>> even though it was compiled for those platforms as well.) Now, with the >>> mapfiles gone, do_foo() will be exported on all platforms. And contrary, >>> functions that are compiled on all platforms, and were exported in mapfiles, >>> but now have gotten an JNIEXPORT decoration, will now be visible even on >>> Windows. (This accounts for half of the noticed symbol differences on >>> Windows.) I could have made the JNIEXPORT conditional on OS, but I didn't >>> think the mess in source code were worth the keeping of binary confidence >>> with the old build. >>> >>> A third common source for change in symbols is due to exported functions >>> "leaking" across library borders. For instance, some functions in >>> java.desktop is compiled in both libawt_xawt and libawt_headless, but they >>> were previously only included in the mapfile for one of these libraries. >>> Now, since the visibility is determined by the source code itself, it gets >>> exported in both libraries. A variant of this is when a library depends on >>> another JDK library, and includes the header file from that other library, >>> which in turn declares a function as JNIEXPORT. This will cause the >>> including library to also export the function. This accounts for the other >>> half of the changes on Windows. A typical example of this is that multiple >>> libraries now re-export hotspot symbols from libjvm.so, like jio_fprintf. (I >>> have not listed the libjvm re-exports below.) >>> >>> Note that Java_java_io_FileOutputStream_close0 in >>> java.base/unix/native/libjava/FileOutputStream_md.c is no longer exported, >>> and can probably be removed. >>> >>> Here is a detailed table showing and accounting for all the remaining >>> differences found on Linux and Solaris: >>> java.base/unix/native/libjava: Java_java_io_FileOutputStream_close0 is >>> now also exported on unix platforms due to JNIEXPORT. >>> >>> java.base/jspawnlauncher: On solaris, we also include >>> libjava/childproc.o, which >>> now exports less functions than it used to (it used to export all >>> functions, now it is compiled with visibility=hidden). >>> >>> java.base/java(w).exe: Is now also exporting the following symbols due to >>> added JNIEXPORT in libjli on Windows: >>> (Yes, executables can export symbols on Windows. Confusing, I know.) >>> JLI_AddArgsFromEnvVar >>> JLI_CmdToArgs >>> JLI_GetAppArgIndex >>> JLI_GetStdArgc >>> JLI_GetStdArgs >>> JLI_InitArgProcessing >>> JLI_Launch >>> JLI_List_add >>> JLI_List_new >>> JLI_ManifestIterate >>> JLI_MemAlloc >>> JLI_MemFree >>> JLI_PreprocessArg >>> JLI_ReportErrorMessage >>> JLI_ReportErrorMessageSys >>> JLI_ReportExceptionDescription >>> JLI_ReportMessage >>> JLI_SetTraceLauncher >>> JLI_StringDup >>> >>> java.desktop:/libawt_xawt: The following symbols are now also exported on >>> linux and solaris due to JNIEXPORT: >>> awt_DrawingSurface_FreeDrawingSurfaceInfo >>> awt_DrawingSurface_GetDrawingSurfaceInfo >>> awt_DrawingSurface_Lock >>> awt_DrawingSurface_Unlock >>> awt_GetColor >>> >>> The following symbols are now also exported on linux and solaris due to >>> JNIEXPORT (they were previously >>> exported only in libawt): >>> Java_sun_awt_DebugSettings_setCTracingOn__Z >>> Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2 >>> Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2I >>> Java_sun_awt_X11GraphicsConfig_getNumColors >>> >>> java.desktop:/libawt_headless: The following symbols are now also >>> exported due to JNIEXPORT (they were previously >>> exported only in libawt_xawt and/or libawt): >>> Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo >>> Java_sun_java2d_opengl_GLXGraphicsConfig_getOGLCapabilities >>> Java_sun_java2d_x11_X11PMBlitLoops_updateBitmask >>> Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable >>> X11SurfaceData_GetOps >>> >>> java.desktop/libawt: The following symbols are now also exported on >>> Windows, due to added >>> JNIEXPORT: >>> SurfaceData_InitOps >>> mul8table >>> div8table >>> doDrawPath >>> doFillPath >>> g_CMpDataID >>> initInverseGrayLut >>> make_dither_arrays >>> make_uns_ordered_dither_array >>> path2DFloatCoordsID >>> path2DNumTypesID >>> path2DTypesID >>> path2DWindingRuleID >>> sg2dStrokeHintID >>> std_img_oda_blue >>> std_img_oda_green >>> std_img_oda_red >>> std_odas_computed >>> sunHints_INTVAL_STROKE_PURE >>> >>> java.desktop/libawt on solaris: >>> A number of "#pragma weak" directives was previously overridden by the >>> mapfile. >>> Now these directives are respected, so these symbols are now weak instead >>> of local: >>> ByteGrayToIntArgbPreConvert_F >>> ByteGrayToIntArgbPreScaleConvert_F >>> IntArgbBmToFourByteAbgrPreScaleXparOver_F >>> IntArgbToIntRgbXorBlit_F >>> IntBgrToIntBgrAlphaMaskBlit_F >>> >>> java.desktop/libawt on solaris: These are now also exported due to >>> JNIEXPORT in libmlib_image. >>> j2d_mlib_ImageCreate >>> j2d_mlib_ImageCreateStruct >>> j2d_mlib_ImageDelete >>> >>> java.desktop/libawt on solaris: This is now also exported due to >>> JNIEXPORT: >>> GrPrim_CompGetXorColor >>> SurfaceData_GetOpsNoSetup >>> SurfaceData_IntersectBoundsXYWH >>> SurfaceData_SetOps >>> Transform_GetInfo >>> Transform_transform >>> >>> java.desktop/libsplashscreen: JNI_OnLoad is now exported on linux and >>> solaris due to JNIEXPORT. >>> libspashscreen also had JNIEXPORT (actually a pure _declspec(dllexport)) >>> but no JNICALL, which I added as >>> a part of converting to JNIEXPORT. The same goes for libmlib_image . >>> >>> jdk.sctp/libsctp: handleSocketError is now exported on linux and solaris >>> due to JNIEXPORT in libnio. >>> >>> java.instrument:/libinstrument: Agent_OnUnload is now also exported on >>> linux and solaris platforms due to JNIEXPORT. >>> JLI_ManifestIterate is now also exported on Windows, due to added >>> JNIEXPORT in libjli. >>> >>> jdk.management/libmanagement_ext: >>> Java_com_sun_management_internal_Flag_setDoubleValue is now also exported on >>> linux and solaris platforms due to JNIEXPORT. >>> >>> /Magnus >>> >>> >> > From philip.race at oracle.com Fri Mar 23 17:33:55 2018 From: philip.race at oracle.com (Phil Race) Date: Fri, 23 Mar 2018 10:33:55 -0700 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> Message-ID: <359e997c-6f49-218b-a1e6-81888135242b@oracle.com> There are a lot of changes in the desktop libraries. Doing mach5 tier1/2/3 testing is not nearly sufficient to cover those since only tier3 has any UI tests and it barely uses anything that's touched here. So since testing seems to be wise, then I think you should do a jtreg desktop group run on Linux & Windows. You can probably skip Mac since it is unaffected and I think Linux will cover Solaris here. You should also do some headless testing. It could take some time to review this properly and decide what changes are OK, what changes are something we should clean up later, and what changes are something that ought to be addressed now .. I think I'd be mainly concerned that something fails due to a missing symbol, or that for newly exported symbols if we ended up with duplicate symbols as a result. The results of a test run will add confidence here. BTW I don't think you are right that java.desktop:/libawt_headless: The following symbols are now also exported due to JNIEXPORT (they were previously .. X11SurfaceData_GetOps It looks to me like it was previously exported. -phil. On 03/23/2018 06:56 AM, Magnus Ihse Bursie wrote: > With modern compilers, we can use compiler directives (such as > _attribute__((visibility("default"))), or __declspec(dllexport)) to > control symbol visibility, directly in the source code. This has > historically not been present on all compilers, so we had to resort to > using mapfiles (also known as linker scripts). > > This is no longer the case. Now all compilers we use support symbol > visibility directives, in one form or another. We should start using > this. Since this has been the only way to control symbol visibility on > Windows, for most of the shared code, we already have proper JNIEXPORT > decorations in place. > > If we fix the remaining platform-specific files to have proper > JNIEXPORT tagging, then we can finally get rid of mapfiles. > > This fix removed mapfiles for all JDK libraries. It does not touch > hotspot libraries nor JDK executables; they will have to wait for a > future fix -- this was complex enough. This change will not have any > impact on macosx, since we do not use mapfiles there, but instead > export all symbols. (This is not a good idea, but I'll address that > separately.) This change will also have a minimal impact on Windows. > The only reason Windows is impacted at all, is that some changes > needed by Solaris and Linux were simpler to fix for all platforms. > > I have strived for this change to have no impact on the actual > generated code. Unfortunately, this was not possible to fully achieve. > I do not believe that these changes will have any actual impact on the > product, though. I will present the differences more in detail further > down. Those who are not interested can probably skip that. > > The patch has passed tier1 testing and is currently running tier2 and > tier3. Since the running code is more or less (see caveat below) > unmodified, I don't expect any testing issues. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8200178 > WebRev: > http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01 > > Details on changes: > Most of the source code changes are (unsurprisingly) in java.base and > java.desktop. Remaining changes are in jdk.crypto.ucrypto, > jdk.hotspot.agent, jdk.jdi and jdk.jdwp.agent. > > Source code changes does almost to 100% consists in decorating an > exported function with JNIEXPORT. I have also followed the > long-standing convention of adding JNICALL. This is a no-op on > non-Windows platforms, so for most of the changes this is purely > cosmetic (and possibly adding in robustness, should the function ever > be used on Windows in the future). I have also followed the stylistic > convention of putting "JNIEXPORT JNICALL" on a separate > line. For some functions, however, this might cause a change in > calling convention on Windows. Since this can not apply to exported > functions on Windows (otherwise they would already have had > JNIEXPORT), I do not think this matters anything. > > A few libraries did not have a mapfile, on Linux and/or Solaris. This > actually meant that all symbols were exported. It is highly unclear if > this was known and intended by the original make rule writer. I have > emulated this by adding the flag $(EXPORT_ALL_SYMBOLS) to these > libraries. Hopefully, we can remove this flag and fix proper exported > symbols in the future. > > I have run the complete build using COMPARE_BUILD, and made a > thourough analysis of the differences for Linux and Solaris. All > native libraries have symbol differences, but most of them are trivial > and/or harmless. As a result, most libraries have disasm differences > as well, but these too seem trivial and harmless. The differences in > symbols that are common to all libraries include: > * Internal symbols such as __bss_start, _edata, _end and _fini are > now global. (They are imported as such from the compiler > libraries/archives, and we have no linker script to override this > behavior). > * The versioning tag SUNWprivate_1.1 is not included, and thus > neither the .gnu.version_d symbol. > * There are a few differences in the symbol and/or mangling of some > local functions. I'm not sure what's causing this, > but it's unlikely to have any effect on the product. > > Another common source for change in symbols is due to previous > platform differences. For instance, if we had "JNIEXPORT int JNICALL > do_foo() { ... }", but do_foo was not in the mapfile, the symbol was > exported on Windows but not on Linux and Solaris. (Presumable since it > was not needed there, even though it was compiled for those platforms > as well.) Now, with the mapfiles gone, do_foo() will be exported on > all platforms. And contrary, functions that are compiled on all > platforms, and were exported in mapfiles, but now have gotten an > JNIEXPORT decoration, will now be visible even on Windows. (This > accounts for half of the noticed symbol differences on Windows.) I > could have made the JNIEXPORT conditional on OS, but I didn't think > the mess in source code were worth the keeping of binary confidence > with the old build. > > A third common source for change in symbols is due to exported > functions "leaking" across library borders. For instance, some > functions in java.desktop is compiled in both libawt_xawt and > libawt_headless, but they were previously only included in the mapfile > for one of these libraries. Now, since the visibility is determined by > the source code itself, it gets exported in both libraries. A variant > of this is when a library depends on another JDK library, and includes > the header file from that other library, which in turn declares a > function as JNIEXPORT. This will cause the including library to also > export the function. This accounts for the other half of the changes > on Windows. A typical example of this is that multiple libraries now > re-export hotspot symbols from libjvm.so, like jio_fprintf. (I have > not listed the libjvm re-exports below.) > > Note that Java_java_io_FileOutputStream_close0 in > java.base/unix/native/libjava/FileOutputStream_md.c is no longer > exported, > and can probably be removed. > > Here is a detailed table showing and accounting for all the remaining > differences found on Linux and Solaris: > java.base/unix/native/libjava: Java_java_io_FileOutputStream_close0 is > now also exported on unix platforms due to JNIEXPORT. > > java.base/jspawnlauncher: On solaris, we also include > libjava/childproc.o, which > now exports less functions than it used to (it used to export all > functions, now it is compiled with visibility=hidden). > > java.base/java(w).exe: Is now also exporting the following symbols due > to added JNIEXPORT in libjli on Windows: > (Yes, executables can export symbols on Windows. Confusing, I know.) > JLI_AddArgsFromEnvVar > JLI_CmdToArgs > JLI_GetAppArgIndex > JLI_GetStdArgc > JLI_GetStdArgs > JLI_InitArgProcessing > JLI_Launch > JLI_List_add > JLI_List_new > JLI_ManifestIterate > JLI_MemAlloc > JLI_MemFree > JLI_PreprocessArg > JLI_ReportErrorMessage > JLI_ReportErrorMessageSys > JLI_ReportExceptionDescription > JLI_ReportMessage > JLI_SetTraceLauncher > JLI_StringDup > > java.desktop:/libawt_xawt: The following symbols are now also exported > on linux and solaris due to JNIEXPORT: > awt_DrawingSurface_FreeDrawingSurfaceInfo > awt_DrawingSurface_GetDrawingSurfaceInfo > awt_DrawingSurface_Lock > awt_DrawingSurface_Unlock > awt_GetColor > > The following symbols are now also exported on linux and solaris due > to JNIEXPORT (they were previously > exported only in libawt): > Java_sun_awt_DebugSettings_setCTracingOn__Z > Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2 > Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2I > Java_sun_awt_X11GraphicsConfig_getNumColors > > java.desktop:/libawt_headless: The following symbols are now also > exported due to JNIEXPORT (they were previously > exported only in libawt_xawt and/or libawt): > Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo > Java_sun_java2d_opengl_GLXGraphicsConfig_getOGLCapabilities > Java_sun_java2d_x11_X11PMBlitLoops_updateBitmask > Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable > X11SurfaceData_GetOps > > java.desktop/libawt: The following symbols are now also exported on > Windows, due to added > JNIEXPORT: > SurfaceData_InitOps > mul8table > div8table > doDrawPath > doFillPath > g_CMpDataID > initInverseGrayLut > make_dither_arrays > make_uns_ordered_dither_array > path2DFloatCoordsID > path2DNumTypesID > path2DTypesID > path2DWindingRuleID > sg2dStrokeHintID > std_img_oda_blue > std_img_oda_green > std_img_oda_red > std_odas_computed > sunHints_INTVAL_STROKE_PURE > > java.desktop/libawt on solaris: > A number of "#pragma weak" directives was previously overridden by the > mapfile. > Now these directives are respected, so these symbols are now weak > instead of local: > ByteGrayToIntArgbPreConvert_F > ByteGrayToIntArgbPreScaleConvert_F > IntArgbBmToFourByteAbgrPreScaleXparOver_F > IntArgbToIntRgbXorBlit_F > IntBgrToIntBgrAlphaMaskBlit_F > > java.desktop/libawt on solaris: These are now also exported due to > JNIEXPORT in libmlib_image. > j2d_mlib_ImageCreate > j2d_mlib_ImageCreateStruct > j2d_mlib_ImageDelete > > java.desktop/libawt on solaris: This is now also exported due to > JNIEXPORT: > GrPrim_CompGetXorColor > SurfaceData_GetOpsNoSetup > SurfaceData_IntersectBoundsXYWH > SurfaceData_SetOps > Transform_GetInfo > Transform_transform > > java.desktop/libsplashscreen: JNI_OnLoad is now exported on linux and > solaris due to JNIEXPORT. > libspashscreen also had JNIEXPORT (actually a pure > _declspec(dllexport)) but no JNICALL, which I added as > a part of converting to JNIEXPORT. The same goes for libmlib_image . > > jdk.sctp/libsctp: handleSocketError is now exported on linux and > solaris due to JNIEXPORT in libnio. > > java.instrument:/libinstrument: Agent_OnUnload is now also exported on > linux and solaris platforms due to JNIEXPORT. > JLI_ManifestIterate is now also exported on Windows, due to added > JNIEXPORT in libjli. > > jdk.management/libmanagement_ext: > Java_com_sun_management_internal_Flag_setDoubleValue is now also > exported on linux and solaris platforms due to JNIEXPORT. > > /Magnus > > From Roger.Riggs at Oracle.com Fri Mar 23 17:49:14 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Fri, 23 Mar 2018 13:49:14 -0400 Subject: RFR (JDK11/doc-only) 8199176: Accessibility issues in java.base docs In-Reply-To: References: <5AB2ADB9.8080909@oracle.com> <551fd76a-bd69-3186-865f-b38ade2a5ba6@oracle.com> <37c2ae02-38da-a8e4-9efe-3b7d817fcb87@oracle.com> Message-ID: Hi Joe, Looks fine. (I would be in favor of a future solution that correctly generated/fixed up the appropriate headers; Manual editing and corrections are an unnecessary overhead.) Thanks, Roger On 3/21/2018 6:47 PM, Joe Wang wrote: > They look ok. They actually go better with the package name when they > are just 1 level down instead of 2, that is,

rather than

for > the titles when the package name is

. If we don't want the strong > emphasis on the titles, we could lower the package name generated by > javadoc to

instead of

. Then we could keep the

s. > > Most of the package-info pages have already used

for titles, > which is why we're fixing only a handful of them here. Consider: > > *Currently using

:* > https://docs.oracle.com/javase/10/docs/api//java/io/package-summary.html > https://docs.oracle.com/javase/10/docs/api//java/lang/invoke/package-summary.html > > > In the later page, it actually started with

: > ?

Summary of relevant Java Virtual Machine > changes

> > *Currently using

:* > https://docs.oracle.com/javase/10/docs/api//javax/xml/transform/package-summary.html > > > -Joe > > > On 3/21/2018 2:39 PM, Jonathan Gibbons wrote: >> >> >> On 3/21/18 2:28 PM, Alan Bateman wrote: >>> On 21/03/2018 19:08, Joe Wang wrote: >>>> : >>>> >>>> *Item 3*: Heading leavels should only increase by one >>>> ??? This is due to the javadoc tool generates a header with an >>>> addition of headings, in this particular case,

. The fix for >>>> this particular case is to replace the

s with

. >>> I assume this has the effect of increasing the size of the headings. >>> Does it look okay? I assume many of these usages of h3 choose that >>> to avoid heading in very large font. >>> >>> -Alan >> >> I know accessibility fixes are important, but usability is important >> too.? The uses of h3 were previously consistent across different pages. >> >> We could remediate the problem either by figuring a design that has >> javadoc put a similar set of headers on every page (thus rendering >> this changeset unnecessary) or else changing the stylesheet so that >>

on a package-summary page looks the same as

on a class page >> (which sounds icky, even as I type it.) >> >> -- Jon >> > From xueming.shen at oracle.com Fri Mar 23 17:51:17 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 23 Mar 2018 10:51:17 -0700 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> Message-ID: <5AB53E95.9080308@oracle.com> Hi David, Sorry for the late response. I will sponsor this change. Will prepare for the CSR for the new APIs. Couple more comments (1) Deflater.java/deflate(ByteBuffer, int); "In the case of FULL_FLUSH or SYNC_FLUSH ..." It's a copy/paste from the corresponding part in deflate(byte[], int, int, int). The existing one might not be clear. What it meant to say is "if the returned value is equal to the space available in the output buffer passed in ...then you need to call it with more sapce, greater than 6 bytes ...". So the {@code len} need to updated to something like {@code output.remainint()}. (2) Inflater.java/setDictionary(ByteBuffer); "Sets the preset dictionary to the given array of bytes" --> bytes in the specified byte buffer? (3) Infalter.java.inflater(...) It appears there is opportunity to "consolidate" some of the repetitive code block, for example the "catch (DFE e) { ...} the only difference is the "inputPos/input.position()" line. Maybe we can move the try/catch out a "level" and consolidate this catch block. Sure it's a style preference. We can deal with it later. Thanks, Sherman On 03/23/2018 08:18 AM, David Lloyd wrote: > Are there any further comments on this? If not, would it be possible > to get a sponsor for this change? > > Sorry again for the detached email threads; I've learned my GMail lesson well... > > Thanks. > > On Fri, Mar 16, 2018 at 8:25 AM, David Lloyd wrote: >> Sorry, that was an error on my part, caused by too much context >> switching. I've posted an update at >> https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v13 which is >> also attached. >> >> On Wed, Mar 14, 2018 at 8:53 PM, Xueming Shen wrote: >>> Hi David, >>> >>> https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v12 >>> >>> Should we start to review the changes included in above link, or we should >>> wait ? It appears >>> the API is being updated but some implementation have not been updated to >>> follow the spec >>> yet, especially the piece that deals with the output buffer/byteWritten when >>> DataFormatException >>> is raised, for example >>> >>> (1) the "outputConsumedID" is defined but never used to update the >>> corresponding java field >>> in Inflater.c and >>> >>> (2) the "outputConsumed" is used to update the output ByteBuffer when DFE >>> raised (in Java), but >>> the corresponding "byteWritten" is not being updated before the >>> exception is thrown. >>> >>> -Sherman >>> >>> >>> >>> >>> On 3/13/18, 10:46 AM, David Lloyd wrote: >>>> Sorry all, it looks like GMail doesn't know how to keep replies with >>>> the thread when you change the subject line. The follow-up to this >>>> thread is >>>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-March/051960.html >>>> with only a few small changes as discussed above. >>>> >>>> On Fri, Mar 2, 2018 at 2:36 PM, David Lloyd >>>> wrote: >>>>> On Fri, Mar 2, 2018 at 2:34 PM, David Lloyd >>>>> wrote: >>>>>> On Fri, Mar 2, 2018 at 12:49 PM, Xueming Shen >>>>>> wrote: >>>>>>> Hi David, >>>>>>> >>>>>>> (1) Deflater.deflate(Bytebuffer) >>>>>>> the api doc regarding "no_flush" appears to be the copy/paste of >>>>>>> the >>>>>>> byte[] version >>>>>>> without being updated to the corresponding ByteBuffer? >>>>>> You're right, I missed that one. I've incorporated this fix locally: >>>>> Oops, this should have been: >>>>> >>>>> --- 8< --- cut here --- 8< --- >>>>> >>>>> diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java >>>>> b/src/java.base/share/classes/java/util/zip/Deflater.java >>>>> index 524125787a8..40f0d9736e2 100644 >>>>> --- a/src/java.base/share/classes/java/util/zip/Deflater.java >>>>> +++ b/src/java.base/share/classes/java/util/zip/Deflater.java >>>>> @@ -481,9 +481,9 @@ public class Deflater { >>>>> * in order to determine if more input data is required. >>>>> * >>>>> *

This method uses {@link #NO_FLUSH} as its compression flush >>>>> mode. >>>>> - * An invocation of this method of the form {@code >>>>> deflater.deflate(b)} >>>>> + * An invocation of this method of the form {@code >>>>> deflater.deflate(output)} >>>>> * yields the same result as the invocation of >>>>> - * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. >>>>> + * {@code deflater.deflate(output, Deflater.NO_FLUSH)}. >>>>> * >>>>> * @param output the buffer for the compressed data >>>>> * @return the actual number of bytes of compressed data written to >>>>> the >>>>> >>>>> --- 8< --- cut here --- 8< --- >>>>> >>>>> -- >>>>> - DML >>>> >>>> >> >> >> -- >> - DML > > From philip.race at oracle.com Fri Mar 23 18:01:34 2018 From: philip.race at oracle.com (Phil Race) Date: Fri, 23 Mar 2018 11:01:34 -0700 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <359e997c-6f49-218b-a1e6-81888135242b@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> <359e997c-6f49-218b-a1e6-81888135242b@oracle.com> Message-ID: <96a6b8d6-d979-9cc9-6d51-7c6f0926bf97@oracle.com> http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01/src/java.desktop/share/native/libmlib_image/mlib_image_proto.h.udiff.html The variable definitions here are now misaligned. ..and added 2d-dev since many of these native changes are in 2d. -phil. On 03/23/2018 10:33 AM, Phil Race wrote: > There are a lot of changes in the desktop libraries. > Doing mach5 tier1/2/3 testing is not nearly sufficient to cover those > since > only tier3 has any UI tests and it barely uses anything that's touched > here. > So since testing seems to be wise, then I think you should do a > jtreg desktop group run on Linux & Windows. > You can probably skip Mac since it is unaffected and I think Linux > will cover Solaris here. > You should also do some headless testing. > > It could take some time to review this properly and decide what > changes are OK, > what changes are something we should clean up later, and what changes > are something > that ought to be addressed now .. > > I think I'd be mainly concerned that something fails due to a missing > symbol, or > that for newly exported symbols if we ended up with duplicate symbols > as a result. > > The results of a test run will add confidence here. > > BTW I don't think you are right that > java.desktop:/libawt_headless: The following symbols are now also > exported due to JNIEXPORT (they were previously > .. > X11SurfaceData_GetOps > > It looks to me like it was previously exported. > > > -phil. > > > > On 03/23/2018 06:56 AM, Magnus Ihse Bursie wrote: >> With modern compilers, we can use compiler directives (such as >> _attribute__((visibility("default"))), or __declspec(dllexport)) to >> control symbol visibility, directly in the source code. This has >> historically not been present on all compilers, so we had to resort >> to using mapfiles (also known as linker scripts). >> >> This is no longer the case. Now all compilers we use support symbol >> visibility directives, in one form or another. We should start using >> this. Since this has been the only way to control symbol visibility >> on Windows, for most of the shared code, we already have proper >> JNIEXPORT decorations in place. >> >> If we fix the remaining platform-specific files to have proper >> JNIEXPORT tagging, then we can finally get rid of mapfiles. >> >> This fix removed mapfiles for all JDK libraries. It does not touch >> hotspot libraries nor JDK executables; they will have to wait for a >> future fix -- this was complex enough. This change will not have any >> impact on macosx, since we do not use mapfiles there, but instead >> export all symbols. (This is not a good idea, but I'll address that >> separately.) This change will also have a minimal impact on Windows. >> The only reason Windows is impacted at all, is that some changes >> needed by Solaris and Linux were simpler to fix for all platforms. >> >> I have strived for this change to have no impact on the actual >> generated code. Unfortunately, this was not possible to fully >> achieve. I do not believe that these changes will have any actual >> impact on the product, though. I will present the differences more in >> detail further down. Those who are not interested can probably skip >> that. >> >> The patch has passed tier1 testing and is currently running tier2 and >> tier3. Since the running code is more or less (see caveat below) >> unmodified, I don't expect any testing issues. >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8200178 >> WebRev: >> http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01 >> >> Details on changes: >> Most of the source code changes are (unsurprisingly) in java.base and >> java.desktop. Remaining changes are in jdk.crypto.ucrypto, >> jdk.hotspot.agent, jdk.jdi and jdk.jdwp.agent. >> >> Source code changes does almost to 100% consists in decorating an >> exported function with JNIEXPORT. I have also followed the >> long-standing convention of adding JNICALL. This is a no-op on >> non-Windows platforms, so for most of the changes this is purely >> cosmetic (and possibly adding in robustness, should the function ever >> be used on Windows in the future). I have also followed the stylistic >> convention of putting "JNIEXPORT JNICALL" on a separate >> line. For some functions, however, this might cause a change in >> calling convention on Windows. Since this can not apply to exported >> functions on Windows (otherwise they would already have had >> JNIEXPORT), I do not think this matters anything. >> >> A few libraries did not have a mapfile, on Linux and/or Solaris. This >> actually meant that all symbols were exported. It is highly unclear >> if this was known and intended by the original make rule writer. I >> have emulated this by adding the flag $(EXPORT_ALL_SYMBOLS) to these >> libraries. Hopefully, we can remove this flag and fix proper exported >> symbols in the future. >> >> I have run the complete build using COMPARE_BUILD, and made a >> thourough analysis of the differences for Linux and Solaris. All >> native libraries have symbol differences, but most of them are >> trivial and/or harmless. As a result, most libraries have disasm >> differences as well, but these too seem trivial and harmless. The >> differences in symbols that are common to all libraries include: >> * Internal symbols such as __bss_start, _edata, _end and _fini are >> now global. (They are imported as such from the compiler >> libraries/archives, and we have no linker script to override this >> behavior). >> * The versioning tag SUNWprivate_1.1 is not included, and thus >> neither the .gnu.version_d symbol. >> * There are a few differences in the symbol and/or mangling of some >> local functions. I'm not sure what's causing this, >> but it's unlikely to have any effect on the product. >> >> Another common source for change in symbols is due to previous >> platform differences. For instance, if we had "JNIEXPORT int JNICALL >> do_foo() { ... }", but do_foo was not in the mapfile, the symbol was >> exported on Windows but not on Linux and Solaris. (Presumable since >> it was not needed there, even though it was compiled for those >> platforms as well.) Now, with the mapfiles gone, do_foo() will be >> exported on all platforms. And contrary, functions that are compiled >> on all platforms, and were exported in mapfiles, but now have gotten >> an JNIEXPORT decoration, will now be visible even on Windows. (This >> accounts for half of the noticed symbol differences on Windows.) I >> could have made the JNIEXPORT conditional on OS, but I didn't think >> the mess in source code were worth the keeping of binary confidence >> with the old build. >> >> A third common source for change in symbols is due to exported >> functions "leaking" across library borders. For instance, some >> functions in java.desktop is compiled in both libawt_xawt and >> libawt_headless, but they were previously only included in the >> mapfile for one of these libraries. Now, since the visibility is >> determined by the source code itself, it gets exported in both >> libraries. A variant of this is when a library depends on another JDK >> library, and includes the header file from that other library, which >> in turn declares a function as JNIEXPORT. This will cause the >> including library to also export the function. This accounts for the >> other half of the changes on Windows. A typical example of this is >> that multiple libraries now re-export hotspot symbols from libjvm.so, >> like jio_fprintf. (I have not listed the libjvm re-exports below.) >> >> Note that Java_java_io_FileOutputStream_close0 in >> java.base/unix/native/libjava/FileOutputStream_md.c is no longer >> exported, >> and can probably be removed. >> >> Here is a detailed table showing and accounting for all the remaining >> differences found on Linux and Solaris: >> java.base/unix/native/libjava: Java_java_io_FileOutputStream_close0 >> is now also exported on unix platforms due to JNIEXPORT. >> >> java.base/jspawnlauncher: On solaris, we also include >> libjava/childproc.o, which >> now exports less functions than it used to (it used to export all >> functions, now it is compiled with visibility=hidden). >> >> java.base/java(w).exe: Is now also exporting the following symbols >> due to added JNIEXPORT in libjli on Windows: >> (Yes, executables can export symbols on Windows. Confusing, I know.) >> JLI_AddArgsFromEnvVar >> JLI_CmdToArgs >> JLI_GetAppArgIndex >> JLI_GetStdArgc >> JLI_GetStdArgs >> JLI_InitArgProcessing >> JLI_Launch >> JLI_List_add >> JLI_List_new >> JLI_ManifestIterate >> JLI_MemAlloc >> JLI_MemFree >> JLI_PreprocessArg >> JLI_ReportErrorMessage >> JLI_ReportErrorMessageSys >> JLI_ReportExceptionDescription >> JLI_ReportMessage >> JLI_SetTraceLauncher >> JLI_StringDup >> >> java.desktop:/libawt_xawt: The following symbols are now also >> exported on linux and solaris due to JNIEXPORT: >> awt_DrawingSurface_FreeDrawingSurfaceInfo >> awt_DrawingSurface_GetDrawingSurfaceInfo >> awt_DrawingSurface_Lock >> awt_DrawingSurface_Unlock >> awt_GetColor >> >> The following symbols are now also exported on linux and solaris due >> to JNIEXPORT (they were previously >> exported only in libawt): >> Java_sun_awt_DebugSettings_setCTracingOn__Z >> Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2 >> Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2I >> Java_sun_awt_X11GraphicsConfig_getNumColors >> >> java.desktop:/libawt_headless: The following symbols are now also >> exported due to JNIEXPORT (they were previously >> exported only in libawt_xawt and/or libawt): >> Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo >> Java_sun_java2d_opengl_GLXGraphicsConfig_getOGLCapabilities >> Java_sun_java2d_x11_X11PMBlitLoops_updateBitmask >> Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable >> X11SurfaceData_GetOps >> >> java.desktop/libawt: The following symbols are now also exported on >> Windows, due to added >> JNIEXPORT: >> SurfaceData_InitOps >> mul8table >> div8table >> doDrawPath >> doFillPath >> g_CMpDataID >> initInverseGrayLut >> make_dither_arrays >> make_uns_ordered_dither_array >> path2DFloatCoordsID >> path2DNumTypesID >> path2DTypesID >> path2DWindingRuleID >> sg2dStrokeHintID >> std_img_oda_blue >> std_img_oda_green >> std_img_oda_red >> std_odas_computed >> sunHints_INTVAL_STROKE_PURE >> >> java.desktop/libawt on solaris: >> A number of "#pragma weak" directives was previously overridden by >> the mapfile. >> Now these directives are respected, so these symbols are now weak >> instead of local: >> ByteGrayToIntArgbPreConvert_F >> ByteGrayToIntArgbPreScaleConvert_F >> IntArgbBmToFourByteAbgrPreScaleXparOver_F >> IntArgbToIntRgbXorBlit_F >> IntBgrToIntBgrAlphaMaskBlit_F >> >> java.desktop/libawt on solaris: These are now also exported due to >> JNIEXPORT in libmlib_image. >> j2d_mlib_ImageCreate >> j2d_mlib_ImageCreateStruct >> j2d_mlib_ImageDelete >> >> java.desktop/libawt on solaris: This is now also exported due to >> JNIEXPORT: >> GrPrim_CompGetXorColor >> SurfaceData_GetOpsNoSetup >> SurfaceData_IntersectBoundsXYWH >> SurfaceData_SetOps >> Transform_GetInfo >> Transform_transform >> >> java.desktop/libsplashscreen: JNI_OnLoad is now exported on linux and >> solaris due to JNIEXPORT. >> libspashscreen also had JNIEXPORT (actually a pure >> _declspec(dllexport)) but no JNICALL, which I added as >> a part of converting to JNIEXPORT. The same goes for libmlib_image . >> >> jdk.sctp/libsctp: handleSocketError is now exported on linux and >> solaris due to JNIEXPORT in libnio. >> >> java.instrument:/libinstrument: Agent_OnUnload is now also exported >> on linux and solaris platforms due to JNIEXPORT. >> JLI_ManifestIterate is now also exported on Windows, due to added >> JNIEXPORT in libjli. >> >> jdk.management/libmanagement_ext: >> Java_com_sun_management_internal_Flag_setDoubleValue is now also >> exported on linux and solaris platforms due to JNIEXPORT. >> >> /Magnus >> >> > From Alan.Bateman at ORACLE.COM Fri Mar 23 18:06:37 2018 From: Alan.Bateman at ORACLE.COM (Alan Bateman) Date: Fri, 23 Mar 2018 18:06:37 +0000 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: <5AB53E95.9080308@oracle.com> References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> Message-ID: Is there an up to date webrev on cr.openjdk.java.net that we can review? The inflate/deflate methods in the original proposal made sense, I'm less sure about introducing a new setDictionary method. -Alan On 23/03/2018 17:51, Xueming Shen wrote: > > Hi David, > > Sorry for the late response. I will sponsor this change. Will prepare > for the CSR for > the new APIs. > > Couple more comments > > (1) Deflater.java/deflate(ByteBuffer, int); > "In the case of FULL_FLUSH or SYNC_FLUSH ..." > > It's a copy/paste from the corresponding part in deflate(byte[], int, > int, int). The existing > one might not be clear. What it meant to say is "if the returned value > is equal to the > space available in the output buffer passed in ...then you need to > call it with more sapce, > greater than 6 bytes ...". So the {@code len} need to updated to > something like > {@code output.remainint()}. > > (2) Inflater.java/setDictionary(ByteBuffer); > "Sets the preset dictionary to the given array of bytes" > ??? --> bytes in the specified byte buffer? > > (3) Infalter.java.inflater(...) > It appears there is opportunity to "consolidate" some of the > repetitive code block, > for example the "catch (DFE e) { ...} the only difference is the > "inputPos/input.position()" > line. Maybe we can move the try/catch out a "level" and consolidate > this catch block. > Sure it's a style preference. We can deal with it later. > > Thanks, > Sherman > > > On 03/23/2018 08:18 AM, David Lloyd wrote: >> Are there any further comments on this? If not, would it be possible >> to get a sponsor for this change? >> >> Sorry again for the detached email threads; I've learned my GMail >> lesson well... >> >> Thanks. >> >> On Fri, Mar 16, 2018 at 8:25 AM, David Lloyd? >> wrote: >>> Sorry, that was an error on my part, caused by too much context >>> switching.? I've posted an update at >>> https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v13 which is >>> also attached. >>> >>> On Wed, Mar 14, 2018 at 8:53 PM, Xueming >>> Shen? wrote: >>>> Hi David, >>>> >>>> https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v12 >>>> >>>> Should we start to review the changes included in above link, or we >>>> should >>>> wait ? It appears >>>> the API is being updated but some implementation have not been >>>> updated to >>>> follow the spec >>>> yet, especially the piece that deals with the output >>>> buffer/byteWritten when >>>> DataFormatException >>>> is raised, for example >>>> >>>> (1) the "outputConsumedID" is defined but never used to update the >>>> corresponding java field >>>> ????? in Inflater.c and >>>> >>>> (2) the "outputConsumed" is used to update the output ByteBuffer >>>> when DFE >>>> raised (in Java), but >>>> ????? the corresponding "byteWritten" is not being updated before the >>>> exception is thrown. >>>> >>>> -Sherman >>>> >>>> >>>> >>>> >>>> On 3/13/18, 10:46 AM, David Lloyd wrote: >>>>> Sorry all, it looks like GMail doesn't know how to keep replies with >>>>> the thread when you change the subject line.? The follow-up to this >>>>> thread is >>>>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-March/051960.html >>>>> >>>>> with only a few small changes as discussed above. >>>>> >>>>> On Fri, Mar 2, 2018 at 2:36 PM, David Lloyd >>>>> wrote: >>>>>> On Fri, Mar 2, 2018 at 2:34 PM, David Lloyd >>>>>> wrote: >>>>>>> On Fri, Mar 2, 2018 at 12:49 PM, Xueming >>>>>>> Shen >>>>>>> wrote: >>>>>>>> Hi David, >>>>>>>> >>>>>>>> (1) Deflater.deflate(Bytebuffer) >>>>>>>> ?????? the api doc regarding "no_flush" appears to be the >>>>>>>> copy/paste of >>>>>>>> the >>>>>>>> byte[] version >>>>>>>> ?????? without being updated to the corresponding ByteBuffer? >>>>>>> You're right, I missed that one.? I've incorporated this fix >>>>>>> locally: >>>>>> Oops, this should have been: >>>>>> >>>>>> --- 8>>>>> >>>>>> diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java >>>>>> b/src/java.base/share/classes/java/util/zip/Deflater.java >>>>>> index 524125787a8..40f0d9736e2 100644 >>>>>> --- a/src/java.base/share/classes/java/util/zip/Deflater.java >>>>>> +++ b/src/java.base/share/classes/java/util/zip/Deflater.java >>>>>> @@ -481,9 +481,9 @@ public class Deflater { >>>>>> ??????? * in order to determine if more input data is required. >>>>>> ??????? * >>>>>> ??????? *

This method uses {@link #NO_FLUSH} as its compression >>>>>> flush >>>>>> mode. >>>>>> -???? * An invocation of this method of the form {@code >>>>>> deflater.deflate(b)} >>>>>> +???? * An invocation of this method of the form {@code >>>>>> deflater.deflate(output)} >>>>>> ??????? * yields the same result as the invocation of >>>>>> -???? * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. >>>>>> +???? * {@code deflater.deflate(output, Deflater.NO_FLUSH)}. >>>>>> ??????? * >>>>>> ??????? * @param output the buffer for the compressed data >>>>>> ??????? * @return the actual number of bytes of compressed data >>>>>> written to >>>>>> the >>>>>> >>>>>> --- 8>>>>> >>>>>> -- >>>>>> - DML >>>>> >>>>> >>> >>> >>> -- >>> - DML >> >> > From huizhe.wang at oracle.com Fri Mar 23 18:42:58 2018 From: huizhe.wang at oracle.com (Joe Wang) Date: Fri, 23 Mar 2018 11:42:58 -0700 Subject: RFR (JDK11/doc-only) 8199176: Accessibility issues in java.base docs In-Reply-To: References: <5AB2ADB9.8080909@oracle.com> <551fd76a-bd69-3186-865f-b38ade2a5ba6@oracle.com> <37c2ae02-38da-a8e4-9efe-3b7d817fcb87@oracle.com> Message-ID: <883d9dc2-ec91-de9e-080f-bb29e26a3352@oracle.com> Thanks Roger!? I'll check this changeset in for now to fix the accessibility issue, with a note that a future solution that correctly generates the appropriate and consistent headers is desirable. JDK-8199895 may be used for further discussion. [1] https://bugs.openjdk.java.net/browse/JDK-8199895 Best, Joe On 3/23/2018 10:49 AM, Roger Riggs wrote: > Hi Joe, > > Looks fine. > > (I would be in favor of a future solution that correctly > generated/fixed up the appropriate headers; > Manual editing and corrections are an unnecessary overhead.) > > Thanks, Roger > > On 3/21/2018 6:47 PM, Joe Wang wrote: >> They look ok. They actually go better with the package name when they >> are just 1 level down instead of 2, that is,

rather than

>> for the titles when the package name is

. If we don't want the >> strong emphasis on the titles, we could lower the package name >> generated by javadoc to

instead of

. Then we could keep the >>

s. >> >> Most of the package-info pages have already used

for titles, >> which is why we're fixing only a handful of them here. Consider: >> >> *Currently using

:* >> https://docs.oracle.com/javase/10/docs/api//java/io/package-summary.html >> https://docs.oracle.com/javase/10/docs/api//java/lang/invoke/package-summary.html >> >> >> In the later page, it actually started with

: >> ?

Summary of relevant Java Virtual Machine >> changes

>> >> *Currently using

:* >> https://docs.oracle.com/javase/10/docs/api//javax/xml/transform/package-summary.html >> >> >> -Joe >> >> >> On 3/21/2018 2:39 PM, Jonathan Gibbons wrote: >>> >>> >>> On 3/21/18 2:28 PM, Alan Bateman wrote: >>>> On 21/03/2018 19:08, Joe Wang wrote: >>>>> : >>>>> >>>>> *Item 3*: Heading leavels should only increase by one >>>>> ??? This is due to the javadoc tool generates a header with an >>>>> addition of headings, in this particular case,

. The fix for >>>>> this particular case is to replace the

s with

. >>>> I assume this has the effect of increasing the size of the >>>> headings. Does it look okay? I assume many of these usages of h3 >>>> choose that to avoid heading in very large font. >>>> >>>> -Alan >>> >>> I know accessibility fixes are important, but usability is important >>> too.? The uses of h3 were previously consistent across different pages. >>> >>> We could remediate the problem either by figuring a design that has >>> javadoc put a similar set of headers on every page (thus rendering >>> this changeset unnecessary) or else changing the stylesheet so that >>>

on a package-summary page looks the same as

on a class >>> page (which sounds icky, even as I type it.) >>> >>> -- Jon >>> >> > From david.lloyd at redhat.com Fri Mar 23 19:17:59 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Fri, 23 Mar 2018 14:17:59 -0500 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: <5AB53E95.9080308@oracle.com> References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> Message-ID: On Fri, Mar 23, 2018 at 12:51 PM, Xueming Shen wrote: > > Hi David, > > Sorry for the late response. I will sponsor this change. Will prepare for > the CSR for > the new APIs. Thanks! > Couple more comments > > (1) Deflater.java/deflate(ByteBuffer, int); > "In the case of FULL_FLUSH or SYNC_FLUSH ..." > [...] > (2) Inflater.java/setDictionary(ByteBuffer); > "Sets the preset dictionary to the given array of bytes" > --> bytes in the specified byte buffer? > > (3) Infalter.java.inflater(...) > It appears there is opportunity to "consolidate" some of the repetitive code > block, > [...] > for example the "catch (DFE e) { ...} the only difference is the All fixed. You're right, the catch blocks consolidated fairly easily and it looks better. I've attached the latest version of the patch. -- - DML -------------- next part -------------- commit 2c798586b3451ba9cfe3069e5ee2699caf2c38fb Author: David M. Lloyd Date: Fri Feb 16 11:00:10 2018 -0600 [JDK-6341887] Update Inflater/Deflater to handle ByteBuffer diff --git a/make/mapfiles/libzip/mapfile-vers b/make/mapfiles/libzip/mapfile-vers index d711d8e17f4..11ccc2d6ecb 100644 --- a/make/mapfiles/libzip/mapfile-vers +++ b/make/mapfiles/libzip/mapfile-vers @@ -33,20 +33,28 @@ SUNWprivate_1.1 { Java_java_util_zip_CRC32_update; Java_java_util_zip_CRC32_updateBytes0; Java_java_util_zip_CRC32_updateByteBuffer0; - Java_java_util_zip_Deflater_deflateBytes; + Java_java_util_zip_Deflater_deflateBytesBytes; + Java_java_util_zip_Deflater_deflateBytesBuffer; + Java_java_util_zip_Deflater_deflateBufferBytes; + Java_java_util_zip_Deflater_deflateBufferBuffer; Java_java_util_zip_Deflater_end; Java_java_util_zip_Deflater_getAdler; Java_java_util_zip_Deflater_init; Java_java_util_zip_Deflater_initIDs; Java_java_util_zip_Deflater_reset; Java_java_util_zip_Deflater_setDictionary; + Java_java_util_zip_Deflater_setDictionaryBuffer; Java_java_util_zip_Inflater_end; Java_java_util_zip_Inflater_getAdler; - Java_java_util_zip_Inflater_inflateBytes; + Java_java_util_zip_Inflater_inflateBytesBytes; + Java_java_util_zip_Inflater_inflateBytesBuffer; + Java_java_util_zip_Inflater_inflateBufferBytes; + Java_java_util_zip_Inflater_inflateBufferBuffer; Java_java_util_zip_Inflater_init; Java_java_util_zip_Inflater_initIDs; Java_java_util_zip_Inflater_reset; Java_java_util_zip_Inflater_setDictionary; + Java_java_util_zip_Inflater_setDictionaryBuffer; ZIP_Close; ZIP_CRC32; ZIP_FreeEntry; diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java b/src/java.base/share/classes/java/util/zip/Deflater.java index c75dd4a33f0..a1720a78986 100644 --- a/src/java.base/share/classes/java/util/zip/Deflater.java +++ b/src/java.base/share/classes/java/util/zip/Deflater.java @@ -26,7 +26,13 @@ package java.util.zip; import java.lang.ref.Cleaner.Cleanable; +import java.lang.ref.Reference; +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; +import java.util.Objects; + import jdk.internal.ref.CleanerFactory; +import sun.nio.ch.DirectBuffer; /** * This class provides support for general purpose compression using the @@ -92,8 +98,9 @@ import jdk.internal.ref.CleanerFactory; public class Deflater { private final DeflaterZStreamRef zsRef; - private byte[] buf = new byte[0]; - private int off, len; + private ByteBuffer input = ZipUtils.defaultBuf; + private byte[] inputArray; + private int inputPos, inputLim; private int level, strategy; private boolean setParams; private boolean finish, finished; @@ -170,9 +177,14 @@ public class Deflater { */ public static final int FULL_FLUSH = 3; + /** + * Flush mode to use at the end of output. Can only be provided by the + * user by way of {@link #finish()}. + */ + private static final int FINISH = 4; + static { ZipUtils.loadLibrary(); - initIDs(); } /** @@ -216,16 +228,14 @@ public class Deflater { * @see Deflater#needsInput */ public void setInput(byte[] b, int off, int len) { - if (b== null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { - this.buf = b; - this.off = off; - this.len = len; + this.input = null; + this.inputArray = b; + this.inputPos = off; + this.inputLim = off + len; } } @@ -239,6 +249,31 @@ public class Deflater { setInput(b, 0, b.length); } + /** + * Sets input data for compression. This should be called whenever + * needsInput() returns true indicating that more input data is required. + *

+ * The given buffer's position will be updated as deflate operations are + * performed. The input buffer may be modified (refilled) between deflate + * operations; doing so is equivalent to creating a new buffer and setting + * it with this method. + *

+ * Modifying the input buffer's contents, position, or limit concurrently with + * a deflate operation will result in undefined behavior, which may include + * incorrect operation results or operation failure. + * + * @param byteBuffer the input data bytes + * @see Deflater#needsInput + * @since 11 + */ + public void setInput(ByteBuffer byteBuffer) { + Objects.requireNonNull(byteBuffer); + synchronized (zsRef) { + this.input = byteBuffer; + this.inputArray = null; + } + } + /** * Sets preset dictionary for compression. A preset dictionary is used * when the history buffer can be predetermined. When the data is later @@ -252,9 +287,6 @@ public class Deflater { * @see Inflater#getAdler */ public void setDictionary(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } @@ -278,6 +310,41 @@ public class Deflater { setDictionary(b, 0, b.length); } + /** + * Sets preset dictionary for compression. A preset dictionary is used + * when the history buffer can be predetermined. When the data is later + * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called + * in order to get the Adler-32 value of the dictionary required for + * decompression. + *

+ * The bytes in given byte buffer will be fully consumed by this method. On + * return, its position will equal its limit. + * + * @param byteBuffer the dictionary data bytes + * @see Inflater#inflate + * @see Inflater#getAdler + */ + public void setDictionary(ByteBuffer byteBuffer) { + synchronized (zsRef) { + final int position = byteBuffer.position(); + final int remaining = Math.max(byteBuffer.limit() - position, 0); + ensureOpen(); + if (byteBuffer.isDirect()) { + final long address = ((DirectBuffer) byteBuffer).address(); + try { + setDictionaryBuffer(zsRef.address(), address + position, remaining); + } finally { + Reference.reachabilityFence(byteBuffer); + } + } else { + final byte[] array = ZipUtils.getBufferArray(byteBuffer); + final int offset = ZipUtils.getBufferOffset(byteBuffer); + setDictionary(zsRef.address(), array, offset + position, remaining); + } + byteBuffer.position(position + remaining); + } + } + /** * Sets the compression strategy to the specified value. * @@ -331,14 +398,17 @@ public class Deflater { } /** - * Returns true if the input data buffer is empty and setInput() - * should be called in order to provide more input. + * Returns true if no data remains in the input buffer. This can + * be used to determine if one of the {@code setInput()} methods should be + * called in order to provide more input. + * * @return true if the input data buffer is empty and setInput() * should be called in order to provide more input */ public boolean needsInput() { synchronized (zsRef) { - return len <= 0; + final ByteBuffer input = this.input; + return input == null ? inputLim == inputPos : ! input.hasRemaining(); } } @@ -404,6 +474,26 @@ public class Deflater { return deflate(b, 0, b.length, NO_FLUSH); } + /** + * Compresses the input data and fills specified buffer with compressed + * data. Returns actual number of bytes of compressed data. A return value + * of 0 indicates that {@link #needsInput() needsInput} should be called + * in order to determine if more input data is required. + * + *

This method uses {@link #NO_FLUSH} as its compression flush mode. + * An invocation of this method of the form {@code deflater.deflate(output)} + * yields the same result as the invocation of + * {@code deflater.deflate(output, Deflater.NO_FLUSH)}. + * + * @param output the buffer for the compressed data + * @return the actual number of bytes of compressed data written to the + * output buffer + * @since 11 + */ + public int deflate(ByteBuffer output) { + return deflate(output, NO_FLUSH); + } + /** * Compresses the input data and fills the specified buffer with compressed * data. Returns actual number of bytes of data compressed. @@ -441,6 +531,10 @@ public class Deflater { * repeatedly output to the output buffer every time this method is * invoked. * + *

If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation. + * * @param b the buffer for the compressed data * @param off the start offset of the data * @param len the maximum number of bytes of compressed data @@ -452,24 +546,247 @@ public class Deflater { * @since 1.7 */ public int deflate(byte[] b, int off, int len, int flush) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } + if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) { + throw new IllegalArgumentException(); + } synchronized (zsRef) { ensureOpen(); - if (flush == NO_FLUSH || flush == SYNC_FLUSH || - flush == FULL_FLUSH) { - int thisLen = this.len; - int n = deflateBytes(zsRef.address(), b, off, len, flush); - bytesWritten += n; - bytesRead += (thisLen - this.len); - return n; + + final ByteBuffer input = this.input; + if (finish) { + // disregard given flush mode in this case + flush = FINISH; + } + final int params; + if (setParams) { + // bit 0: true to set params + // bit 1-2: strategy (0, 1, or 2) + // bit 3-31: level (0..9 or -1) + params = 1 | strategy << 1 | level << 3; + } else { + params = 0; + } + final int inputPos; + final long result; + if (input == null) { + inputPos = this.inputPos; + result = deflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + b, off, len, + flush, params); + } else { + inputPos = input.position(); + final int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + try { + final long inputAddress = ((DirectBuffer) input).address(); + result = deflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + b, off, len, + flush, params); + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + b, off, len, + flush, params); + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; } + if (params != 0 && (result >>> 63 & 1) == 0) { + setParams = false; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + bytesWritten += written; + bytesRead += read; + return written; + } + } + + /** + * Compresses the input data and fills the specified buffer with compressed + * data. Returns actual number of bytes of data compressed. + * + *

Compression flush mode is one of the following three modes: + * + *

    + *
  • {@link #NO_FLUSH}: allows the deflater to decide how much data + * to accumulate, before producing output, in order to achieve the best + * compression (should be used in normal use scenario). A return value + * of 0 in this flush mode indicates that {@link #needsInput()} should + * be called in order to determine if more input data is required. + * + *
  • {@link #SYNC_FLUSH}: all pending output in the deflater is flushed, + * to the specified output buffer, so that an inflater that works on + * compressed data can get all input data available so far (In particular + * the {@link #needsInput()} returns {@code true} after this invocation + * if enough output space is provided). Flushing with {@link #SYNC_FLUSH} + * may degrade compression for some compression algorithms and so it + * should be used only when necessary. + * + *
  • {@link #FULL_FLUSH}: all pending output is flushed out as with + * {@link #SYNC_FLUSH}. The compression state is reset so that the inflater + * that works on the compressed output data can restart from this point + * if previous compressed data has been damaged or if random access is + * desired. Using {@link #FULL_FLUSH} too often can seriously degrade + * compression. + *
+ * + *

In the case of {@link #FULL_FLUSH} or {@link #SYNC_FLUSH}, if + * the return value is equal to the {@linkplain ByteBuffer#remaining() remaining space} + * of the buffer, this method should be invoked again with the same + * {@code flush} parameter and more output space. Make sure that + * the buffer's remaining space is greater than 6 to avoid the + * flush marker (5 bytes) being repeatedly output to the output buffer + * every time this method is invoked. + * + *

On success, the position of the given {@code output} byte buffer will be + * advanced by as many bytes as were produced by the operation, which is equal + * to the number returned by this method. + * + *

If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation. + * + * @param output the buffer for the compressed data + * @param flush the compression flush mode + * @return the actual number of bytes of compressed data written to + * the output buffer + * + * @throws IllegalArgumentException if the flush mode is invalid + * @since 11 + */ + public int deflate(ByteBuffer output, int flush) { + if (output.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) { throw new IllegalArgumentException(); } + synchronized (zsRef) { + ensureOpen(); + + final ByteBuffer input = this.input; + if (finish) { + // disregard given flush mode in this case + flush = FINISH; + } + final int params; + if (setParams) { + // bit 0: true to set params + // bit 1-2: strategy (0, 1, or 2) + // bit 3-31: level (0..9 or -1) + params = 1 | strategy << 1 | level << 3; + } else { + params = 0; + } + final int outputPos = output.position(); + final int outputRem = Math.max(output.limit() - outputPos, 0); + final int inputPos; + final long result; + if (input == null) { + inputPos = this.inputPos; + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = deflateBytesBuffer(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputAddress + outputPos, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } else { + inputPos = input.position(); + final int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + final long inputAddress = ((DirectBuffer) input).address(); + try { + if (output.isDirect()) { + final long outputAddress = outputPos + ((DirectBuffer) output).address(); + try { + result = deflateBufferBuffer(zsRef.address(), + inputAddress + inputPos, inputRem, + outputAddress, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = deflateBytesBuffer(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputAddress + outputPos, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if (params != 0 && (result >>> 63 & 1) == 0) { + setParams = false; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + output.position(outputPos + written); + bytesWritten += written; + bytesRead += read; + return written; + } } /** @@ -545,7 +862,8 @@ public class Deflater { reset(zsRef.address()); finish = false; finished = false; - off = len = 0; + input = ZipUtils.defaultBuf; + inputArray = null; bytesRead = bytesWritten = 0; } } @@ -560,7 +878,7 @@ public class Deflater { public void end() { synchronized (zsRef) { zsRef.clean(); - buf = null; + input = ZipUtils.defaultBuf; } } @@ -585,11 +903,26 @@ public class Deflater { throw new NullPointerException("Deflater has been closed"); } - private static native void initIDs(); private static native long init(int level, int strategy, boolean nowrap); - private static native void setDictionary(long addr, byte[] b, int off, int len); - private native int deflateBytes(long addr, byte[] b, int off, int len, - int flush); + private static native void setDictionary(long addr, byte[] b, int off, + int len); + private static native void setDictionaryBuffer(long addr, long bufAddress, int len); + private native long deflateBytesBytes(long addr, + byte[] inputArray, int inputOff, int inputLen, + byte[] outputArray, int outputOff, int outputLen, + int flush, int params); + private native long deflateBytesBuffer(long addr, + byte[] inputArray, int inputOff, int inputLen, + long outputAddress, int outputLen, + int flush, int params); + private native long deflateBufferBytes(long addr, + long inputAddress, int inputLen, + byte[] outputArray, int outputOff, int outputLen, + int flush, int params); + private native long deflateBufferBuffer(long addr, + long inputAddress, int inputLen, + long outputAddress, int outputLen, + int flush, int params); private static native int getAdler(long addr); private static native void reset(long addr); private static native void end(long addr); diff --git a/src/java.base/share/classes/java/util/zip/Inflater.java b/src/java.base/share/classes/java/util/zip/Inflater.java index 9c6d8aa3d83..bafb1140dfc 100644 --- a/src/java.base/share/classes/java/util/zip/Inflater.java +++ b/src/java.base/share/classes/java/util/zip/Inflater.java @@ -26,7 +26,13 @@ package java.util.zip; import java.lang.ref.Cleaner.Cleanable; +import java.lang.ref.Reference; +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; +import java.util.Objects; + import jdk.internal.ref.CleanerFactory; +import sun.nio.ch.DirectBuffer; /** * This class provides support for general purpose decompression using the @@ -92,14 +98,20 @@ import jdk.internal.ref.CleanerFactory; public class Inflater { private final InflaterZStreamRef zsRef; - private byte[] buf = defaultBuf; - private int off, len; + private ByteBuffer input = ZipUtils.defaultBuf; + private byte[] inputArray; + private int inputPos, inputLim; private boolean finished; private boolean needDict; private long bytesRead; private long bytesWritten; - private static final byte[] defaultBuf = new byte[0]; + /* + * These fields are used as an "out" parameter from JNI when a + * DataFormatException is thrown during the inflate operation. + */ + private int inputConsumed; + private int outputConsumed; static { ZipUtils.loadLibrary(); @@ -138,16 +150,14 @@ public class Inflater { * @see Inflater#needsInput */ public void setInput(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { - this.buf = b; - this.off = off; - this.len = len; + this.input = null; + this.inputArray = b; + this.inputPos = off; + this.inputLim = off + len; } } @@ -162,6 +172,32 @@ public class Inflater { setInput(b, 0, b.length); } + /** + * Sets input data for decompression. Should be called whenever + * needsInput() returns true indicating that more input data is + * required. + *

+ * The given buffer's position will be updated as inflate operations are + * performed. The input buffer may be modified (refilled) between inflate + * operations; doing so is equivalent to creating a new buffer and setting + * it with this method. + *

+ * Modifying the input buffer's contents, position, or limit concurrently with + * an inflate operation will result in undefined behavior, which may include + * incorrect operation results or operation failure. + * + * @param byteBuffer the input data bytes + * @see Inflater#needsInput + * @since 11 + */ + public void setInput(ByteBuffer byteBuffer) { + Objects.requireNonNull(byteBuffer); + synchronized (zsRef) { + this.input = byteBuffer; + this.inputArray = null; + } + } + /** * Sets the preset dictionary to the given array of bytes. Should be * called when inflate() returns 0 and needsDictionary() returns true @@ -174,9 +210,6 @@ public class Inflater { * @see Inflater#getAdler */ public void setDictionary(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } @@ -200,6 +233,42 @@ public class Inflater { setDictionary(b, 0, b.length); } + /** + * Sets the preset dictionary to the bytes in the given buffer. Should be + * called when inflate() returns 0 and needsDictionary() returns true + * indicating that a preset dictionary is required. The method getAdler() + * can be used to get the Adler-32 value of the dictionary needed. + *

+ * The bytes in given byte buffer will be fully consumed by this method. On + * return, its position will equal its limit. + * + * @param byteBuffer the dictionary data bytes + * @see Inflater#needsDictionary + * @see Inflater#getAdler + * @since 11 + */ + public void setDictionary(ByteBuffer byteBuffer) { + synchronized (zsRef) { + final int position = byteBuffer.position(); + final int remaining = Math.max(byteBuffer.limit() - position, 0); + ensureOpen(); + if (byteBuffer.isDirect()) { + final long address = ((DirectBuffer) byteBuffer).address(); + try { + setDictionaryBuffer(zsRef.address(), address + position, remaining); + } finally { + Reference.reachabilityFence(byteBuffer); + } + } else { + final byte[] array = ZipUtils.getBufferArray(byteBuffer); + final int offset = ZipUtils.getBufferOffset(byteBuffer); + setDictionary(zsRef.address(), array, offset + position, remaining); + } + byteBuffer.position(position + remaining); + needDict = false; + } + } + /** * Returns the total number of bytes remaining in the input buffer. * This can be used to find out what bytes still remain in the input @@ -208,19 +277,22 @@ public class Inflater { */ public int getRemaining() { synchronized (zsRef) { - return len; + final ByteBuffer input = this.input; + return input == null ? inputLim - inputPos : input.remaining(); } } /** * Returns true if no data remains in the input buffer. This can - * be used to determine if #setInput should be called in order - * to provide more input. + * be used to determine if one of the {@code setInput()} methods should be + * called in order to provide more input. + * * @return true if no data remains in the input buffer */ public boolean needsInput() { synchronized (zsRef) { - return len <= 0; + final ByteBuffer input = this.input; + return input == null ? inputLim == inputPos : ! input.hasRemaining(); } } @@ -254,30 +326,103 @@ public class Inflater { * determine if more input data or a preset dictionary is required. * In the latter case, getAdler() can be used to get the Adler-32 * value of the dictionary required. + *

+ * If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation, even in the event that a {@link DataFormatException} + * is thrown. + *

+ * The {@linkplain #getRemaining() remaining byte count} will be reduced by + * the number of consumed input bytes. If the {@link #setInput(ByteBuffer)} + * method was called to provide a buffer for input, the input buffer's position + * will be advanced the number of consumed bytes. + *

+ * These byte totals, as well as + * the {@linkplain #getBytesRead() total bytes read} + * and the {@linkplain #getBytesWritten() total bytes written} + * values, will be updated even in the event that a {@link DataFormatException} + * is thrown to reflect the amount of data consumed and produced before the + * exception occurred. + * * @param b the buffer for the uncompressed data * @param off the start offset of the data * @param len the maximum number of uncompressed bytes * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid + * @throws DataFormatException if the compressed data format is invalid * @see Inflater#needsInput * @see Inflater#needsDictionary */ public int inflate(byte[] b, int off, int len) throws DataFormatException { - if (b == null) { - throw new NullPointerException(); - } if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { ensureOpen(); - int thisLen = this.len; - int n = inflateBytes(zsRef.address(), b, off, len); - bytesWritten += n; - bytesRead += (thisLen - this.len); - return n; + final ByteBuffer input = this.input; + final long result; + final int inputPos; + try { + if (input == null) { + inputPos = this.inputPos; + try { + result = inflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + b, off, len); + } catch (DataFormatException e) { + this.inputPos = inputPos + inputConsumed; + throw e; + } + } else { + inputPos = input.position(); + try { + final int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + try { + final long inputAddress = ((DirectBuffer) input).address(); + result = inflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + b, off, len); + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + b, off, len); + } + } catch (DataFormatException e) { + input.position(inputPos + inputConsumed); + throw e; + } + } + } catch (DataFormatException e) { + bytesRead += inputConsumed; + inputConsumed = 0; + int written = outputConsumed; + bytesWritten += written; + outputConsumed = 0; + throw e; + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if ((result >>> 63 & 1) != 0) { + needDict = true; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + bytesWritten += written; + bytesRead += read; + return written; } } @@ -288,9 +433,22 @@ public class Inflater { * determine if more input data or a preset dictionary is required. * In the latter case, getAdler() can be used to get the Adler-32 * value of the dictionary required. + *

+ * The {@linkplain #getRemaining() remaining byte count} will be reduced by + * the number of consumed input bytes. If the {@link #setInput(ByteBuffer)} + * method was called to provide a buffer for input, the input buffer's position + * will be advanced the number of consumed bytes. + *

+ * These byte totals, as well as + * the {@linkplain #getBytesRead() total bytes read} + * and the {@linkplain #getBytesWritten() total bytes written} + * values, will be updated even in the event that a {@link DataFormatException} + * is thrown to reflect the amount of data consumed and produced before the + * exception occurred. + * * @param b the buffer for the uncompressed data * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid + * @throws DataFormatException if the compressed data format is invalid * @see Inflater#needsInput * @see Inflater#needsDictionary */ @@ -298,6 +456,156 @@ public class Inflater { return inflate(b, 0, b.length); } + /** + * Uncompresses bytes into specified buffer. Returns actual number + * of bytes uncompressed. A return value of 0 indicates that + * needsInput() or needsDictionary() should be called in order to + * determine if more input data or a preset dictionary is required. + * In the latter case, getAdler() can be used to get the Adler-32 + * value of the dictionary required. + *

+ * On success, the position of the given {@code output} byte buffer will be + * advanced by as many bytes as were produced by the operation, which is equal + * to the number returned by this method. Note that the position of the + * {@code output} buffer will be advanced even in the event that a + * {@link DataFormatException} is thrown. + *

+ * The {@linkplain #getRemaining() remaining byte count} will be reduced by + * the number of consumed input bytes. If the {@link #setInput(ByteBuffer)} + * method was called to provide a buffer for input, the input buffer's position + * will be advanced the number of consumed bytes. + *

+ * These byte totals, as well as + * the {@linkplain #getBytesRead() total bytes read} + * and the {@linkplain #getBytesWritten() total bytes written} + * values, will be updated even in the event that a {@link DataFormatException} + * is thrown to reflect the amount of data consumed and produced before the + * exception occurred. + * + * @param output the buffer for the uncompressed data + * @return the actual number of uncompressed bytes + * @throws DataFormatException if the compressed data format is invalid + * @throws ReadOnlyBufferException if the given output buffer is read-only + * @see Inflater#needsInput + * @see Inflater#needsDictionary + * @since 11 + */ + public int inflate(ByteBuffer output) throws DataFormatException { + if (output.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + synchronized (zsRef) { + ensureOpen(); + final ByteBuffer input = this.input; + final long result; + final int inputPos; + final int outputPos = output.position(); + final int outputRem = Math.max(output.limit() - outputPos, 0); + try { + if (input == null) { + inputPos = this.inputPos; + try { + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBytesBuffer(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputArray, outputOffset + outputPos, outputRem); + } + } catch (DataFormatException e) { + this.inputPos = inputPos + inputConsumed; + throw e; + } + } else { + inputPos = input.position(); + final int inputRem = Math.max(input.limit() - inputPos, 0); + try { + if (input.isDirect()) { + final long inputAddress = ((DirectBuffer) input).address(); + try { + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBufferBuffer(zsRef.address(), + inputAddress + inputPos, inputRem, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem); + } + } finally { + Reference.reachabilityFence(input); + } + } else { + final byte[] inputArray = ZipUtils.getBufferArray(input); + final int inputOffset = ZipUtils.getBufferOffset(input); + if (output.isDirect()) { + final long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBytesBuffer(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + final byte[] outputArray = ZipUtils.getBufferArray(output); + final int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem); + } + } + } catch (DataFormatException e) { + input.position(inputPos + inputConsumed); + throw e; + } + } + } catch (DataFormatException e) { + bytesRead += inputConsumed; + inputConsumed = 0; + int written = outputConsumed; + output.position(outputPos + written); + bytesWritten += written; + outputConsumed = 0; + throw e; + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if ((result >>> 63 & 1) != 0) { + needDict = true; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + // Note: this method call also serves to keep the byteBuffer ref alive + output.position(outputPos + written); + bytesWritten += written; + bytesRead += read; + return written; + } + } + /** * Returns the ADLER-32 value of the uncompressed data. * @return the ADLER-32 value of the uncompressed data @@ -368,10 +676,10 @@ public class Inflater { synchronized (zsRef) { ensureOpen(); reset(zsRef.address()); - buf = defaultBuf; + input = ZipUtils.defaultBuf; + inputArray = null; finished = false; needDict = false; - off = len = 0; bytesRead = bytesWritten = 0; } } @@ -386,7 +694,8 @@ public class Inflater { public void end() { synchronized (zsRef) { zsRef.clean(); - buf = null; + input = ZipUtils.defaultBuf; + inputArray = null; } } @@ -416,18 +725,23 @@ public class Inflater { throw new NullPointerException("Inflater has been closed"); } - boolean ended() { - synchronized (zsRef) { - return zsRef.address() == 0; - } - } - private static native void initIDs(); private static native long init(boolean nowrap); private static native void setDictionary(long addr, byte[] b, int off, int len); - private native int inflateBytes(long addr, byte[] b, int off, int len) - throws DataFormatException; + private static native void setDictionaryBuffer(long addr, long bufAddress, int len); + private native long inflateBytesBytes(long addr, + byte[] inputArray, int inputOff, int inputLen, + byte[] outputArray, int outputOff, int outputLen) throws DataFormatException; + private native long inflateBytesBuffer(long addr, + byte[] inputArray, int inputOff, int inputLen, + long outputAddress, int outputLen) throws DataFormatException; + private native long inflateBufferBytes(long addr, + long inputAddress, int inputLen, + byte[] outputArray, int outputOff, int outputLen) throws DataFormatException; + private native long inflateBufferBuffer(long addr, + long inputAddress, int inputLen, + long outputAddress, int outputLen) throws DataFormatException; private static native int getAdler(long addr); private static native void reset(long addr); private static native void end(long addr); diff --git a/src/java.base/share/classes/java/util/zip/ZipUtils.java b/src/java.base/share/classes/java/util/zip/ZipUtils.java index 45c5d8dbb67..07e64e4fa92 100644 --- a/src/java.base/share/classes/java/util/zip/ZipUtils.java +++ b/src/java.base/share/classes/java/util/zip/ZipUtils.java @@ -25,6 +25,8 @@ package java.util.zip; +import java.nio.Buffer; +import java.nio.ByteBuffer; import java.nio.file.attribute.FileTime; import java.security.AccessController; import java.security.PrivilegedAction; @@ -37,6 +39,9 @@ import java.util.concurrent.TimeUnit; import static java.util.zip.ZipConstants.ENDHDR; +import jdk.internal.misc.Unsafe; +import sun.nio.ch.DirectBuffer; + class ZipUtils { // used to adjust values between Windows and java epoch @@ -45,6 +50,8 @@ class ZipUtils { // used to indicate the corresponding windows time is not available public static final long WINDOWS_TIME_NOT_AVAILABLE = Long.MIN_VALUE; + static final ByteBuffer defaultBuf = ByteBuffer.allocateDirect(0); + /** * Converts Windows time (in microseconds, UTC/GMT) time to FileTime. */ @@ -281,4 +288,17 @@ class ZipUtils { AccessController.doPrivileged(pa); } } + + private static final Unsafe unsafe = Unsafe.getUnsafe(); + + private static final long byteBufferArrayOffset = unsafe.objectFieldOffset(ByteBuffer.class, "hb"); + private static final long byteBufferOffsetOffset = unsafe.objectFieldOffset(ByteBuffer.class, "offset"); + + static byte[] getBufferArray(ByteBuffer byteBuffer) { + return (byte[]) unsafe.getObject(byteBuffer, byteBufferArrayOffset); + } + + static int getBufferOffset(ByteBuffer byteBuffer) { + return unsafe.getInt(byteBuffer, byteBufferOffsetOffset); + } } diff --git a/src/java.base/share/native/libzip/Deflater.c b/src/java.base/share/native/libzip/Deflater.c index b666a16145a..b56df5ecc1b 100644 --- a/src/java.base/share/native/libzip/Deflater.c +++ b/src/java.base/share/native/libzip/Deflater.c @@ -38,34 +38,6 @@ #define DEF_MEM_LEVEL 8 -static jfieldID levelID; -static jfieldID strategyID; -static jfieldID setParamsID; -static jfieldID finishID; -static jfieldID finishedID; -static jfieldID bufID, offID, lenID; - -JNIEXPORT void JNICALL -Java_java_util_zip_Deflater_initIDs(JNIEnv *env, jclass cls) -{ - levelID = (*env)->GetFieldID(env, cls, "level", "I"); - CHECK_NULL(levelID); - strategyID = (*env)->GetFieldID(env, cls, "strategy", "I"); - CHECK_NULL(strategyID); - setParamsID = (*env)->GetFieldID(env, cls, "setParams", "Z"); - CHECK_NULL(setParamsID); - finishID = (*env)->GetFieldID(env, cls, "finish", "Z"); - CHECK_NULL(finishID); - finishedID = (*env)->GetFieldID(env, cls, "finished", "Z"); - CHECK_NULL(finishedID); - bufID = (*env)->GetFieldID(env, cls, "buf", "[B"); - CHECK_NULL(bufID); - offID = (*env)->GetFieldID(env, cls, "off", "I"); - CHECK_NULL(offID); - lenID = (*env)->GetFieldID(env, cls, "len", "I"); - CHECK_NULL(lenID); -} - JNIEXPORT jlong JNICALL Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level, jint strategy, jboolean nowrap) @@ -104,17 +76,9 @@ Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level, } } -JNIEXPORT void JNICALL -Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, - jarray b, jint off, jint len) +static void doSetDictionary(JNIEnv *env, jlong addr, jbyte *buf, jint len) { - Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - int res; - if (buf == 0) {/* out of memory */ - return; - } - res = deflateSetDictionary((z_stream *)jlong_to_ptr(addr), buf + off, len); - (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); + int res = deflateSetDictionary(jlong_to_ptr(addr), (Bytef *) buf, len); switch (res) { case Z_OK: break; @@ -127,94 +91,169 @@ Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, } } -JNIEXPORT jint JNICALL -Java_java_util_zip_Deflater_deflateBytes(JNIEnv *env, jobject this, jlong addr, - jarray b, jint off, jint len, jint flush) +JNIEXPORT void JNICALL +Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, + jbyteArray b, jint off, jint len) +{ + jbyte *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); + if (buf == NULL) /* out of memory */ + return; + doSetDictionary(env, addr, buf + off, len); + (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); +} + +JNIEXPORT void JNICALL +Java_java_util_zip_Deflater_setDictionaryBuffer(JNIEnv *env, jclass cls, jlong addr, + jlong bufferAddr, jint len) +{ + jbyte *buf = jlong_to_ptr(bufferAddr); + doSetDictionary(env, addr, buf, len); +} + +static jlong doDeflate(JNIEnv *env, jobject this, jlong addr, + jbyte *input, jint inputLen, + jbyte *output, jint outputLen, + jint flush, jint params) { z_stream *strm = jlong_to_ptr(addr); + jint inputUsed = 0, outputUsed = 0; - jarray this_buf = (*env)->GetObjectField(env, this, bufID); - jint this_off = (*env)->GetIntField(env, this, offID); - jint this_len = (*env)->GetIntField(env, this, lenID); - jbyte *in_buf; - jbyte *out_buf; - int res; - if ((*env)->GetBooleanField(env, this, setParamsID)) { - int level = (*env)->GetIntField(env, this, levelID); - int strategy = (*env)->GetIntField(env, this, strategyID); - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - // Throw OOME only when length is not zero - if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } + strm->next_in = (Bytef *) input; + strm->next_out = (Bytef *) output; + strm->avail_in = inputLen; + strm->avail_out = outputLen; + + int finished = 0; + int setParams = params & 1; - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - res = deflateParams(strm, level, strategy); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + if (setParams) { + int strategy = (params >> 1) & 3; + int level = params >> 3; + int res = deflateParams(strm, level, strategy); switch (res) { case Z_OK: - (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE); + setParams = 0; + /* fall through */ case Z_BUF_ERROR: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return (jint) (len - strm->avail_out); + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; default: JNU_ThrowInternalError(env, strm->msg); return 0; } } else { - jboolean finish = (*env)->GetBooleanField(env, this, finishID); - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - if (this_len != 0) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0) - JNU_ThrowOutOfMemoryError(env, 0); - - return 0; - } - - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - res = deflate(strm, finish ? Z_FINISH : flush); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + int res = deflate(strm, flush); switch (res) { case Z_STREAM_END: - (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); + finished = 1; /* fall through */ case Z_OK: case Z_BUF_ERROR: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return len - strm->avail_out; + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; default: JNU_ThrowInternalError(env, strm->msg); return 0; } } + return ((jlong)inputUsed) | (((jlong)outputUsed) << 31) | (((jlong)finished) << 62) | (((jlong)setParams) << 63); +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBytesBytes(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen, + jint flush, jint params) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doDeflate(env, this, addr, + input + inputOff, inputLen, + output + outputOff, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0); + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBytesBuffer(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jlong outputBuffer, jint outputLen, + jint flush, jint params) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = jlong_to_ptr(outputBuffer); + + jlong retVal = doDeflate(env, this, addr, + input + inputOff, inputLen, + output, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBufferBytes(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen, + jint flush, jint params) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doDeflate(env, this, addr, + input, inputLen, + output + outputOff, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBufferBuffer(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jlong outputBuffer, jint outputLen, + jint flush, jint params) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = jlong_to_ptr(outputBuffer); + + return doDeflate(env, this, addr, + input, inputLen, + output, outputLen, + flush, params); } JNIEXPORT jint JNICALL diff --git a/src/java.base/share/native/libzip/Inflater.c b/src/java.base/share/native/libzip/Inflater.c index 2e21d084b39..465e2534e47 100644 --- a/src/java.base/share/native/libzip/Inflater.c +++ b/src/java.base/share/native/libzip/Inflater.c @@ -42,23 +42,16 @@ #define ThrowDataFormatException(env, msg) \ JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg) -static jfieldID needDictID; -static jfieldID finishedID; -static jfieldID bufID, offID, lenID; +static jfieldID inputConsumedID; +static jfieldID outputConsumedID; JNIEXPORT void JNICALL Java_java_util_zip_Inflater_initIDs(JNIEnv *env, jclass cls) { - needDictID = (*env)->GetFieldID(env, cls, "needDict", "Z"); - CHECK_NULL(needDictID); - finishedID = (*env)->GetFieldID(env, cls, "finished", "Z"); - CHECK_NULL(finishedID); - bufID = (*env)->GetFieldID(env, cls, "buf", "[B"); - CHECK_NULL(bufID); - offID = (*env)->GetFieldID(env, cls, "off", "I"); - CHECK_NULL(offID); - lenID = (*env)->GetFieldID(env, cls, "len", "I"); - CHECK_NULL(lenID); + inputConsumedID = (*env)->GetFieldID(env, cls, "inputConsumed", "I"); + outputConsumedID = (*env)->GetFieldID(env, cls, "outputConsumed", "I"); + CHECK_NULL(inputConsumedID); + CHECK_NULL(outputConsumedID); } JNIEXPORT jlong JNICALL @@ -94,16 +87,9 @@ Java_java_util_zip_Inflater_init(JNIEnv *env, jclass cls, jboolean nowrap) } } -JNIEXPORT void JNICALL -Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, - jarray b, jint off, jint len) +static void doSetDictionary(JNIEnv *env, jlong addr, jbyte *buf, jint len) { - Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - int res; - if (buf == 0) /* out of memory */ - return; - res = inflateSetDictionary(jlong_to_ptr(addr), buf + off, len); - (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); + int res = inflateSetDictionary(jlong_to_ptr(addr), (Bytef *) buf, len); switch (res) { case Z_OK: break; @@ -117,68 +103,159 @@ Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, } } -JNIEXPORT jint JNICALL -Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr, - jarray b, jint off, jint len) +JNIEXPORT void JNICALL +Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, + jbyteArray b, jint off, jint len) +{ + jbyte *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); + if (buf == NULL) /* out of memory */ + return; + doSetDictionary(env, addr, buf + off, len); + (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); +} + +JNIEXPORT void JNICALL +Java_java_util_zip_Inflater_setDictionaryBuffer(JNIEnv *env, jclass cls, jlong addr, + jlong bufferAddr, jint len) +{ + jbyte *buf = jlong_to_ptr(bufferAddr); + doSetDictionary(env, addr, buf, len); +} + +static jlong doInflate(JNIEnv *env, jobject this, jlong addr, + jbyte *input, jint inputLen, + jbyte *output, jint outputLen) { z_stream *strm = jlong_to_ptr(addr); - jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID); - jint this_off = (*env)->GetIntField(env, this, offID); - jint this_len = (*env)->GetIntField(env, this, lenID); + jint inputUsed = 0, outputUsed = 0; - jbyte *in_buf; - jbyte *out_buf; - int ret; + strm->next_in = (Bytef *) input; + strm->next_out = (Bytef *) output; + strm->avail_in = inputLen; + strm->avail_out = outputLen; - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - ret = inflate(strm, Z_PARTIAL_FLUSH); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + int ret = inflate(strm, Z_PARTIAL_FLUSH); + int finished = 0; + int needDict = 0; switch (ret) { case Z_STREAM_END: - (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); + finished = 1; /* fall through */ case Z_OK: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return (jint) (len - strm->avail_out); + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; case Z_NEED_DICT: - (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE); + needDict = 1; /* Might have consumed some input here! */ - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return 0; + inputUsed = inputLen - strm->avail_in; + /* zlib is unclear about whether output may be produced */ + outputUsed = outputLen - strm->avail_out; + break; case Z_BUF_ERROR: - return 0; + break; case Z_DATA_ERROR: + inputUsed = inputLen - strm->avail_in; + (*env)->SetIntField(env, this, inputConsumedID, inputUsed); + outputUsed = outputLen - strm->avail_out; + (*env)->SetIntField(env, this, outputConsumedID, outputUsed); ThrowDataFormatException(env, strm->msg); - return 0; + break; case Z_MEM_ERROR: JNU_ThrowOutOfMemoryError(env, 0); - return 0; + break; default: JNU_ThrowInternalError(env, strm->msg); - return 0; + break; + } + return ((jlong)inputUsed) | (((jlong)outputUsed) << 31) | (((jlong)finished) << 62) | (((jlong)needDict) << 63); +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBytesBytes(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doInflate(env, this, addr, + input + inputOff, inputLen, + output + outputOff, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0); + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBytesBuffer(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jlong outputBuffer, jint outputLen) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = jlong_to_ptr(outputBuffer); + + jlong retVal = doInflate(env, this, addr, + input + inputOff, inputLen, + output, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBufferBytes(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; } + + jlong retVal = doInflate(env, this, addr, + input, inputLen, + output + outputOff, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBufferBuffer(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jlong outputBuffer, jint outputLen) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = jlong_to_ptr(outputBuffer); + + return doInflate(env, this, addr, + input, inputLen, + output, outputLen); } JNIEXPORT jint JNICALL diff --git a/test/jdk/java/util/zip/FlaterTest.java b/test/jdk/java/util/zip/FlaterTest.java index 7245440d033..b5aff0319b3 100644 --- a/test/jdk/java/util/zip/FlaterTest.java +++ b/test/jdk/java/util/zip/FlaterTest.java @@ -29,7 +29,6 @@ * @key randomness */ -import java.io.*; import java.nio.*; import java.util.*; import java.util.zip.*; @@ -41,35 +40,37 @@ import java.util.zip.*; */ public class FlaterTest extends Thread { private static final int DATA_LEN = 1024 * 128; - private static byte[] data; + + private static ByteBuffer dataDirect; + private static ByteBuffer dataHeap; // If true, print extra info. private static final boolean debug = false; // Set of Flater threads running. - private static Set flaters = - Collections.synchronizedSet(new HashSet()); + private static Set flaters = + Collections.synchronizedSet(new HashSet<>()); /** Fill in {@code data} with random values. */ static void createData() { - ByteBuffer bb = ByteBuffer.allocate(8); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - for (int i = 0; i < DATA_LEN; i++) { - bb.putDouble(0, Math.random()); - baos.write(bb.array(), 0, 8); + ByteBuffer bb = ByteBuffer.allocateDirect(DATA_LEN * 8); + for (int i = 0; i < DATA_LEN * 8; i += 8) { + bb.putDouble(i, Math.random()); } - data = baos.toByteArray(); - if (debug) System.out.println("data length is " + data.length); + dataDirect = bb; + final ByteBuffer hb = ByteBuffer.allocate(bb.capacity()); + hb.duplicate().put(bb.duplicate()); + dataHeap = hb; + if (debug) System.out.println("data length is " + bb.capacity()); } /** @return the length of the deflated {@code data}. */ - private static int getDeflatedLength() throws Throwable { - int rc = 0; + private static int getDeflatedLength() { Deflater deflater = new Deflater(); - deflater.setInput(data); + deflater.setInput(dataDirect.duplicate()); deflater.finish(); - byte[] out = new byte[data.length]; - rc = deflater.deflate(out); + byte[] out = new byte[dataDirect.capacity()]; + int rc = deflater.deflate(out); deflater.end(); if (debug) System.out.println("deflatedLength is " + rc); return rc; @@ -78,70 +79,98 @@ public class FlaterTest extends Thread { /** Compares given bytes with those in {@code data}. * @throws Exception if given bytes don't match {@code data}. */ - private static void validate(byte[] buf, int offset, int len) throws Exception { + private static void validate(ByteBuffer buf, int offset, int len) throws Exception { for (int i = 0; i < len; i++ ) { - if (buf[i] != data[offset+i]) { + if (buf.get(i) != dataDirect.get(offset+i)) { throw new Exception("mismatch at " + (offset + i)); } } } - public static void realMain(String[] args) throws Throwable { - createData(); + public static void realMain(String[] args) { int numThreads = args.length > 0 ? Integer.parseInt(args[0]) : 5; - new FlaterTest().go(numThreads); + createData(); + for (int srcMode = 0; srcMode <= 2; srcMode ++) { + for (int dstMode = 0; dstMode <= 2; dstMode ++) { + new FlaterTest().go(numThreads, srcMode, dstMode); + } + } } - private synchronized void go(int numThreads) throws Throwable { + private synchronized void go(int numThreads, int srcMode, int dstMode) { int deflatedLength = getDeflatedLength(); long time = System.currentTimeMillis(); for (int i = 0; i < numThreads; i++) { - Flater f = new Flater(deflatedLength); + Flater f = new Flater(deflatedLength, srcMode, dstMode); flaters.add(f); f.start(); } - while (flaters.size() != 0) { - try { - Thread.currentThread().sleep(10); - } catch (InterruptedException ex) { - unexpected(ex); + synchronized (flaters) { + while (flaters.size() != 0) { + try { + flaters.wait(); + } catch (InterruptedException ex) { + unexpected(ex); + } } } time = System.currentTimeMillis() - time; System.out.println("Time needed for " + numThreads - + " threads to deflate/inflate: " + time + " ms."); + + " threads to deflate/inflate: " + time + " ms (srcMode="+srcMode+",dstMode="+dstMode+")"); } /** Deflates and inflates data. */ static class Flater extends Thread { private final int deflatedLength; + private final int srcMode, dstMode; - private Flater(int length) { + private Flater(int length, int srcMode, int dstMode) { this.deflatedLength = length; + this.srcMode = srcMode; + this.dstMode = dstMode; } /** Deflates and inflates {@code data}. */ public void run() { if (debug) System.out.println(getName() + " starting run()"); try { - byte[] deflated = DeflateData(deflatedLength); + ByteBuffer deflated = DeflateData(deflatedLength); InflateData(deflated); } catch (Throwable t) { t.printStackTrace(); fail(getName() + " failed"); } finally { - flaters.remove(this); + synchronized (flaters) { + flaters.remove(this); + if (flaters.isEmpty()) { + flaters.notifyAll(); + } + } } } /** Returns a copy of {@code data} in deflated form. */ - private byte[] DeflateData(int length) throws Throwable { + private ByteBuffer DeflateData(int length) { Deflater deflater = new Deflater(); - deflater.setInput(data); + if (srcMode == 0) { + deflater.setInput(dataHeap.array()); + } else if (srcMode == 1) { + deflater.setInput(dataHeap.duplicate()); + } else { + assert srcMode == 2; + deflater.setInput(dataDirect.duplicate()); + } deflater.finish(); - byte[] out = new byte[length]; - deflater.deflate(out); + ByteBuffer out = dstMode == 2 ? ByteBuffer.allocateDirect(length) : ByteBuffer.allocate(length); + int deflated; + if (dstMode == 0) { + deflated = deflater.deflate(out.array(), 0, length); + out.position(deflated); + } else { + deflater.deflate(out); + } + out.flip(); return out; } @@ -149,14 +178,30 @@ public class FlaterTest extends Thread { * inflation. * @throws Exception if inflated bytes don't match {@code data}. */ - private void InflateData(byte[] bytes) throws Throwable { + private void InflateData(ByteBuffer bytes) throws Throwable { Inflater inflater = new Inflater(); - inflater.setInput(bytes, 0, bytes.length); + if (dstMode == 0) { + inflater.setInput(bytes.array(), 0, bytes.remaining()); + } else { + inflater.setInput(bytes); + } + if (inflater.getRemaining() == 0) { + throw new Exception("Nothing to inflate (bytes=" + bytes + ")"); + } int len = 1024 * 8; int offset = 0; + ByteBuffer buf = srcMode == 2 ? ByteBuffer.allocateDirect(len) : ByteBuffer.allocate(len); while (inflater.getRemaining() > 0) { - byte[] buf = new byte[len]; - int inflated = inflater.inflate(buf, 0, len); + buf.clear(); + int inflated; + if (srcMode == 0) { + inflated = inflater.inflate(buf.array(), 0, buf.remaining()); + } else { + inflated = inflater.inflate(buf); + } + if (inflated == 0) { + throw new Exception("Nothing inflated (dst=" + buf + ",offset=" + offset + ",rem=" + inflater.getRemaining() + ",srcMode="+srcMode+",dstMode="+dstMode+")"); + } validate(buf, offset, inflated); offset += inflated; } From david.lloyd at redhat.com Fri Mar 23 19:21:27 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Fri, 23 Mar 2018 14:21:27 -0500 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> Message-ID: On Fri, Mar 23, 2018 at 1:06 PM, Alan Bateman wrote: > Is there an up to date webrev on cr.openjdk.java.net that we can review? I'm an outside contributor so I don't have any easy way to prepare one; however, if you wish, you can look at the diff on my GitHub mirror here [1]. In case you're curious about the "version", it's the 16th local iteration for me, even though the updated patch I've just sent is only the 6th version sent to the list. [1] https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v16 -- - DML From magnus.ihse.bursie at oracle.com Fri Mar 23 20:36:29 2018 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Fri, 23 Mar 2018 21:36:29 +0100 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <96a6b8d6-d979-9cc9-6d51-7c6f0926bf97@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> <359e997c-6f49-218b-a1e6-81888135242b@oracle.com> <96a6b8d6-d979-9cc9-6d51-7c6f0926bf97@oracle.com> Message-ID: <2db2ec37-b561-3f93-623b-14ddbc615381@oracle.com> On 2018-03-23 19:01, Phil Race wrote: > > http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01/src/java.desktop/share/native/libmlib_image/mlib_image_proto.h.udiff.html > > > The variable definitions here are now misaligned. No, they are not. That's just an artifact of webrev, which filters out whitespace changes in the diff view. :-( To see the proper changes, including whitespace, you need to download the patch file. I've gone to great pains to mimick the existing style in the source codes I've made changes to. /Magnus > > ..and added 2d-dev since many of these native changes are in 2d. > > -phil. > > On 03/23/2018 10:33 AM, Phil Race wrote: >> There are a lot of changes in the desktop libraries. >> Doing mach5 tier1/2/3 testing is not nearly sufficient to cover those >> since >> only tier3 has any UI tests and it barely uses anything that's >> touched here. >> So since testing seems to be wise, then I think you should do a >> jtreg desktop group run on Linux & Windows. >> You can probably skip Mac since it is unaffected and I think Linux >> will cover Solaris here. >> You should also do some headless testing. >> >> It could take some time to review this properly and decide what >> changes are OK, >> what changes are something we should clean up later, and what changes >> are something >> that ought to be addressed now .. >> >> I think I'd be mainly concerned that something fails due to a missing >> symbol, or >> that for newly exported symbols if we ended up with duplicate symbols >> as a result. >> >> The results of a test run will add confidence here. >> >> BTW I don't think you are right that >> java.desktop:/libawt_headless: The following symbols are now also >> exported due to JNIEXPORT (they were previously >> .. >> ?X11SurfaceData_GetOps >> >> It looks to me like it was previously exported. >> >> >> -phil. >> >> >> >> On 03/23/2018 06:56 AM, Magnus Ihse Bursie wrote: >>> With modern compilers, we can use compiler directives (such as >>> _attribute__((visibility("default"))), or __declspec(dllexport)) to >>> control symbol visibility, directly in the source code. This has >>> historically not been present on all compilers, so we had to resort >>> to using mapfiles (also known as linker scripts). >>> >>> This is no longer the case. Now all compilers we use support symbol >>> visibility directives, in one form or another. We should start using >>> this. Since this has been the only way to control symbol visibility >>> on Windows, for most of the shared code, we already have proper >>> JNIEXPORT decorations in place. >>> >>> If we fix the remaining platform-specific files to have proper >>> JNIEXPORT tagging, then we can finally get rid of mapfiles. >>> >>> This fix removed mapfiles for all JDK libraries. It does not touch >>> hotspot libraries nor JDK executables; they will have to wait for a >>> future fix -- this was complex enough. This change will not have any >>> impact on macosx, since we do not use mapfiles there, but instead >>> export all symbols. (This is not a good idea, but I'll address that >>> separately.) This change will also have a minimal impact on Windows. >>> The only reason Windows is impacted at all, is that some changes >>> needed by Solaris and Linux were simpler to fix for all platforms. >>> >>> I have strived for this change to have no impact on the actual >>> generated code. Unfortunately, this was not possible to fully >>> achieve. I do not believe that these changes will have any actual >>> impact on the product, though. I will present the differences more >>> in detail further down. Those who are not interested can probably >>> skip that. >>> >>> The patch has passed tier1 testing and is currently running tier2 >>> and tier3. Since the running code is more or less (see caveat below) >>> unmodified, I don't expect any testing issues. >>> >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8200178 >>> WebRev: >>> http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01 >>> >>> Details on changes: >>> Most of the source code changes are (unsurprisingly) in java.base >>> and java.desktop. Remaining changes are in jdk.crypto.ucrypto, >>> jdk.hotspot.agent, jdk.jdi and jdk.jdwp.agent. >>> >>> Source code changes does almost to 100% consists in decorating an >>> exported function with JNIEXPORT. I have also followed the >>> long-standing convention of adding JNICALL. This is a no-op on >>> non-Windows platforms, so for most of the changes this is purely >>> cosmetic (and possibly adding in robustness, should the function >>> ever be used on Windows in the future). I have also followed the >>> stylistic convention of putting "JNIEXPORT JNICALL" on >>> a separate line. For some functions, however, this might cause a >>> change in calling convention on Windows. Since this can not apply to >>> exported functions on Windows (otherwise they would already have had >>> JNIEXPORT), I do not think this matters anything. >>> >>> A few libraries did not have a mapfile, on Linux and/or Solaris. >>> This actually meant that all symbols were exported. It is highly >>> unclear if this was known and intended by the original make rule >>> writer. I have emulated this by adding the flag >>> $(EXPORT_ALL_SYMBOLS) to these libraries. Hopefully, we can remove >>> this flag and fix proper exported symbols in the future. >>> >>> I have run the complete build using COMPARE_BUILD, and made a >>> thourough analysis of the differences for Linux and Solaris. All >>> native libraries have symbol differences, but most of them are >>> trivial and/or harmless. As a result, most libraries have disasm >>> differences as well, but these too seem trivial and harmless. The >>> differences in symbols that are common to all libraries include: >>> ?* Internal symbols such as __bss_start, _edata, _end and _fini are >>> now global. (They are imported as such from the compiler >>> libraries/archives, and we have no linker script to override this >>> behavior). >>> ?* The versioning tag SUNWprivate_1.1 is not included, and thus >>> neither the .gnu.version_d symbol. >>> ?* There are a few differences in the symbol and/or mangling of some >>> local functions. I'm not sure what's causing this, >>> but it's unlikely to have any effect on the product. >>> >>> Another common source for change in symbols is due to previous >>> platform differences. For instance, if we had "JNIEXPORT int JNICALL >>> do_foo() { ... }", but do_foo was not in the mapfile, the symbol was >>> exported on Windows but not on Linux and Solaris. (Presumable since >>> it was not needed there, even though it was compiled for those >>> platforms as well.) Now, with the mapfiles gone, do_foo() will be >>> exported on all platforms. And contrary, functions that are compiled >>> on all platforms, and were exported in mapfiles, but now have gotten >>> an JNIEXPORT decoration, will now be visible even on Windows. (This >>> accounts for half of the noticed symbol differences on Windows.) I >>> could have made the JNIEXPORT conditional on OS, but I didn't think >>> the mess in source code were worth the keeping of binary confidence >>> with the old build. >>> >>> A third common source for change in symbols is due to exported >>> functions "leaking" across library borders. For instance, some >>> functions in java.desktop is compiled in both libawt_xawt and >>> libawt_headless, but they were previously only included in the >>> mapfile for one of these libraries. Now, since the visibility is >>> determined by the source code itself, it gets exported in both >>> libraries. A variant of this is when a library depends on another >>> JDK library, and includes the header file from that other library, >>> which in turn declares a function as JNIEXPORT. This will cause the >>> including library to also export the function. This accounts for the >>> other half of the changes on Windows. A typical example of this is >>> that multiple libraries now re-export hotspot symbols from >>> libjvm.so, like jio_fprintf. (I have not listed the libjvm >>> re-exports below.) >>> >>> Note that? Java_java_io_FileOutputStream_close0 in >>> java.base/unix/native/libjava/FileOutputStream_md.c is no longer >>> exported, >>> and can probably be removed. >>> >>> Here is a detailed table showing and accounting for all the >>> remaining differences found on Linux and Solaris: >>> java.base/unix/native/libjava: Java_java_io_FileOutputStream_close0 >>> is now also exported on unix platforms due to JNIEXPORT. >>> >>> java.base/jspawnlauncher: On solaris, we also include >>> libjava/childproc.o, which >>> now exports less functions than it used to (it used to export all >>> functions, now it is compiled with visibility=hidden). >>> >>> java.base/java(w).exe: Is now also exporting the following symbols >>> due to added JNIEXPORT in libjli on Windows: >>> (Yes, executables can export symbols on Windows. Confusing, I know.) >>> ?JLI_AddArgsFromEnvVar >>> ?JLI_CmdToArgs >>> ?JLI_GetAppArgIndex >>> ?JLI_GetStdArgc >>> ?JLI_GetStdArgs >>> ?JLI_InitArgProcessing >>> ?JLI_Launch >>> ?JLI_List_add >>> ?JLI_List_new >>> ?JLI_ManifestIterate >>> ?JLI_MemAlloc >>> ?JLI_MemFree >>> ?JLI_PreprocessArg >>> ?JLI_ReportErrorMessage >>> ?JLI_ReportErrorMessageSys >>> ?JLI_ReportExceptionDescription >>> ?JLI_ReportMessage >>> ?JLI_SetTraceLauncher >>> ?JLI_StringDup >>> >>> java.desktop:/libawt_xawt: The following symbols are now also >>> exported on linux and solaris due to JNIEXPORT: >>> ?awt_DrawingSurface_FreeDrawingSurfaceInfo >>> ?awt_DrawingSurface_GetDrawingSurfaceInfo >>> ?awt_DrawingSurface_Lock >>> ?awt_DrawingSurface_Unlock >>> ?awt_GetColor >>> >>> The following symbols are now also exported on linux and solaris due >>> to JNIEXPORT (they were previously >>> ?exported only in libawt): >>> ?Java_sun_awt_DebugSettings_setCTracingOn__Z >>> ?Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2 >>> ?Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2I >>> ?Java_sun_awt_X11GraphicsConfig_getNumColors >>> >>> java.desktop:/libawt_headless: The following symbols are now also >>> exported due to JNIEXPORT (they were previously >>> ?exported only in libawt_xawt and/or libawt): >>> ?Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo >>> ?Java_sun_java2d_opengl_GLXGraphicsConfig_getOGLCapabilities >>> ?Java_sun_java2d_x11_X11PMBlitLoops_updateBitmask >>> ?Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable >>> ?X11SurfaceData_GetOps >>> >>> java.desktop/libawt: The following symbols are now also exported on >>> Windows, due to added >>> JNIEXPORT: >>> ?SurfaceData_InitOps >>> ?mul8table >>> ?div8table >>> ?doDrawPath >>> ?doFillPath >>> ?g_CMpDataID >>> ?initInverseGrayLut >>> ?make_dither_arrays >>> ?make_uns_ordered_dither_array >>> ?path2DFloatCoordsID >>> ?path2DNumTypesID >>> ?path2DTypesID >>> ?path2DWindingRuleID >>> ?sg2dStrokeHintID >>> ?std_img_oda_blue >>> ?std_img_oda_green >>> ?std_img_oda_red >>> ?std_odas_computed >>> ?sunHints_INTVAL_STROKE_PURE >>> >>> java.desktop/libawt on solaris: >>> A number of "#pragma weak" directives was previously overridden by >>> the mapfile. >>> Now these directives are respected, so these symbols are now weak >>> instead of local: >>> ?ByteGrayToIntArgbPreConvert_F >>> ?ByteGrayToIntArgbPreScaleConvert_F >>> ?IntArgbBmToFourByteAbgrPreScaleXparOver_F >>> ?IntArgbToIntRgbXorBlit_F >>> ?IntBgrToIntBgrAlphaMaskBlit_F >>> >>> java.desktop/libawt on solaris: These are now also exported due to >>> JNIEXPORT in libmlib_image. >>> ?j2d_mlib_ImageCreate >>> ?j2d_mlib_ImageCreateStruct >>> ?j2d_mlib_ImageDelete >>> >>> java.desktop/libawt on solaris: This is now also exported due to >>> JNIEXPORT: >>> ?GrPrim_CompGetXorColor >>> ?SurfaceData_GetOpsNoSetup >>> ?SurfaceData_IntersectBoundsXYWH >>> ?SurfaceData_SetOps >>> ?Transform_GetInfo >>> ?Transform_transform >>> >>> java.desktop/libsplashscreen: JNI_OnLoad is now exported on linux >>> and solaris due to JNIEXPORT. >>> libspashscreen also had JNIEXPORT (actually a pure >>> _declspec(dllexport)) but no JNICALL, which I added as >>> a part of converting to JNIEXPORT. The same goes for libmlib_image . >>> >>> jdk.sctp/libsctp: handleSocketError is now exported on linux and >>> solaris due to JNIEXPORT in libnio. >>> >>> java.instrument:/libinstrument: Agent_OnUnload is now also exported >>> on linux and solaris platforms due to JNIEXPORT. >>> JLI_ManifestIterate is now also exported on Windows, due to added >>> JNIEXPORT in libjli. >>> >>> jdk.management/libmanagement_ext: >>> Java_com_sun_management_internal_Flag_setDoubleValue is now also >>> exported on linux and solaris platforms due to JNIEXPORT. >>> >>> /Magnus >>> >>> >> > From magnus.ihse.bursie at oracle.com Fri Mar 23 21:08:35 2018 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Fri, 23 Mar 2018 22:08:35 +0100 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <359e997c-6f49-218b-a1e6-81888135242b@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> <359e997c-6f49-218b-a1e6-81888135242b@oracle.com> Message-ID: On 2018-03-23 18:33, Phil Race wrote: > There are a lot of changes in the desktop libraries. Well, yes and no. While there are multiple touched files, the resulting native shared libraries that are built have very minimal changes in them. (That's the view point from the build guy, you know :)) > Doing mach5 tier1/2/3 testing is not nearly sufficient to cover those > since > only tier3 has any UI tests and it barely uses anything that's touched > here. > So since testing seems to be wise, then I think you should do a > jtreg desktop group run on Linux & Windows. There is next to *no* difference for java.desktop on Windows. The only, very subtle, difference, is that awt.dll now exports 18 more functions (totalling 800, instead of 782). I can't even begin to imagine how anything could fail due to this additional exporting. Not even the disassembly of the machine code of awt.dll is different from before, not a single byte. So I don't buy it that I need to do extensive client testing on Windows. > You can probably skip Mac since it is unaffected and I think Linux > will cover Solaris here. > You should also do some headless testing. I agree that it seems prudent to do some Linux/Solaris testing, since changes there are more wide spread. Could you please point me to some guidance on how to run these tests? (You can do it off list) > It could take some time to review this properly and decide what > changes are OK, > what changes are something we should clean up later, and what changes > are something > that ought to be addressed now .. As I said, I am going to file follow-up bugs for suspicious handling of exported symbols. These follow-up bugs will be separated per component team, unlike this fix, which by necessity addresses all JDK libraries at once. So you will get plenty of time to consider ways of cleaning up any exports handling that you do not like. It would be a pity if this entire checkin was delayed since the client team could not accept the changes needed in client libraries. :-( And frankly, I believe the java.desktop libs needs some serious refactoring to get to grip with the exported symbols situation. The major cause of problems is, I believe, rooted in a non-optimal split of functionality between libawt, libawt_xawt and libawt_headless. This is not likely something that can be addressed in this change. > I think I'd be mainly concerned that something fails due to a missing > symbol, or > that for newly exported symbols if we ended up with duplicate symbols > as a result. Once again, I've run the COMPARE_BUILD script on this patch. Let me explain a bit more in detail what it does, since that might be known only to us in the build team. This script analyses the build result, the jmods, the lib*.so files, etc. The basic idea here is that a change in the build system, which does not produce a change in the build result, is "transparent" to the product. There is e.g. no reason to run any further testing, since we're in effect testing the same bits. For many changes in the build system, we hold this as the gold standard. For this particular change, to achieve this kind of fidelity would have come with a too high price in code complexity, so I have allowed certain small deviations. These are really minimal, and should in most cases be undetectable by the product. The changes in Linux and Solaris that have occured, is those that I listed in my review mail. Basically, for some libraries, additional symbols are exported. I could fix this, but only at the expense of more complex code. While it's a good thing to minimize the functions exported, a handful extra symbols is not a disaster. (We have more important issues to address in our native libraries.) For the AWT libraries, most of the duplicates are coming from the source code that are shared between libraries, in java.desktop/share/native/common. This means that the same function is compiled into -- and now also exported from -- multiple libraries. This is not a big deal. Even if we were to link with two libraries defining the same symbol, the dynamic linker will arbitrarily chose one of them, but since they are identical, it does not matter. (It's another thing if they implement different functions, as you noted yourself in the bugs about linking with awt_xawt vs doing a runtime linking to awt_headless). Also, I guarantee you that in no way are there missing symbols in the refactored build. I've checked, double-checked and triple-checked that. > The results of a test run will add confidence here. > > BTW I don't think you are right that > java.desktop:/libawt_headless: The following symbols are now also > exported due to JNIEXPORT (they were previously > .. > ?X11SurfaceData_GetOps > > It looks to me like it was previously exported. You are correct, it was previously exported in libawt_headless. I meant that it is now also exported for libawt_xawt due to the JNIEXPORT. Sorry for mixing this up. /Magnus > > > -phil. > > > > On 03/23/2018 06:56 AM, Magnus Ihse Bursie wrote: >> With modern compilers, we can use compiler directives (such as >> _attribute__((visibility("default"))), or __declspec(dllexport)) to >> control symbol visibility, directly in the source code. This has >> historically not been present on all compilers, so we had to resort >> to using mapfiles (also known as linker scripts). >> >> This is no longer the case. Now all compilers we use support symbol >> visibility directives, in one form or another. We should start using >> this. Since this has been the only way to control symbol visibility >> on Windows, for most of the shared code, we already have proper >> JNIEXPORT decorations in place. >> >> If we fix the remaining platform-specific files to have proper >> JNIEXPORT tagging, then we can finally get rid of mapfiles. >> >> This fix removed mapfiles for all JDK libraries. It does not touch >> hotspot libraries nor JDK executables; they will have to wait for a >> future fix -- this was complex enough. This change will not have any >> impact on macosx, since we do not use mapfiles there, but instead >> export all symbols. (This is not a good idea, but I'll address that >> separately.) This change will also have a minimal impact on Windows. >> The only reason Windows is impacted at all, is that some changes >> needed by Solaris and Linux were simpler to fix for all platforms. >> >> I have strived for this change to have no impact on the actual >> generated code. Unfortunately, this was not possible to fully >> achieve. I do not believe that these changes will have any actual >> impact on the product, though. I will present the differences more in >> detail further down. Those who are not interested can probably skip >> that. >> >> The patch has passed tier1 testing and is currently running tier2 and >> tier3. Since the running code is more or less (see caveat below) >> unmodified, I don't expect any testing issues. >> >> Bug: https://bugs.openjdk.java.net/browse/JDK-8200178 >> WebRev: >> http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01 >> >> Details on changes: >> Most of the source code changes are (unsurprisingly) in java.base and >> java.desktop. Remaining changes are in jdk.crypto.ucrypto, >> jdk.hotspot.agent, jdk.jdi and jdk.jdwp.agent. >> >> Source code changes does almost to 100% consists in decorating an >> exported function with JNIEXPORT. I have also followed the >> long-standing convention of adding JNICALL. This is a no-op on >> non-Windows platforms, so for most of the changes this is purely >> cosmetic (and possibly adding in robustness, should the function ever >> be used on Windows in the future). I have also followed the stylistic >> convention of putting "JNIEXPORT JNICALL" on a separate >> line. For some functions, however, this might cause a change in >> calling convention on Windows. Since this can not apply to exported >> functions on Windows (otherwise they would already have had >> JNIEXPORT), I do not think this matters anything. >> >> A few libraries did not have a mapfile, on Linux and/or Solaris. This >> actually meant that all symbols were exported. It is highly unclear >> if this was known and intended by the original make rule writer. I >> have emulated this by adding the flag $(EXPORT_ALL_SYMBOLS) to these >> libraries. Hopefully, we can remove this flag and fix proper exported >> symbols in the future. >> >> I have run the complete build using COMPARE_BUILD, and made a >> thourough analysis of the differences for Linux and Solaris. All >> native libraries have symbol differences, but most of them are >> trivial and/or harmless. As a result, most libraries have disasm >> differences as well, but these too seem trivial and harmless. The >> differences in symbols that are common to all libraries include: >> ?* Internal symbols such as __bss_start, _edata, _end and _fini are >> now global. (They are imported as such from the compiler >> libraries/archives, and we have no linker script to override this >> behavior). >> ?* The versioning tag SUNWprivate_1.1 is not included, and thus >> neither the .gnu.version_d symbol. >> ?* There are a few differences in the symbol and/or mangling of some >> local functions. I'm not sure what's causing this, >> but it's unlikely to have any effect on the product. >> >> Another common source for change in symbols is due to previous >> platform differences. For instance, if we had "JNIEXPORT int JNICALL >> do_foo() { ... }", but do_foo was not in the mapfile, the symbol was >> exported on Windows but not on Linux and Solaris. (Presumable since >> it was not needed there, even though it was compiled for those >> platforms as well.) Now, with the mapfiles gone, do_foo() will be >> exported on all platforms. And contrary, functions that are compiled >> on all platforms, and were exported in mapfiles, but now have gotten >> an JNIEXPORT decoration, will now be visible even on Windows. (This >> accounts for half of the noticed symbol differences on Windows.) I >> could have made the JNIEXPORT conditional on OS, but I didn't think >> the mess in source code were worth the keeping of binary confidence >> with the old build. >> >> A third common source for change in symbols is due to exported >> functions "leaking" across library borders. For instance, some >> functions in java.desktop is compiled in both libawt_xawt and >> libawt_headless, but they were previously only included in the >> mapfile for one of these libraries. Now, since the visibility is >> determined by the source code itself, it gets exported in both >> libraries. A variant of this is when a library depends on another JDK >> library, and includes the header file from that other library, which >> in turn declares a function as JNIEXPORT. This will cause the >> including library to also export the function. This accounts for the >> other half of the changes on Windows. A typical example of this is >> that multiple libraries now re-export hotspot symbols from libjvm.so, >> like jio_fprintf. (I have not listed the libjvm re-exports below.) >> >> Note that? Java_java_io_FileOutputStream_close0 in >> java.base/unix/native/libjava/FileOutputStream_md.c is no longer >> exported, >> and can probably be removed. >> >> Here is a detailed table showing and accounting for all the remaining >> differences found on Linux and Solaris: >> java.base/unix/native/libjava: Java_java_io_FileOutputStream_close0 >> is now also exported on unix platforms due to JNIEXPORT. >> >> java.base/jspawnlauncher: On solaris, we also include >> libjava/childproc.o, which >> now exports less functions than it used to (it used to export all >> functions, now it is compiled with visibility=hidden). >> >> java.base/java(w).exe: Is now also exporting the following symbols >> due to added JNIEXPORT in libjli on Windows: >> (Yes, executables can export symbols on Windows. Confusing, I know.) >> ?JLI_AddArgsFromEnvVar >> ?JLI_CmdToArgs >> ?JLI_GetAppArgIndex >> ?JLI_GetStdArgc >> ?JLI_GetStdArgs >> ?JLI_InitArgProcessing >> ?JLI_Launch >> ?JLI_List_add >> ?JLI_List_new >> ?JLI_ManifestIterate >> ?JLI_MemAlloc >> ?JLI_MemFree >> ?JLI_PreprocessArg >> ?JLI_ReportErrorMessage >> ?JLI_ReportErrorMessageSys >> ?JLI_ReportExceptionDescription >> ?JLI_ReportMessage >> ?JLI_SetTraceLauncher >> ?JLI_StringDup >> >> java.desktop:/libawt_xawt: The following symbols are now also >> exported on linux and solaris due to JNIEXPORT: >> ?awt_DrawingSurface_FreeDrawingSurfaceInfo >> ?awt_DrawingSurface_GetDrawingSurfaceInfo >> ?awt_DrawingSurface_Lock >> ?awt_DrawingSurface_Unlock >> ?awt_GetColor >> >> The following symbols are now also exported on linux and solaris due >> to JNIEXPORT (they were previously >> ?exported only in libawt): >> ?Java_sun_awt_DebugSettings_setCTracingOn__Z >> ?Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2 >> ?Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2I >> ?Java_sun_awt_X11GraphicsConfig_getNumColors >> >> java.desktop:/libawt_headless: The following symbols are now also >> exported due to JNIEXPORT (they were previously >> ?exported only in libawt_xawt and/or libawt): >> ?Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo >> ?Java_sun_java2d_opengl_GLXGraphicsConfig_getOGLCapabilities >> ?Java_sun_java2d_x11_X11PMBlitLoops_updateBitmask >> ?Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable >> ?X11SurfaceData_GetOps >> >> java.desktop/libawt: The following symbols are now also exported on >> Windows, due to added >> JNIEXPORT: >> ?SurfaceData_InitOps >> ?mul8table >> ?div8table >> ?doDrawPath >> ?doFillPath >> ?g_CMpDataID >> ?initInverseGrayLut >> ?make_dither_arrays >> ?make_uns_ordered_dither_array >> ?path2DFloatCoordsID >> ?path2DNumTypesID >> ?path2DTypesID >> ?path2DWindingRuleID >> ?sg2dStrokeHintID >> ?std_img_oda_blue >> ?std_img_oda_green >> ?std_img_oda_red >> ?std_odas_computed >> ?sunHints_INTVAL_STROKE_PURE >> >> java.desktop/libawt on solaris: >> A number of "#pragma weak" directives was previously overridden by >> the mapfile. >> Now these directives are respected, so these symbols are now weak >> instead of local: >> ?ByteGrayToIntArgbPreConvert_F >> ?ByteGrayToIntArgbPreScaleConvert_F >> ?IntArgbBmToFourByteAbgrPreScaleXparOver_F >> ?IntArgbToIntRgbXorBlit_F >> ?IntBgrToIntBgrAlphaMaskBlit_F >> >> java.desktop/libawt on solaris: These are now also exported due to >> JNIEXPORT in libmlib_image. >> ?j2d_mlib_ImageCreate >> ?j2d_mlib_ImageCreateStruct >> ?j2d_mlib_ImageDelete >> >> java.desktop/libawt on solaris: This is now also exported due to >> JNIEXPORT: >> ?GrPrim_CompGetXorColor >> ?SurfaceData_GetOpsNoSetup >> ?SurfaceData_IntersectBoundsXYWH >> ?SurfaceData_SetOps >> ?Transform_GetInfo >> ?Transform_transform >> >> java.desktop/libsplashscreen: JNI_OnLoad is now exported on linux and >> solaris due to JNIEXPORT. >> libspashscreen also had JNIEXPORT (actually a pure >> _declspec(dllexport)) but no JNICALL, which I added as >> a part of converting to JNIEXPORT. The same goes for libmlib_image . >> >> jdk.sctp/libsctp: handleSocketError is now exported on linux and >> solaris due to JNIEXPORT in libnio. >> >> java.instrument:/libinstrument: Agent_OnUnload is now also exported >> on linux and solaris platforms due to JNIEXPORT. >> JLI_ManifestIterate is now also exported on Windows, due to added >> JNIEXPORT in libjli. >> >> jdk.management/libmanagement_ext: >> Java_com_sun_management_internal_Flag_setDoubleValue is now also >> exported on linux and solaris platforms due to JNIEXPORT. >> >> /Magnus >> >> > From magnus.ihse.bursie at oracle.com Fri Mar 23 21:31:36 2018 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Fri, 23 Mar 2018 22:31:36 +0100 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> <86488d2c-61e3-e489-d9fc-976178c35775@oracle.com> <2329dea1-a75e-bb70-95a6-242a93006c6d@oracle.com> Message-ID: <278836b5-b49b-2409-f1b5-e05fdc0d2b30@oracle.com> On 2018-03-23 18:24, Volker Simonis wrote: > Hi Magnus, > > thanks for addressing this long standing issue! I haven't looked at > the changes, but just want to share some general and historical notes: > > - Compiling with "-fvisibility=hidden" which hides all symbols expect > the ones explicitly exported with > "__attribute__((visibility("default")))" has been requested by SAP > back in 2007 even before we had OpenJDK (see "Use -fvisibility=hidden > for gcc compiles" https://bugs.openjdk.java.net/browse/JDK-6588413) > and finally pushed into the OpenJKD around 2010. > - "-fvisibility=hidden" gave us performance improvements of about 5% > (JBB2005) and 2% (JVM98) on Linux/IA64 and 1,5% (JBB2005) and 0,5% > (JVM98) on Linux/PPC64 because the compiler could use faster calls for > non exported symbols. This improvement was only very small on x86 > tough. That's a nice side effect! Although my main purpose here is maintainability, gaining performance is nothing I say no to. :) > - "-fvisibility=hidden"/"__attribute__((visibility("default")))" > applies BEFORE using the map files in the linking step (i.e. hidden > symbols can't be exported any more even if mentioned in the map file) > - because of the performance improvements we got by using > "-fvisibility=hidden" it was worth while using it even though we had > the mapfiles at the end of the process. > > Then we had several mail threads (which you probably remember because > you were involved :) where we discussed to either remove the map files > completely or instead generate them automatically during the build: > > http://mail.openjdk.java.net/pipermail/hotspot-dev/2014-February/thread.html#12412 > http://mail.openjdk.java.net/pipermail/hotspot-dev/2014-February/thread.html#12628 > > The main arguments against removing the map files at that time were: > > 1. the danger to re-export all symbols of statically linked libraries > (notably libstdc++ at that time) > 2. loosing exports of compiler generated symbols like vtables which > are required by the Serviceability Agent > > Point 1 is not a problem today, because I don't think we do any static > linking any more. If we still do it under some circumstances, this > problem should be re-evaluated. Well, we do static linking with libstdc++ on linux, in certain circumstances. See "--with-stdc++lib=,,". Fortunately, this is not a problem. The linker can be told not to include symbols from statically linked libraries, which is exactly what I do with LDFLAGS_JDKLIB += -Wl,--exclude-libs,ALL. The corresponding feature does not exist for the solstudio linker, but fortunately we do not use statically linked libraries there. > Point 2 is only relevant for HotSpot. But because of "8034065: GCC 4.3 > and later doesn't export vtable symbols any more which seem to be > needed by SA" (https://bugs.openjdk.java.net/browse/JDK-8034065), > exporting such symbols trough a map files doesn't work any more > anyway. So this isn't a problem either. In any case, that's a question for another day. :) There were reasons I left Hotspot out of this fix, and the question about the SA agent is one of them. :) As you say, I think they do not apply anymore, but I'll return to consider Hotspot later on. > So to cut a long story short - I think the time is ripe to get rid of > the map files. Thumbs up from me (meant as moral support, not as a > concrete review :) Thanks for the kind words! /Magnus > > Regards, > Volker > > On Fri, Mar 23, 2018 at 5:05 PM, mandy chung wrote: >> This is a very good change and no more mapfile to maintain!! >> >> Please do file JBS issues for the component teams to clean up their exports. >> >> Mandy >> >> >> On 3/23/18 7:30 AM, Erik Joelsson wrote: >>> I have looked at the build changes and they look good. >>> >>> Will you file followups for each component team to look over their >>> exported symbols, at least for the libraries with $(EXPORT_ALL_SYMBOLS)? It >>> sure looks like there is some technical debt laying around here. >>> >>> /Erik >>> >>> >>> On 2018-03-23 06:56, Magnus Ihse Bursie wrote: >>>> With modern compilers, we can use compiler directives (such as >>>> _attribute__((visibility("default"))), or __declspec(dllexport)) to control >>>> symbol visibility, directly in the source code. This has historically not >>>> been present on all compilers, so we had to resort to using mapfiles (also >>>> known as linker scripts). >>>> >>>> This is no longer the case. Now all compilers we use support symbol >>>> visibility directives, in one form or another. We should start using this. >>>> Since this has been the only way to control symbol visibility on Windows, >>>> for most of the shared code, we already have proper JNIEXPORT decorations in >>>> place. >>>> >>>> If we fix the remaining platform-specific files to have proper JNIEXPORT >>>> tagging, then we can finally get rid of mapfiles. >>>> >>>> This fix removed mapfiles for all JDK libraries. It does not touch >>>> hotspot libraries nor JDK executables; they will have to wait for a future >>>> fix -- this was complex enough. This change will not have any impact on >>>> macosx, since we do not use mapfiles there, but instead export all symbols. >>>> (This is not a good idea, but I'll address that separately.) This change >>>> will also have a minimal impact on Windows. The only reason Windows is >>>> impacted at all, is that some changes needed by Solaris and Linux were >>>> simpler to fix for all platforms. >>>> >>>> I have strived for this change to have no impact on the actual generated >>>> code. Unfortunately, this was not possible to fully achieve. I do not >>>> believe that these changes will have any actual impact on the product, >>>> though. I will present the differences more in detail further down. Those >>>> who are not interested can probably skip that. >>>> >>>> The patch has passed tier1 testing and is currently running tier2 and >>>> tier3. Since the running code is more or less (see caveat below) unmodified, >>>> I don't expect any testing issues. >>>> >>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8200178 >>>> WebRev: >>>> http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01 >>>> >>>> Details on changes: >>>> Most of the source code changes are (unsurprisingly) in java.base and >>>> java.desktop. Remaining changes are in jdk.crypto.ucrypto, >>>> jdk.hotspot.agent, jdk.jdi and jdk.jdwp.agent. >>>> >>>> Source code changes does almost to 100% consists in decorating an >>>> exported function with JNIEXPORT. I have also followed the long-standing >>>> convention of adding JNICALL. This is a no-op on non-Windows platforms, so >>>> for most of the changes this is purely cosmetic (and possibly adding in >>>> robustness, should the function ever be used on Windows in the future). I >>>> have also followed the stylistic convention of putting "JNIEXPORT >>> type> JNICALL" on a separate line. For some functions, however, this might >>>> cause a change in calling convention on Windows. Since this can not apply to >>>> exported functions on Windows (otherwise they would already have had >>>> JNIEXPORT), I do not think this matters anything. >>>> >>>> A few libraries did not have a mapfile, on Linux and/or Solaris. This >>>> actually meant that all symbols were exported. It is highly unclear if this >>>> was known and intended by the original make rule writer. I have emulated >>>> this by adding the flag $(EXPORT_ALL_SYMBOLS) to these libraries. Hopefully, >>>> we can remove this flag and fix proper exported symbols in the future. >>>> >>>> I have run the complete build using COMPARE_BUILD, and made a thourough >>>> analysis of the differences for Linux and Solaris. All native libraries have >>>> symbol differences, but most of them are trivial and/or harmless. As a >>>> result, most libraries have disasm differences as well, but these too seem >>>> trivial and harmless. The differences in symbols that are common to all >>>> libraries include: >>>> * Internal symbols such as __bss_start, _edata, _end and _fini are now >>>> global. (They are imported as such from the compiler libraries/archives, and >>>> we have no linker script to override this behavior). >>>> * The versioning tag SUNWprivate_1.1 is not included, and thus neither >>>> the .gnu.version_d symbol. >>>> * There are a few differences in the symbol and/or mangling of some >>>> local functions. I'm not sure what's causing this, >>>> but it's unlikely to have any effect on the product. >>>> >>>> Another common source for change in symbols is due to previous platform >>>> differences. For instance, if we had "JNIEXPORT int JNICALL do_foo() { ... >>>> }", but do_foo was not in the mapfile, the symbol was exported on Windows >>>> but not on Linux and Solaris. (Presumable since it was not needed there, >>>> even though it was compiled for those platforms as well.) Now, with the >>>> mapfiles gone, do_foo() will be exported on all platforms. And contrary, >>>> functions that are compiled on all platforms, and were exported in mapfiles, >>>> but now have gotten an JNIEXPORT decoration, will now be visible even on >>>> Windows. (This accounts for half of the noticed symbol differences on >>>> Windows.) I could have made the JNIEXPORT conditional on OS, but I didn't >>>> think the mess in source code were worth the keeping of binary confidence >>>> with the old build. >>>> >>>> A third common source for change in symbols is due to exported functions >>>> "leaking" across library borders. For instance, some functions in >>>> java.desktop is compiled in both libawt_xawt and libawt_headless, but they >>>> were previously only included in the mapfile for one of these libraries. >>>> Now, since the visibility is determined by the source code itself, it gets >>>> exported in both libraries. A variant of this is when a library depends on >>>> another JDK library, and includes the header file from that other library, >>>> which in turn declares a function as JNIEXPORT. This will cause the >>>> including library to also export the function. This accounts for the other >>>> half of the changes on Windows. A typical example of this is that multiple >>>> libraries now re-export hotspot symbols from libjvm.so, like jio_fprintf. (I >>>> have not listed the libjvm re-exports below.) >>>> >>>> Note that Java_java_io_FileOutputStream_close0 in >>>> java.base/unix/native/libjava/FileOutputStream_md.c is no longer exported, >>>> and can probably be removed. >>>> >>>> Here is a detailed table showing and accounting for all the remaining >>>> differences found on Linux and Solaris: >>>> java.base/unix/native/libjava: Java_java_io_FileOutputStream_close0 is >>>> now also exported on unix platforms due to JNIEXPORT. >>>> >>>> java.base/jspawnlauncher: On solaris, we also include >>>> libjava/childproc.o, which >>>> now exports less functions than it used to (it used to export all >>>> functions, now it is compiled with visibility=hidden). >>>> >>>> java.base/java(w).exe: Is now also exporting the following symbols due to >>>> added JNIEXPORT in libjli on Windows: >>>> (Yes, executables can export symbols on Windows. Confusing, I know.) >>>> JLI_AddArgsFromEnvVar >>>> JLI_CmdToArgs >>>> JLI_GetAppArgIndex >>>> JLI_GetStdArgc >>>> JLI_GetStdArgs >>>> JLI_InitArgProcessing >>>> JLI_Launch >>>> JLI_List_add >>>> JLI_List_new >>>> JLI_ManifestIterate >>>> JLI_MemAlloc >>>> JLI_MemFree >>>> JLI_PreprocessArg >>>> JLI_ReportErrorMessage >>>> JLI_ReportErrorMessageSys >>>> JLI_ReportExceptionDescription >>>> JLI_ReportMessage >>>> JLI_SetTraceLauncher >>>> JLI_StringDup >>>> >>>> java.desktop:/libawt_xawt: The following symbols are now also exported on >>>> linux and solaris due to JNIEXPORT: >>>> awt_DrawingSurface_FreeDrawingSurfaceInfo >>>> awt_DrawingSurface_GetDrawingSurfaceInfo >>>> awt_DrawingSurface_Lock >>>> awt_DrawingSurface_Unlock >>>> awt_GetColor >>>> >>>> The following symbols are now also exported on linux and solaris due to >>>> JNIEXPORT (they were previously >>>> exported only in libawt): >>>> Java_sun_awt_DebugSettings_setCTracingOn__Z >>>> Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2 >>>> Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2I >>>> Java_sun_awt_X11GraphicsConfig_getNumColors >>>> >>>> java.desktop:/libawt_headless: The following symbols are now also >>>> exported due to JNIEXPORT (they were previously >>>> exported only in libawt_xawt and/or libawt): >>>> Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo >>>> Java_sun_java2d_opengl_GLXGraphicsConfig_getOGLCapabilities >>>> Java_sun_java2d_x11_X11PMBlitLoops_updateBitmask >>>> Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable >>>> X11SurfaceData_GetOps >>>> >>>> java.desktop/libawt: The following symbols are now also exported on >>>> Windows, due to added >>>> JNIEXPORT: >>>> SurfaceData_InitOps >>>> mul8table >>>> div8table >>>> doDrawPath >>>> doFillPath >>>> g_CMpDataID >>>> initInverseGrayLut >>>> make_dither_arrays >>>> make_uns_ordered_dither_array >>>> path2DFloatCoordsID >>>> path2DNumTypesID >>>> path2DTypesID >>>> path2DWindingRuleID >>>> sg2dStrokeHintID >>>> std_img_oda_blue >>>> std_img_oda_green >>>> std_img_oda_red >>>> std_odas_computed >>>> sunHints_INTVAL_STROKE_PURE >>>> >>>> java.desktop/libawt on solaris: >>>> A number of "#pragma weak" directives was previously overridden by the >>>> mapfile. >>>> Now these directives are respected, so these symbols are now weak instead >>>> of local: >>>> ByteGrayToIntArgbPreConvert_F >>>> ByteGrayToIntArgbPreScaleConvert_F >>>> IntArgbBmToFourByteAbgrPreScaleXparOver_F >>>> IntArgbToIntRgbXorBlit_F >>>> IntBgrToIntBgrAlphaMaskBlit_F >>>> >>>> java.desktop/libawt on solaris: These are now also exported due to >>>> JNIEXPORT in libmlib_image. >>>> j2d_mlib_ImageCreate >>>> j2d_mlib_ImageCreateStruct >>>> j2d_mlib_ImageDelete >>>> >>>> java.desktop/libawt on solaris: This is now also exported due to >>>> JNIEXPORT: >>>> GrPrim_CompGetXorColor >>>> SurfaceData_GetOpsNoSetup >>>> SurfaceData_IntersectBoundsXYWH >>>> SurfaceData_SetOps >>>> Transform_GetInfo >>>> Transform_transform >>>> >>>> java.desktop/libsplashscreen: JNI_OnLoad is now exported on linux and >>>> solaris due to JNIEXPORT. >>>> libspashscreen also had JNIEXPORT (actually a pure _declspec(dllexport)) >>>> but no JNICALL, which I added as >>>> a part of converting to JNIEXPORT. The same goes for libmlib_image . >>>> >>>> jdk.sctp/libsctp: handleSocketError is now exported on linux and solaris >>>> due to JNIEXPORT in libnio. >>>> >>>> java.instrument:/libinstrument: Agent_OnUnload is now also exported on >>>> linux and solaris platforms due to JNIEXPORT. >>>> JLI_ManifestIterate is now also exported on Windows, due to added >>>> JNIEXPORT in libjli. >>>> >>>> jdk.management/libmanagement_ext: >>>> Java_com_sun_management_internal_Flag_setDoubleValue is now also exported on >>>> linux and solaris platforms due to JNIEXPORT. >>>> >>>> /Magnus >>>> >>>> From magnus.ihse.bursie at oracle.com Fri Mar 23 22:03:59 2018 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Fri, 23 Mar 2018 23:03:59 +0100 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <2329dea1-a75e-bb70-95a6-242a93006c6d@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> <86488d2c-61e3-e489-d9fc-976178c35775@oracle.com> <2329dea1-a75e-bb70-95a6-242a93006c6d@oracle.com> Message-ID: <32db4add-8a59-03db-0074-e7df0aed14b8@oracle.com> On 2018-03-23 17:05, mandy chung wrote: > This is a very good change and no more mapfile to maintain!! Thank you! > > Please do file JBS issues for the component teams to clean up their > exports. I have now filed: https://bugs.openjdk.java.net/browse/JDK-8200191 -- for java.base https://bugs.openjdk.java.net/browse/JDK-8200192 -- for java.desktop https://bugs.openjdk.java.net/browse/JDK-8200193 -- for jdk.security.auth /Magnus > > Mandy > > On 3/23/18 7:30 AM, Erik Joelsson wrote: >> I have looked at the build changes and they look good. >> >> Will you file followups for each component team to look over their >> exported symbols, at least for the libraries with >> $(EXPORT_ALL_SYMBOLS)? It sure looks like there is some technical >> debt laying around here. >> >> /Erik >> >> >> On 2018-03-23 06:56, Magnus Ihse Bursie wrote: >>> With modern compilers, we can use compiler directives (such as >>> _attribute__((visibility("default"))), or __declspec(dllexport)) to >>> control symbol visibility, directly in the source code. This has >>> historically not been present on all compilers, so we had to resort >>> to using mapfiles (also known as linker scripts). >>> >>> This is no longer the case. Now all compilers we use support symbol >>> visibility directives, in one form or another. We should start using >>> this. Since this has been the only way to control symbol visibility >>> on Windows, for most of the shared code, we already have proper >>> JNIEXPORT decorations in place. >>> >>> If we fix the remaining platform-specific files to have proper >>> JNIEXPORT tagging, then we can finally get rid of mapfiles. >>> >>> This fix removed mapfiles for all JDK libraries. It does not touch >>> hotspot libraries nor JDK executables; they will have to wait for a >>> future fix -- this was complex enough. This change will not have any >>> impact on macosx, since we do not use mapfiles there, but instead >>> export all symbols. (This is not a good idea, but I'll address that >>> separately.) This change will also have a minimal impact on Windows. >>> The only reason Windows is impacted at all, is that some changes >>> needed by Solaris and Linux were simpler to fix for all platforms. >>> >>> I have strived for this change to have no impact on the actual >>> generated code. Unfortunately, this was not possible to fully >>> achieve. I do not believe that these changes will have any actual >>> impact on the product, though. I will present the differences more >>> in detail further down. Those who are not interested can probably >>> skip that. >>> >>> The patch has passed tier1 testing and is currently running tier2 >>> and tier3. Since the running code is more or less (see caveat below) >>> unmodified, I don't expect any testing issues. >>> >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8200178 >>> WebRev: >>> http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01 >>> >>> Details on changes: >>> Most of the source code changes are (unsurprisingly) in java.base >>> and java.desktop. Remaining changes are in jdk.crypto.ucrypto, >>> jdk.hotspot.agent, jdk.jdi and jdk.jdwp.agent. >>> >>> Source code changes does almost to 100% consists in decorating an >>> exported function with JNIEXPORT. I have also followed the >>> long-standing convention of adding JNICALL. This is a no-op on >>> non-Windows platforms, so for most of the changes this is purely >>> cosmetic (and possibly adding in robustness, should the function >>> ever be used on Windows in the future). I have also followed the >>> stylistic convention of putting "JNIEXPORT JNICALL" on >>> a separate line. For some functions, however, this might cause a >>> change in calling convention on Windows. Since this can not apply to >>> exported functions on Windows (otherwise they would already have had >>> JNIEXPORT), I do not think this matters anything. >>> >>> A few libraries did not have a mapfile, on Linux and/or Solaris. >>> This actually meant that all symbols were exported. It is highly >>> unclear if this was known and intended by the original make rule >>> writer. I have emulated this by adding the flag >>> $(EXPORT_ALL_SYMBOLS) to these libraries. Hopefully, we can remove >>> this flag and fix proper exported symbols in the future. >>> >>> I have run the complete build using COMPARE_BUILD, and made a >>> thourough analysis of the differences for Linux and Solaris. All >>> native libraries have symbol differences, but most of them are >>> trivial and/or harmless. As a result, most libraries have disasm >>> differences as well, but these too seem trivial and harmless. The >>> differences in symbols that are common to all libraries include: >>> ?* Internal symbols such as __bss_start, _edata, _end and _fini are >>> now global. (They are imported as such from the compiler >>> libraries/archives, and we have no linker script to override this >>> behavior). >>> ?* The versioning tag SUNWprivate_1.1 is not included, and thus >>> neither the .gnu.version_d symbol. >>> ?* There are a few differences in the symbol and/or mangling of some >>> local functions. I'm not sure what's causing this, >>> but it's unlikely to have any effect on the product. >>> >>> Another common source for change in symbols is due to previous >>> platform differences. For instance, if we had "JNIEXPORT int JNICALL >>> do_foo() { ... }", but do_foo was not in the mapfile, the symbol was >>> exported on Windows but not on Linux and Solaris. (Presumable since >>> it was not needed there, even though it was compiled for those >>> platforms as well.) Now, with the mapfiles gone, do_foo() will be >>> exported on all platforms. And contrary, functions that are compiled >>> on all platforms, and were exported in mapfiles, but now have gotten >>> an JNIEXPORT decoration, will now be visible even on Windows. (This >>> accounts for half of the noticed symbol differences on Windows.) I >>> could have made the JNIEXPORT conditional on OS, but I didn't think >>> the mess in source code were worth the keeping of binary confidence >>> with the old build. >>> >>> A third common source for change in symbols is due to exported >>> functions "leaking" across library borders. For instance, some >>> functions in java.desktop is compiled in both libawt_xawt and >>> libawt_headless, but they were previously only included in the >>> mapfile for one of these libraries. Now, since the visibility is >>> determined by the source code itself, it gets exported in both >>> libraries. A variant of this is when a library depends on another >>> JDK library, and includes the header file from that other library, >>> which in turn declares a function as JNIEXPORT. This will cause the >>> including library to also export the function. This accounts for the >>> other half of the changes on Windows. A typical example of this is >>> that multiple libraries now re-export hotspot symbols from >>> libjvm.so, like jio_fprintf. (I have not listed the libjvm >>> re-exports below.) >>> >>> Note that? Java_java_io_FileOutputStream_close0 in >>> java.base/unix/native/libjava/FileOutputStream_md.c is no longer >>> exported, >>> and can probably be removed. >>> >>> Here is a detailed table showing and accounting for all the >>> remaining differences found on Linux and Solaris: >>> java.base/unix/native/libjava: Java_java_io_FileOutputStream_close0 >>> is now also exported on unix platforms due to JNIEXPORT. >>> >>> java.base/jspawnlauncher: On solaris, we also include >>> libjava/childproc.o, which >>> now exports less functions than it used to (it used to export all >>> functions, now it is compiled with visibility=hidden). >>> >>> java.base/java(w).exe: Is now also exporting the following symbols >>> due to added JNIEXPORT in libjli on Windows: >>> (Yes, executables can export symbols on Windows. Confusing, I know.) >>> ?JLI_AddArgsFromEnvVar >>> ?JLI_CmdToArgs >>> ?JLI_GetAppArgIndex >>> ?JLI_GetStdArgc >>> ?JLI_GetStdArgs >>> ?JLI_InitArgProcessing >>> ?JLI_Launch >>> ?JLI_List_add >>> ?JLI_List_new >>> ?JLI_ManifestIterate >>> ?JLI_MemAlloc >>> ?JLI_MemFree >>> ?JLI_PreprocessArg >>> ?JLI_ReportErrorMessage >>> ?JLI_ReportErrorMessageSys >>> ?JLI_ReportExceptionDescription >>> ?JLI_ReportMessage >>> ?JLI_SetTraceLauncher >>> ?JLI_StringDup >>> >>> java.desktop:/libawt_xawt: The following symbols are now also >>> exported on linux and solaris due to JNIEXPORT: >>> ?awt_DrawingSurface_FreeDrawingSurfaceInfo >>> ?awt_DrawingSurface_GetDrawingSurfaceInfo >>> ?awt_DrawingSurface_Lock >>> ?awt_DrawingSurface_Unlock >>> ?awt_GetColor >>> >>> The following symbols are now also exported on linux and solaris due >>> to JNIEXPORT (they were previously >>> ?exported only in libawt): >>> ?Java_sun_awt_DebugSettings_setCTracingOn__Z >>> ?Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2 >>> ?Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2I >>> ?Java_sun_awt_X11GraphicsConfig_getNumColors >>> >>> java.desktop:/libawt_headless: The following symbols are now also >>> exported due to JNIEXPORT (they were previously >>> ?exported only in libawt_xawt and/or libawt): >>> ?Java_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo >>> ?Java_sun_java2d_opengl_GLXGraphicsConfig_getOGLCapabilities >>> ?Java_sun_java2d_x11_X11PMBlitLoops_updateBitmask >>> ?Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable >>> ?X11SurfaceData_GetOps >>> >>> java.desktop/libawt: The following symbols are now also exported on >>> Windows, due to added >>> JNIEXPORT: >>> ?SurfaceData_InitOps >>> ?mul8table >>> ?div8table >>> ?doDrawPath >>> ?doFillPath >>> ?g_CMpDataID >>> ?initInverseGrayLut >>> ?make_dither_arrays >>> ?make_uns_ordered_dither_array >>> ?path2DFloatCoordsID >>> ?path2DNumTypesID >>> ?path2DTypesID >>> ?path2DWindingRuleID >>> ?sg2dStrokeHintID >>> ?std_img_oda_blue >>> ?std_img_oda_green >>> ?std_img_oda_red >>> ?std_odas_computed >>> ?sunHints_INTVAL_STROKE_PURE >>> >>> java.desktop/libawt on solaris: >>> A number of "#pragma weak" directives was previously overridden by >>> the mapfile. >>> Now these directives are respected, so these symbols are now weak >>> instead of local: >>> ?ByteGrayToIntArgbPreConvert_F >>> ?ByteGrayToIntArgbPreScaleConvert_F >>> ?IntArgbBmToFourByteAbgrPreScaleXparOver_F >>> ?IntArgbToIntRgbXorBlit_F >>> ?IntBgrToIntBgrAlphaMaskBlit_F >>> >>> java.desktop/libawt on solaris: These are now also exported due to >>> JNIEXPORT in libmlib_image. >>> ?j2d_mlib_ImageCreate >>> ?j2d_mlib_ImageCreateStruct >>> ?j2d_mlib_ImageDelete >>> >>> java.desktop/libawt on solaris: This is now also exported due to >>> JNIEXPORT: >>> ?GrPrim_CompGetXorColor >>> ?SurfaceData_GetOpsNoSetup >>> ?SurfaceData_IntersectBoundsXYWH >>> ?SurfaceData_SetOps >>> ?Transform_GetInfo >>> ?Transform_transform >>> >>> java.desktop/libsplashscreen: JNI_OnLoad is now exported on linux >>> and solaris due to JNIEXPORT. >>> libspashscreen also had JNIEXPORT (actually a pure >>> _declspec(dllexport)) but no JNICALL, which I added as >>> a part of converting to JNIEXPORT. The same goes for libmlib_image . >>> >>> jdk.sctp/libsctp: handleSocketError is now exported on linux and >>> solaris due to JNIEXPORT in libnio. >>> >>> java.instrument:/libinstrument: Agent_OnUnload is now also exported >>> on linux and solaris platforms due to JNIEXPORT. >>> JLI_ManifestIterate is now also exported on Windows, due to added >>> JNIEXPORT in libjli. >>> >>> jdk.management/libmanagement_ext: >>> Java_com_sun_management_internal_Flag_setDoubleValue is now also >>> exported on linux and solaris platforms due to JNIEXPORT. >>> >>> /Magnus >>> >>> >> > From aph at redhat.com Sat Mar 24 11:13:13 2018 From: aph at redhat.com (Andrew Haley) Date: Sat, 24 Mar 2018 11:13:13 +0000 Subject: RFR 8199843 : Optimize Integer/Long.highestOneBit() In-Reply-To: <012cec3f-aa82-d76f-4ec8-bf83e7c049c0@oracle.com> References: <1f0c20c9-4618-79fd-9c3b-be97504f65dc@gmail.com> <012cec3f-aa82-d76f-4ec8-bf83e7c049c0@oracle.com> Message-ID: <23513eba-4e48-ac9e-6088-862d6de0c294@redhat.com> On 03/20/2018 05:20 PM, Ivan Gerasimov wrote: > I tried to run it, but the numbers are non-distinguishable for non-zero > arguments. > And my variant performs slightly better with zero argument. > So, I think it's reasonable to keep the variant with the ternary operator. I am suspicious of this argument. Did you look at the generated code? I get cbnz w10, 0x000003ffa8202384 mov w0, wzr for the zero test and cbz w10, 0x000003ffa81d228c clz w11, w10 orr w10, wzr, #0x80000000 lsr w0, w10, w11 ;*iushr for 42. The branch at the start of both versions goes to a deoptimize trap. We don't want deoptimize traps if we can avoid them, so the branchless version is better IMO. I think your benchmark is of questionable validity because it always uses the same value. This is unlikely in real code. I think the versions should be benchmarked with a *varying* argument. -- Andrew Haley Java Platform Lead Engineer Red Hat UK Ltd. EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671 From kedar.mhaswade at gmail.com Sat Mar 24 18:13:39 2018 From: kedar.mhaswade at gmail.com (kedar mhaswade) Date: Sat, 24 Mar 2018 11:13:39 -0700 Subject: Is a peculiar structural modification permissible while iterating a List using the fail-fast iterator? Message-ID: I apologize in advance if this has been asked before or if I am making a rookie mistake. Consider the program [1]. In Josh Bloch and Neal Gafter style (I miss those Puzzlers at JavaOnes), may I ask, "What does this program print?" As some of you may have guessed correctly, this program works *as naively expected* in that it (erroneously) removes the desired stooge from stooges and prints the list of remaining ones. Some analysis of the fail-fast iterator code in java.util.AbstractList$Itr and java.util.ArrayList$Itr suggests that only the item that is at the penultimate index in the backing list could be removed this way (i.e. *without* the fail-fast iterator detecting its structural modification). This appears to be because the implementation of hasNext() only checks if the cursor is equal to size without ensuring whether the expected and actual modification counts agree. My confusion is whether this is specified somewhere. None of java.util.Iterator#hasNext and java.util.ListIterator#hasNext seem to provide any specification about this. And hence it is not clear whether or not the hasNext() implementation must detect this peculiar structural modification. It is *not *specified if hasNext() may not throw ConcurrentModificationException. An unfortunate consequence is that an oversight on programmer's part (List#remove() instead of Iterator#remove) seems to go undetected. Is this a bug, or a feature? Regards, Kedar PS - It's entirely possible that I am not reading the code fully. I am checked the JDK 1.8.0_131 and Open JDK 1.9.0_181 sources. [1] import java.util.ArrayList;import java.util.List;import static java.util.Arrays.asList;public class ExceptionallyNamedException { public static void main(String[] args) { List stooges = new ArrayList<>(asList("Larry", "Moe", "Curly", "Jo", "Blo")); for (String stooge : stooges) { if ("Jo".equals(stooge)) { *// no other stooge may be removed erroneously * stooges.remove(stooge); *// erroneous removal, use iterator! * } } System.out.println(stooges); } } From martinrb at google.com Sat Mar 24 18:42:27 2018 From: martinrb at google.com (Martin Buchholz) Date: Sat, 24 Mar 2018 11:42:27 -0700 Subject: Is a peculiar structural modification permissible while iterating a List using the fail-fast iterator? In-Reply-To: References: Message-ID: https://docs.oracle.com/javase/9/docs/api/java/util/ConcurrentModificationException.html On Sat, Mar 24, 2018 at 11:13 AM, kedar mhaswade wrote: > I apologize in advance if this has been asked before or if I am making a > rookie mistake. > > Consider the program [1]. In Josh Bloch and Neal Gafter style (I miss those > Puzzlers at JavaOnes), may I ask, "What does this program print?" > > As some of you may have guessed correctly, this program works *as naively > expected* in that it (erroneously) removes the desired stooge from stooges > and prints the list of remaining ones. Some analysis of the fail-fast > iterator code in java.util.AbstractList$Itr and java.util.ArrayList$Itr > suggests that only the item that is at the penultimate index in the backing > list could be removed this way (i.e. *without* the fail-fast iterator > detecting its structural modification). This appears to be because the > implementation of hasNext() only checks if the cursor is equal to size > without ensuring whether the expected and actual modification counts agree. > My confusion is whether this is specified somewhere. None of > java.util.Iterator#hasNext and java.util.ListIterator#hasNext seem to > provide any specification about this. And hence it is not clear whether or > not the hasNext() implementation must detect this peculiar structural > modification. It is *not *specified if hasNext() may not throw > ConcurrentModificationException. An unfortunate consequence is that an > oversight on programmer's part (List#remove() instead of Iterator#remove) > seems to go undetected. > > Is this a bug, or a feature? > > Regards, > Kedar > > PS - It's entirely possible that I am not reading the code fully. I am > checked the JDK 1.8.0_131 and Open JDK 1.9.0_181 sources. > > > [1] > > import java.util.ArrayList;import java.util.List;import static > java.util.Arrays.asList;public class ExceptionallyNamedException { > public static void main(String[] args) { List stooges = > new ArrayList<>(asList("Larry", "Moe", "Curly", "Jo", "Blo")); > for (String stooge : stooges) { if ("Jo".equals(stooge)) { > *// no other stooge may be removed erroneously > * stooges.remove(stooge); *// erroneous removal, use > iterator! > * } } > System.out.println(stooges); } > } > From james at lightbend.com Mon Mar 26 01:58:47 2018 From: james at lightbend.com (James Roper) Date: Mon, 26 Mar 2018 12:58:47 +1100 Subject: Multi-Release jars intended use cases Message-ID: Hi all, According to Alan Bateman, MR jars can be used to introduce JDK9 API features on classes, such that javac can compile code against them to use the JDK9 specific API provided by the JDK9 version of the class, and still have the same classes be compatible with (and loadable by) JDK8: http://kto.so/2017/09/30/the-practical-truth-about-multi-release-jars/#comment-3563924109 My question is whether this is a recommended practice or not. Let me put forward a practical example of a place where we might want to use this. The 4 Reactive Streams interfaces (Publisher, Subscriber, Processor and Subscription) were first available in the org.reactivestreams project, under the package name org.reactivestreams. They were then added to JDK9, as inner interfaces of java.util.concurrent.Flow. Would it be considered a good use of MR jars to make the org.reactivestreams interfaces extend their juc.Flow counterparts when running and compiling by JDK9+? So, for example, in JDK8 and earlier you get: package org.reactivestreams; public interface Publisher { void subscribe(Subscriber s); } While on JDK9, using the MR feature, you get this: package org.reactivestreams; import java.util.concurrent.Flow; public interface Publisher extends Flow.Publisher { void subscribe(Subscriber s); default void subscribe(Flow.Subscriber s) { if (s instanceof Subscriber) { this.subscribe((Subscriber) s); } else { this.subscribe(new FlowSubscriberAdapter<>(s)); } } } The advantage of this approach is that it means if you have a library that produces org.reactivestreams.Publisher, then without any changes to that library to support JDK9, you can pass it to another library (eg, the JDK9 HTTP client) that accepts Flow.Publisher. Of course, it's not a panacea to solving the migration problem of org.reactivestreams to juc.Flow, but it goes a long way to helping. But of course, while the JDK *does* support this, that doesn't necessarily mean that we *should* use it that way, especially if it wasn't intended to be used in that way. Tooling, such as IDEs and compilers for other JVM languages, probably won't support this out of the box and may still need to catch up, and if it was never intended to be used in that way in the first place, then the tooling may decide not to implement it to work in that way. So it would be nice to have an official statement about whether the above use case is using the MR feature as intended, and whether that use case is considered a good practice or not. Regards, James -- *James Roper* *Senior Octonaut* Lightbend ? Build reactive apps! Twitter: @jroper From shade at redhat.com Mon Mar 26 07:45:57 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 26 Mar 2018 09:45:57 +0200 Subject: RFR 8200118: [test] String concat tests should test toString() application order In-Reply-To: <41637232-1c8f-f465-cf18-2f99f6d9df45@redhat.com> References: <41637232-1c8f-f465-cf18-2f99f6d9df45@redhat.com> Message-ID: Paul S. had reviewed, any other reviewers need/want to review? Thanks, -Aleksey On 03/22/2018 06:56 PM, Aleksey Shipilev wrote: > Bug: > https://bugs.openjdk.java.net/browse/JDK-8200118 > > Webrev: > http://cr.openjdk.java.net/~shade/8200118/webrev.01/ > > This adds the relevant test to StringConcat family of tests, which asserts all strategies do the > right thing. There was a bug in MH_* strategies caused by the already fixed bug in filterArguments > [1], which this test was supposed to find, if existed before. > > Testing: run-test with jdk/jdk, run-test before/after filterArguments fix in jdk-updates/jdk10u > > Thanks, > -Aleksey > > [1] https://bugs.openjdk.java.net/browse/JDK-8194554 > From claes.redestad at oracle.com Mon Mar 26 11:23:07 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 26 Mar 2018 13:23:07 +0200 Subject: RFR 8200118: [test] String concat tests should test toString() application order In-Reply-To: References: <41637232-1c8f-f465-cf18-2f99f6d9df45@redhat.com> Message-ID: Looks ok to me. Apart from the -source 1.9 -target 1.9 issue Paul already brought up, my only concern is that the multiplicity of variants makes running this test somewhat time consuming[1].? Complete test coverage is important, so to cut down on testing overheads then maybe it's time to examine if we can let go of some of the optional variants (BC_SB_SIZED, MH_SB_SIZED, ...)? /Claes [1] ~45s on linux-x64, ~1m40s on linux-x64-debug On 2018-03-26 09:45, Aleksey Shipilev wrote: > Paul S. had reviewed, any other reviewers need/want to review? > > Thanks, > -Aleksey > > On 03/22/2018 06:56 PM, Aleksey Shipilev wrote: >> Bug: >> https://bugs.openjdk.java.net/browse/JDK-8200118 >> >> Webrev: >> http://cr.openjdk.java.net/~shade/8200118/webrev.01/ >> >> This adds the relevant test to StringConcat family of tests, which asserts all strategies do the >> right thing. There was a bug in MH_* strategies caused by the already fixed bug in filterArguments >> [1], which this test was supposed to find, if existed before. >> >> Testing: run-test with jdk/jdk, run-test before/after filterArguments fix in jdk-updates/jdk10u >> >> Thanks, >> -Aleksey >> >> [1] https://bugs.openjdk.java.net/browse/JDK-8194554 >> > From Alan.Bateman at oracle.com Mon Mar 26 11:41:50 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 26 Mar 2018 12:41:50 +0100 Subject: Multi-Release jars intended use cases In-Reply-To: References: Message-ID: <2f86e652-1864-6f9c-40d4-70b3b3c002e6@oracle.com> On 26/03/2018 02:58, James Roper wrote: > Hi all, > > According to Alan Bateman, MR jars can be used to introduce JDK9 API > features on classes, such that javac can compile code against them to use > the JDK9 specific API provided by the JDK9 version of the class, and still > have the same classes be compatible with (and loadable by) JDK8: > > http://kto.so/2017/09/30/the-practical-truth-about-multi-release-jars/#comment-3563924109 > > : > > So it would be nice to have an official statement about whether the above > use case is using the MR feature as intended, and whether that use case is > considered a good practice or not. That blog has been updated since I added the comment. If I recall correctly, the original blog was using javac with an exploded build, not a MR JAR. In any case, the intention is that a specific version of a library export one API and it shouldn't vary depending on the JDK version. The implementation may of course have code specific to JDK 9, 10, ... but the API for consumers of that version of the library should always be the same. The `jar` tool checks this when creating a MR JAR. I don't know if the Maven Archiver and other plugins that create JAR files do the same check yet. -Alan From claes.redestad at oracle.com Mon Mar 26 12:08:06 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 26 Mar 2018 14:08:06 +0200 Subject: RFR: 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull Message-ID: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> Hi, MethodHandleNatives::resolve are used by both MemberName$Factory::resolveOrFail and ::resolveOrNull, the latter allowing speculative lookup of methods. While the linkResolver code this calls into in the VM will create and throw exceptions for all cases where a method or field is missing, these are caught by MethodHandles::resolve_MemberName and an empty handle is returned instead. However, the outer method, MHN_resolve_Mem will always create a new exception and throw it. In case of resolveOrNull, we'll then ignore whatever exception is thrown in the java code, so in effect we're creating and ignoring two exceptions on a failed lookup. We can cut this in half by passing a boolean to MethodHandleNatives::resolve to indicate whether we're doing a speculative lookup (resolveOrNull) or not (resolveOrFail): Bug: https://bugs.openjdk.java.net/browse/JDK-8200238 Webrev: http://cr.openjdk.java.net/~redestad/8200238/open.00/ This is a small startup optimization for applications that have a high miss rate (looks up a lot of methods that doesn't exist in the pre-generated Holders). Thanks! /Claes From shade at redhat.com Mon Mar 26 13:02:51 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 26 Mar 2018 15:02:51 +0200 Subject: RFR 8200118: [test] String concat tests should test toString() application order In-Reply-To: References: <41637232-1c8f-f465-cf18-2f99f6d9df45@redhat.com> Message-ID: <08602d6e-006a-9a52-c2cf-786cdd1ed714@redhat.com> On 03/26/2018 01:23 PM, Claes Redestad wrote: > Looks ok to me. > > Apart from the -source 1.9 -target 1.9 issue Paul already brought up, my only > concern is that the multiplicity of variants makes running this test somewhat time > consuming[1].? Complete test coverage is important, so to cut down on testing > overheads then maybe it's time to examine if we can let go of some of the optional > variants (BC_SB_SIZED, MH_SB_SIZED, ...)? Maybe! I would prefer not to disable these in tests now, nor let go of some of them, because those strategies serve as backup options should the default strategy misbehave (like it does now, in some corner cases). Users do not really know which of those strategies are better tested, and which are not, so it seems sensible to test all of them. -Aleksey From david.holmes at oracle.com Mon Mar 26 13:16:41 2018 From: david.holmes at oracle.com (David Holmes) Date: Mon, 26 Mar 2018 23:16:41 +1000 Subject: RFR: 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull In-Reply-To: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> References: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> Message-ID: <57a400b8-946d-7748-b7e0-90a55453fb93@oracle.com> Hi Claes, On 26/03/2018 10:08 PM, Claes Redestad wrote: > Hi, > > MethodHandleNatives::resolve are used by both > MemberName$Factory::resolveOrFail and ::resolveOrNull, the latter > allowing speculative lookup of methods. > > While the linkResolver code this calls into in the VM will create and > throw exceptions for all cases where a method or field is missing, these > are caught by MethodHandles::resolve_MemberName and an empty handle is > returned instead. However, the outer method, MHN_resolve_Mem will always > create a new exception and throw it. MethodHandles::resolve_MemberName doesn't "catch" exceptions from LinkResolver. They remain pending and will be thrown later unless replaced with a different exception - which sounds like what happens from your description. But both that and the unconditional clearing of the exception that you do now seem quite wrong! It may be okay to ignore a missing field/method but there can be various other exceptions thrown which should not simply be ignored/hidden. If an unexpected exception occurs then it should either become the cause of a higher-level exception, or allowed to propagate as itself (OOME, StackOverflow ...) One of the changes that is coming as part of the JEP-181 (Nestmates) work is that LinkResolver access control will no longer convert OOME/StackOverflow etc into IllegalAccessError but let them propagate as is. There will also be the possibility of LinkageErrors being thrown due to nestmate checks. It is not at all clear to me how the MH code is dealing with exceptions that come from this code. David ----- > > In case of resolveOrNull, we'll then ignore whatever exception is thrown > in the java code, so in effect we're creating and ignoring two > exceptions on a failed lookup. > > We can cut this in half by passing a boolean to > MethodHandleNatives::resolve to indicate whether we're doing a > speculative lookup (resolveOrNull) or not (resolveOrFail): > > Bug: https://bugs.openjdk.java.net/browse/JDK-8200238 > > Webrev: http://cr.openjdk.java.net/~redestad/8200238/open.00/ It doesn't look right to clear any pending exception rather than just the ones reporting a missing field or method. > This is a small startup optimization for applications that have a high > miss rate (looks up a lot of methods that doesn't exist in the > pre-generated Holders). > > Thanks! > > /Claes > From shade at redhat.com Mon Mar 26 13:22:19 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 26 Mar 2018 15:22:19 +0200 Subject: RFR 8200241: [TESTBUG] java/lang/String/concat/ tests should not force source/release = 9 anymore Message-ID: <055a33f1-e748-67e6-8a1a-5ed47a179060@redhat.com> Bug: https://bugs.openjdk.java.net/browse/JDK-8200241 Webrev: http://cr.openjdk.java.net/~shade/8200241/webrev.01/ As discussed in a separate thread on this list, we do not need source/target = 9 in these tests anymore. Testing: make run-test TEST=test/jdk/java/lang/String/concat/, Linux x86_64 {fastdebug|release} Thanks, -Aleksey From claes.redestad at oracle.com Mon Mar 26 13:31:34 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 26 Mar 2018 15:31:34 +0200 Subject: RFR: 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull In-Reply-To: <57a400b8-946d-7748-b7e0-90a55453fb93@oracle.com> References: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> <57a400b8-946d-7748-b7e0-90a55453fb93@oracle.com> Message-ID: On 2018-03-26 15:16, David Holmes wrote: > MethodHandles::resolve_MemberName doesn't "catch" exceptions from > LinkResolver. They remain pending and will be thrown later unless > replaced with a different exception - which sounds like what happens > from your description. This doesn't really jive with experience: returning NULL without any CLEAR_PENDING_EXCEPTION in MHN_resolve_Mem or MethodHandles::resolve_MemberName does not mean the exception is later thrown, rather a null is returned from MHN::resolve. I've removed the CLEAR_PENDING_EXCEPTIONS I added experimentally from this webrev, as this might be subtly changing semantics of the resolveOrFail case. /Claes From claes.redestad at oracle.com Mon Mar 26 13:32:14 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 26 Mar 2018 15:32:14 +0200 Subject: RFR 8200241: [TESTBUG] java/lang/String/concat/ tests should not force source/release = 9 anymore In-Reply-To: <055a33f1-e748-67e6-8a1a-5ed47a179060@redhat.com> References: <055a33f1-e748-67e6-8a1a-5ed47a179060@redhat.com> Message-ID: <2f0de72b-503f-287b-b85c-70e2c4f7b879@oracle.com> Looks good. /Claes On 2018-03-26 15:22, Aleksey Shipilev wrote: > Bug: > https://bugs.openjdk.java.net/browse/JDK-8200241 > > Webrev: > http://cr.openjdk.java.net/~shade/8200241/webrev.01/ > > As discussed in a separate thread on this list, we do not need source/target = 9 in these tests anymore. > > Testing: make run-test TEST=test/jdk/java/lang/String/concat/, Linux x86_64 {fastdebug|release} > > Thanks, > -Aleksey > From claes.redestad at oracle.com Mon Mar 26 13:35:45 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 26 Mar 2018 15:35:45 +0200 Subject: RFR 8200118: [test] String concat tests should test toString() application order In-Reply-To: <08602d6e-006a-9a52-c2cf-786cdd1ed714@redhat.com> References: <41637232-1c8f-f465-cf18-2f99f6d9df45@redhat.com> <08602d6e-006a-9a52-c2cf-786cdd1ed714@redhat.com> Message-ID: On 2018-03-26 15:02, Aleksey Shipilev wrote: >> Complete test coverage is important, so to cut down on testing >> overheads then maybe it's time to examine if we can let go of some of the optional >> variants (BC_SB_SIZED, MH_SB_SIZED, ...)? > Maybe! I would prefer not to disable these in tests now, nor let go of some of them, because those > strategies serve as backup options should the default strategy misbehave (like it does now, in some > corner cases). Right, I wasn't suggesting we remove all of them (or even do it now), but maybe start examining which, if any, of these fallback options are being used in the wild and start planning for deprecating and removing any unused ones in an orderly fashion. /Claes From Alan.Bateman at oracle.com Mon Mar 26 14:53:57 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 26 Mar 2018 15:53:57 +0100 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> Message-ID: <10728b43-110c-5dc3-1fdb-2e0241e3a0ff@oracle.com> On 23/03/2018 19:17, David Lloyd wrote: > All fixed. You're right, the catch blocks consolidated fairly easily > and it looks better. I've attached the latest version of the patch. > I went through the APIs and javadoc changes attached to your last mail. This version addresses most of the points I brought up a few weeks ago and the API generally looks good. The only methods that I'm not sure about is the setDictionary variants as I don't see a bit need for these. Deflater.setInput currently has "The given buffer's position will be updated ...". I think could be clearer by saying that the buffer position s? advanced by the deflate operations up to its limit. This will make it more consistent with the wording in the deflate methods. I also wonder if the parameter should be renamed to "input" or "source". The deflate methods talk about "remaining space" which is a bit inconsistent the buffer APIs where it uses "bytes remaining". I think we should try to keep this as consistent as possible. Also the usage advice, "Make sure the buffer's remaining space ..." should probably be moved to an @apiNote (this goes for the existing deflate methods too). I don't have cycles just now to go through all the implementation but I think Sherman is doing that. It will need careful review to avoid being abused to attack memory outside of the buffer. I did check the use of position() and limit() to calculate the remaining and these need correct. Style wide then we should try to keep thing consistent with the existing code as possible (most of the "final" usages are a distraction and aren't needed for example). -Alan From karen.kinnear at oracle.com Mon Mar 26 15:15:55 2018 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Mon, 26 Mar 2018 11:15:55 -0400 Subject: RFR: 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull In-Reply-To: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> References: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> Message-ID: <5829E498-2176-49C2-ACE8-5E7F232D2632@oracle.com> Claes, Discussed with Lois. We think that it would make more sense to pass the new argument into MethodHandles::resolve_MemberName and at all three places that we currently CHECK_PENDING_EXCEPTION/return null there - if speculative flag is set - CLEAR_PENDING_EXCEPTION before you return null - and yes - do this for all three cases, not just the METHOD case Couple of questions though: 1) do you actually reach the new code in MHN_resolve_Mem? Could you possibly add an assertion there that there is no exception pending and/or print the exception if there is one pending? With the CHECK_NULL in the call to resolve_MemberName I do not expect you to get here with a pending exception, so the question arises as to when you would have a null resolved, but no pending exception? 2) with the change you just sent out - do you really get a performance improvement? I?m confused about where that comes from My apologies - I was incorrect - we are not converting Error -> Exception in MHN_resolve_Mem - so I do not know why we are burying existing exceptions here - longer-term I think we need to clean this up and as David points out - at least for the ResolveOrFail case - store the original exception as a cause. thanks, Karen > On Mar 26, 2018, at 8:08 AM, Claes Redestad wrote: > > Hi, > > MethodHandleNatives::resolve are used by both MemberName$Factory::resolveOrFail and ::resolveOrNull, the latter allowing speculative lookup of methods. > > While the linkResolver code this calls into in the VM will create and throw exceptions for all cases where a method or field is missing, these are caught by MethodHandles::resolve_MemberName and an empty handle is returned instead. However, the outer method, MHN_resolve_Mem will always create a new exception and throw it. > > In case of resolveOrNull, we'll then ignore whatever exception is thrown in the java code, so in effect we're creating and ignoring two exceptions on a failed lookup. > > We can cut this in half by passing a boolean to MethodHandleNatives::resolve to indicate whether we're doing a speculative lookup (resolveOrNull) or not (resolveOrFail): > > Bug: https://bugs.openjdk.java.net/browse/JDK-8200238 > > Webrev: http://cr.openjdk.java.net/~redestad/8200238/open.00/ > > This is a small startup optimization for applications that have a high miss rate (looks up a lot of methods that doesn't exist in the pre-generated Holders). > > Thanks! > > /Claes > From claes.redestad at oracle.com Mon Mar 26 15:51:29 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Mon, 26 Mar 2018 17:51:29 +0200 Subject: RFR: 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull In-Reply-To: <5829E498-2176-49C2-ACE8-5E7F232D2632@oracle.com> References: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> <5829E498-2176-49C2-ACE8-5E7F232D2632@oracle.com> Message-ID: <2414aaf1-c7b0-56f0-58cd-84ee852e749f@oracle.com> Karen, On 2018-03-26 17:15, Karen Kinnear wrote: > Claes, > > Discussed with Lois. We think that it would make more sense to pass the new argument into MethodHandles::resolve_MemberName and at all three places that we currently CHECK_PENDING_EXCEPTION/return null there > - if speculative flag is set - CLEAR_PENDING_EXCEPTION before you return null > - and yes - do this for all three cases, not just the METHOD case ok. > > Couple of questions though: > 1) do you actually reach the new code in MHN_resolve_Mem? Could you possibly add an assertion there that > there is no exception pending and/or print the exception if there is one pending? > With the CHECK_NULL in the call to resolve_MemberName I do not expect you to get here with a pending exception, > so the question arises as to when you would have a null resolved, but no pending exception? Yes, we reach it, and by returning NULL there a null return is observed on the java side, regardless of whether or not I CLEAR_PENDING_EXCEPTION. I'd be happy to add more assertions. > > 2) with the change you just sent out - do you really get a performance improvement? > I?m confused about where that comes from By not throwing a new NSME from MHN_resolve_Mem, the effective number of created exceptions (shown by -Xlog:exceptions) is cut in half.? On a startup test that does 10 failed resolveOrNull calls, this equates to a reduction in retired instructions by ~2M on my machine, as measured by perf. > > My apologies - I was incorrect - we are not converting Error -> Exception in MHN_resolve_Mem - so I > do not know why we are burying existing exceptions here - longer-term I think we need to clean this up > and as David points out - at least for the ResolveOrFail case - store the original exception as a cause. Right. /Claes From paul.sandoz at oracle.com Mon Mar 26 18:08:58 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 26 Mar 2018 11:08:58 -0700 Subject: RFR 8200241: [TESTBUG] java/lang/String/concat/ tests should not force source/release = 9 anymore In-Reply-To: <055a33f1-e748-67e6-8a1a-5ed47a179060@redhat.com> References: <055a33f1-e748-67e6-8a1a-5ed47a179060@redhat.com> Message-ID: <77CDA3CD-DF94-4B1A-B1F6-455DB50BF8B5@oracle.com> +1 Paul. > On Mar 26, 2018, at 6:22 AM, Aleksey Shipilev wrote: > > Bug: > https://bugs.openjdk.java.net/browse/JDK-8200241 > > Webrev: > http://cr.openjdk.java.net/~shade/8200241/webrev.01/ > > As discussed in a separate thread on this list, we do not need source/target = 9 in these tests anymore. > > Testing: make run-test TEST=test/jdk/java/lang/String/concat/, Linux x86_64 {fastdebug|release} > > Thanks, > -Aleksey > From shade at redhat.com Mon Mar 26 18:21:19 2018 From: shade at redhat.com (Aleksey Shipilev) Date: Mon, 26 Mar 2018 20:21:19 +0200 Subject: RFR 8200241: [TESTBUG] java/lang/String/concat/ tests should not force source/release = 9 anymore In-Reply-To: <77CDA3CD-DF94-4B1A-B1F6-455DB50BF8B5@oracle.com> References: <055a33f1-e748-67e6-8a1a-5ed47a179060@redhat.com> <77CDA3CD-DF94-4B1A-B1F6-455DB50BF8B5@oracle.com> Message-ID: <76113720-c14a-99c1-5119-d839f6dd8b4c@redhat.com> Thanks, pushed. -Aleksey On 03/26/2018 08:08 PM, Paul Sandoz wrote: > +1 > Paul. > >> On Mar 26, 2018, at 6:22 AM, Aleksey Shipilev wrote: >> >> Bug: >> https://bugs.openjdk.java.net/browse/JDK-8200241 >> >> Webrev: >> http://cr.openjdk.java.net/~shade/8200241/webrev.01/ >> >> As discussed in a separate thread on this list, we do not need source/target = 9 in these tests anymore. >> >> Testing: make run-test TEST=test/jdk/java/lang/String/concat/, Linux x86_64 {fastdebug|release} >> >> Thanks, >> -Aleksey >> > From stuart.marks at oracle.com Mon Mar 26 18:45:29 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Mon, 26 Mar 2018 11:45:29 -0700 Subject: [11] RFR: 8193128: Reduce number of implementation classes returned by List/Set/Map.of() In-Reply-To: References: <7d367ca5-2915-bd80-8247-c748260f93c8@oracle.com> <8746a7ab-4c1c-98fc-a0ba-05594bce794c@oracle.com> <71b8baf0-0f4b-2e64-36d9-610e2286b59e@oracle.com> <4ec012ce-cd0c-003b-c20a-4c77e317e40f@gmail.com> <14910571-3cc8-75a5-9f80-8d633b23ac4b@oracle.com> <94ea8e2e-418c-4408-2dc2-7bea1ca099d4@gmail.com> <2845d01f-742a-bcfe-330c-5fbd586eaf88@oracle.com> <1bcb7c02-5ce0-be4f-e28c-842f229004bc@gmail.com> <98bb59c5-c091-a90d-723e-1a0ce1d6df93@oracle.com> <97367d24-f411-0a75-677d-93e9d213ef94@oracle.com> Message-ID: <947c7459-1b4a-c885-f2c8-671777d48547@oracle.com> On 3/22/18 11:50 PM, Zheka Kozlov wrote: > I noticed that List.copyOf() allocates an array twice. The first allocation is > coll.toArray(), the second one is in ListN constructor. Can we do something with it? Yeah, I still need to fix that. The various fixed-args List.of() factory methods also do extra copies, as do the stream Collectors.toUnmodifiableX(). This is all covered by JDK-8156071. https://bugs.openjdk.java.net/browse/JDK-8156071 s'marks From martinrb at google.com Mon Mar 26 18:46:56 2018 From: martinrb at google.com (Martin Buchholz) Date: Mon, 26 Mar 2018 11:46:56 -0700 Subject: [PATCH] Duplicated indexOf/lasIndexOf in array-based collections In-Reply-To: <3495951520671366@web26g.yandex.ru> References: <3495951520671366@web26g.yandex.ru> Message-ID: ??????, I'm sort of maintaining all those collection classes, and I have on occasion also wanted to have indexOf methods in Array.java. But: Arrays are generally discouraged. Any new static methods on Arrays (or, where I actually want them, on the array object itself! Requires a java language change!) will meet resistance. We've come to regret supporting nulls in collections, so newer collection classes like ArrayDeque don't support them. Another variant users might want is what kind of equality comparison to use. We've come to regret having ArrayList with zero-based start index - it would have been better to have ArrayDeque's circular array behavior in from day one. The code to search array slices is very small, so you're not saving much. It's easy to make an off-by-one error, but that's true for an Arrays API as well. On Sat, Mar 10, 2018 at 12:42 AM, ?????? ??????? wrote: > Hi everyone, > > currently array-based collections, in particular java.util.ArrayList, > java.util.Arrays$ArrayList, java.util.Vector, java.util.concurrent.CopyOnWriteArrayList > have duplicated code in indexOf() and lastIndexOf(). > > My proposal is to extract this code into java.util.Arrays helping JIT and > saving space in ReservedCodeCache. > > Moreover, developers quite often use code snippets like > > Arras.asList(array).indexOf(obj) > Arras.asList(array).contains(obj) or even > Arrays.stream(names).anyMatch(existing -> existing.equals(name)); > > or write similar utility code for allocation-free cases like the one in > > https://github.com/hibernate/hibernate-orm/blob/ > 0a2a5c622e3eb30724e80bc8661c0ac55ebfb2be/hibernate-core/src/ > main/java/org/hibernate/bytecode/enhance/internal/ > tracker/SimpleFieldTracker.java#L40 > > Also see > > https://github.com/JetBrains/intellij-community/blob/ > 200f59d7cf3b0f66feb3a4abebbb90864dc5edc7/platform/util/src/ > com/intellij/util/ArrayUtil.java#L726 > > https://github.com/JetBrains/intellij-community/blob/ > 200f59d7cf3b0f66feb3a4abebbb90864dc5edc7/platform/util-rt/ > src/com/intellij/util/ArrayUtilRt.java#L63 > > https://github.com/spring-projects/spring-framework/blob/ > 5f4d1a4628513ab34098fa3f92ba03aa20fc4204/spring-oxm/src/ > main/java/org/springframework/oxm/jibx/JibxMarshaller.java#L256 > > > If java.util.Arrays incorporates contains() and indexOf() then all that > boilerplate can be replaced with usage of JDK-provided standard API. > > Patch is attached to this mail. > > Regards, > Sergey Tsypanov > > > From martinrb at google.com Mon Mar 26 18:58:47 2018 From: martinrb at google.com (Martin Buchholz) Date: Mon, 26 Mar 2018 11:58:47 -0700 Subject: Inefficient indexOf called inside of CopyOnWriteArrayList$COWSubList.remove(Object) In-Reply-To: <3867991521785065@web23g.yandex.ru> References: <3867991521785065@web23g.yandex.ru> Message-ID: I filed https://bugs.openjdk.java.net/browse/JDK-8200258 and added comment: I agree that CopyOnWriteArrayList subList code can be improved. We should stop subclassing AbstractList. We should add more tests. We should have more guidance about when to use index-based API - only when quiescent or thread-confined. Explain how to most efficiently create a snapshot - probably snapshot = new CopyOnWriteArrayList(sharedCOWAL) From paul.sandoz at oracle.com Mon Mar 26 20:39:02 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 26 Mar 2018 13:39:02 -0700 Subject: [PATCH] Duplicated indexOf/lasIndexOf in array-based collections In-Reply-To: References: <3495951520671366@web26g.yandex.ru> Message-ID: <9B586591-F4D9-4E61-B847-8E8E529AC610@oracle.com> > On Mar 26, 2018, at 11:46 AM, Martin Buchholz wrote: > > ??????, I'm sort of maintaining all those collection classes, and I have on > occasion also wanted to have indexOf methods in Array.java. But: > > Arrays are generally discouraged. Any new static methods on Arrays (or, > where I actually want them, on the array object itself! Requires a java > language change!) will meet resistance. > I would not go so far as to say arrays are discouraged, i would positively spin it as "use with care? as they are prickly e.g. always mutable. They could certainly be improved. I would be very happy to see arrays implement a common array?ish interface, we might be able to make some progress after value types sediment. Any new additions to Arrays would be met with some resistance though, by me at least :-) It?s never adding just one or two methods, many others want come along for the ride as well (all primitives plus range variants). So any new feature needs to be sufficiently beneficial and in this case i don?t think the benefits are strong enough (such as a possible reduction code cache pressure). Paul. > We've come to regret supporting nulls in collections, so newer collection > classes like ArrayDeque don't support them. > > Another variant users might want is what kind of equality comparison to use. > > We've come to regret having ArrayList with zero-based start index - it > would have been better to have ArrayDeque's circular array behavior in from > day one. > > The code to search array slices is very small, so you're not saving much. > It's easy to make an off-by-one error, but that's true for an Arrays API as > well. > > On Sat, Mar 10, 2018 at 12:42 AM, ?????? ??????? > wrote: > >> Hi everyone, >> >> currently array-based collections, in particular java.util.ArrayList, >> java.util.Arrays$ArrayList, java.util.Vector, java.util.concurrent.CopyOnWriteArrayList >> have duplicated code in indexOf() and lastIndexOf(). >> >> My proposal is to extract this code into java.util.Arrays helping JIT and >> saving space in ReservedCodeCache. >> >> Moreover, developers quite often use code snippets like >> >> Arras.asList(array).indexOf(obj) >> Arras.asList(array).contains(obj) or even >> Arrays.stream(names).anyMatch(existing -> existing.equals(name)); >> >> or write similar utility code for allocation-free cases like the one in >> >> https://github.com/hibernate/hibernate-orm/blob/ >> 0a2a5c622e3eb30724e80bc8661c0ac55ebfb2be/hibernate-core/src/ >> main/java/org/hibernate/bytecode/enhance/internal/ >> tracker/SimpleFieldTracker.java#L40 >> >> Also see >> >> https://github.com/JetBrains/intellij-community/blob/ >> 200f59d7cf3b0f66feb3a4abebbb90864dc5edc7/platform/util/src/ >> com/intellij/util/ArrayUtil.java#L726 >> >> https://github.com/JetBrains/intellij-community/blob/ >> 200f59d7cf3b0f66feb3a4abebbb90864dc5edc7/platform/util-rt/ >> src/com/intellij/util/ArrayUtilRt.java#L63 >> >> https://github.com/spring-projects/spring-framework/blob/ >> 5f4d1a4628513ab34098fa3f92ba03aa20fc4204/spring-oxm/src/ >> main/java/org/springframework/oxm/jibx/JibxMarshaller.java#L256 >> >> >> If java.util.Arrays incorporates contains() and indexOf() then all that >> boilerplate can be replaced with usage of JDK-provided standard API. >> >> Patch is attached to this mail. >> >> Regards, >> Sergey Tsypanov >> >> >> From ivan.gerasimov at oracle.com Mon Mar 26 21:26:04 2018 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Mon, 26 Mar 2018 14:26:04 -0700 Subject: RFR 8199843 : Optimize Integer/Long.highestOneBit() In-Reply-To: <23513eba-4e48-ac9e-6088-862d6de0c294@redhat.com> References: <1f0c20c9-4618-79fd-9c3b-be97504f65dc@gmail.com> <012cec3f-aa82-d76f-4ec8-bf83e7c049c0@oracle.com> <23513eba-4e48-ac9e-6088-862d6de0c294@redhat.com> Message-ID: Thank you Andrew for looking into this! On 3/24/18 4:13 AM, Andrew Haley wrote: > On 03/20/2018 05:20 PM, Ivan Gerasimov wrote: >> I tried to run it, but the numbers are non-distinguishable for non-zero >> arguments. >> And my variant performs slightly better with zero argument. >> So, I think it's reasonable to keep the variant with the ternary operator. > I am suspicious of this argument. Did you look at the generated code? > > I get > > cbnz w10, 0x000003ffa8202384 > mov w0, wzr > > for the zero test and > > cbz w10, 0x000003ffa81d228c > clz w11, w10 > orr w10, wzr, #0x80000000 > lsr w0, w10, w11 ;*iushr > > for 42. > > The branch at the start of both versions goes to a deoptimize trap. > We don't want deoptimize traps if we can avoid them, so the branchless > version is better IMO. This looks persuasive, so let's go ahead with the branchless variant! With kind regards, Ivan > I think your benchmark is of questionable validity because it always > uses the same value. This is unlikely in real code. I think the > versions should be benchmarked with a *varying* argument. > -- With kind regards, Ivan Gerasimov From paul.sandoz at oracle.com Mon Mar 26 21:42:35 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Mon, 26 Mar 2018 14:42:35 -0700 Subject: RFR 8199843 : Optimize Integer/Long.highestOneBit() In-Reply-To: References: <1f0c20c9-4618-79fd-9c3b-be97504f65dc@gmail.com> <012cec3f-aa82-d76f-4ec8-bf83e7c049c0@oracle.com> <23513eba-4e48-ac9e-6088-862d6de0c294@redhat.com> Message-ID: > On Mar 26, 2018, at 2:26 PM, Ivan Gerasimov wrote: > > Thank you Andrew for looking into this! > > > On 3/24/18 4:13 AM, Andrew Haley wrote: >> On 03/20/2018 05:20 PM, Ivan Gerasimov wrote: >>> I tried to run it, but the numbers are non-distinguishable for non-zero >>> arguments. >>> And my variant performs slightly better with zero argument. >>> So, I think it's reasonable to keep the variant with the ternary operator. >> I am suspicious of this argument. Did you look at the generated code? >> >> I get >> >> cbnz w10, 0x000003ffa8202384 >> mov w0, wzr >> >> for the zero test and >> >> cbz w10, 0x000003ffa81d228c >> clz w11, w10 >> orr w10, wzr, #0x80000000 >> lsr w0, w10, w11 ;*iushr >> >> for 42. >> >> The branch at the start of both versions goes to a deoptimize trap. >> We don't want deoptimize traps if we can avoid them, so the branchless >> version is better IMO. > This looks persuasive, so let's go ahead with the branchless variant! > +1 In my experience with nano-benchamarks like this it's often informative to look at the generated code. This is even easier now that JMH supports a dtrace ASM profiler on the Mac: http://mail.openjdk.java.net/pipermail/jmh-dev/2018-January/002686.html (YMMV, I ran into some issues on the mac whereby the spawned dtrace stopped logging output and needed to poked with a signal into action and dump the rest of its output. Not had time to investigate in detail and report back on this.) Paul. From david.lloyd at redhat.com Mon Mar 26 23:09:30 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Mon, 26 Mar 2018 18:09:30 -0500 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: <10728b43-110c-5dc3-1fdb-2e0241e3a0ff@oracle.com> References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> <10728b43-110c-5dc3-1fdb-2e0241e3a0ff@oracle.com> Message-ID: On Mon, Mar 26, 2018 at 9:53 AM, Alan Bateman wrote: > On 23/03/2018 19:17, David Lloyd wrote: >> >> All fixed. You're right, the catch blocks consolidated fairly easily >> and it looks better. I've attached the latest version of the patch. >> > I went through the APIs and javadoc changes attached to your last mail. > > This version addresses most of the points I brought up a few weeks ago and > the API generally looks good. The only methods that I'm not sure about is > the setDictionary variants as I don't see a bit need for these. I think they may have use in some cases e.g. reading a dictionary from a file, and generally in code which prefers byte buffers over arrays (completely outside of the direct/heap buffer question), and they were easy enough to implement. But I'm okay dropping these methods if that is what is desired. > Deflater.setInput currently has "The given buffer's position will be updated > ...". I think could be clearer by saying that the buffer position s > advanced by the deflate operations up to its limit. This will make it more > consistent with the wording in the deflate methods. OK. > I also wonder if the parameter should be renamed to "input" or "source". I was going for some kind of consistency with the array variants (that is, name the parameter what it is), though they simply use "b" for their parameter name so that interpretation might be a stretch. Should I update them all? > The deflate methods talk about "remaining space" which is a bit inconsistent > the buffer APIs where it uses "bytes remaining". I think we should try to > keep this as consistent as possible. OK. > Also the usage advice, "Make sure the buffer's remaining space ..." should > probably be moved to an @apiNote (this goes for the existing deflate methods > too). I'm not 100% familiar with the new JavaDoc categories (ok I'm 0% familiar), but the JEP for these says "This category consists of commentary, rationale, or examples pertaining to the API.". But this feels more like specification to me since it is "specifications that apply to all valid implementations, including preconditions, postconditions, etc.". Which is to say, if you don't provide enough remaining space in the output buffer, you will have incorrect operation as a result. WDYT? > I don't have cycles just now to go through all the implementation but I > think Sherman is doing that. It will need careful review to avoid being > abused to attack memory outside of the buffer. I did check the use of > position() and limit() to calculate the remaining and these need correct. I hope this was a typo of "these seem correct" and not a typo of "these need correcting"? > Style wide then we should try to keep thing consistent with the existing > code as possible (most of the "final" usages are a distraction and aren't > needed for example). OK I can remove them; it's been my personal convention for so many years that I don't see them when they're there (only when they're missing). But removing them here is OK with me. -- - DML From jonathan.gibbons at oracle.com Tue Mar 27 00:01:17 2018 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Mon, 26 Mar 2018 17:01:17 -0700 Subject: RFR: {@docRoot} reference need to be updated to reflect new module structure Message-ID: <5AB989CD.4020008@oracle.com> This is fixing up some links in the java.base module, following a recent change in javadoc to the organization of the generated files. While the change was mostly transparent, links within the documentation using {@docRoot} need to be updated. All the changes were done automatically, by the following sed commands, to insert "/java.base" into the affected links. 's|{@docRoot}/java/lang/|{@docRoot}/java.base/java/lang/|' 's|{@docRoot}/java/util/|{@docRoot}/java.base/java/util/|' JBS: https://bugs.openjdk.java.net/browse/JDK-8199465 Webrev: http://cr.openjdk.java.net/~jjg/8199465/webrev.00/ There are a few additional issues in other modules that I will handle separately. -- Jon From david.holmes at oracle.com Tue Mar 27 00:03:41 2018 From: david.holmes at oracle.com (David Holmes) Date: Tue, 27 Mar 2018 10:03:41 +1000 Subject: RFR: 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull In-Reply-To: References: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> <57a400b8-946d-7748-b7e0-90a55453fb93@oracle.com> Message-ID: <4f5c2fd6-ebaa-eeda-165c-617fecee381b@oracle.com> On 26/03/2018 11:31 PM, Claes Redestad wrote: > > > On 2018-03-26 15:16, David Holmes wrote: >> MethodHandles::resolve_MemberName doesn't "catch" exceptions from >> LinkResolver. They remain pending and will be thrown later unless >> replaced with a different exception - which sounds like what happens >> from your description. > > This doesn't really jive with experience: returning NULL without any > CLEAR_PENDING_EXCEPTION in MHN_resolve_Mem or > MethodHandles::resolve_MemberName does not mean the exception is later > thrown, rather a null is returned from MHN::resolve. If there is a pending exception then it will be rethrown as soon as we hit code that checks for pending exceptions. If it is not rethrown then something else is clearing it. > I've removed the CLEAR_PENDING_EXCEPTIONS I added experimentally from > this webrev, as this might be subtly changing semantics of the > resolveOrFail case. Okay ... but I'm not sure how to combine this with your responses to Karen. ?? David > /Claes From martinrb at google.com Tue Mar 27 00:21:16 2018 From: martinrb at google.com (Martin Buchholz) Date: Mon, 26 Mar 2018 17:21:16 -0700 Subject: RFR: Some patches for sherman Message-ID: 8200116: ConstructInflaterOutput, ConstructDeflaterInput still spamming test logs http://cr.openjdk.java.net/~martin/webrevs/jdk/ConstructInflaterOutput/ https://bugs.openjdk.java.net/browse/JDK-8200116 8200124: Various cleanups in jar/zip http://cr.openjdk.java.net/~martin/webrevs/jdk/zip-cleanup/ https://bugs.openjdk.java.net/browse/JDK-8200124 This one I'm not too sure about: The public fields of StandardCharsets are part of the public API, so they definitely need to exist. So let's create them directly (i.e. using "new", not Charset.forName) and don't bother putting these fields anywhere else. Motivation: I ran into trouble using reflection via StandardCharsets. too early during bootstrap with a local mod. 00000000: Avoid charset lookup machinery in StandardCharsets http://cr.openjdk.java.net/~martin/webrevs/jdk/StandardCharsets/ From claes.redestad at oracle.com Tue Mar 27 06:49:45 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 27 Mar 2018 08:49:45 +0200 Subject: RFR: 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull In-Reply-To: <2414aaf1-c7b0-56f0-58cd-84ee852e749f@oracle.com> References: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> <5829E498-2176-49C2-ACE8-5E7F232D2632@oracle.com> <2414aaf1-c7b0-56f0-58cd-84ee852e749f@oracle.com> Message-ID: On 2018-03-26 17:51, Claes Redestad wrote: > Karen, > > On 2018-03-26 17:15, Karen Kinnear wrote: >> Claes, >> >> Discussed with Lois. We think that it would make more sense to pass >> the new argument into MethodHandles::resolve_MemberName and at all >> three places that we currently CHECK_PENDING_EXCEPTION/return null there >> ??? - if speculative flag is set - CLEAR_PENDING_EXCEPTION before you >> return null >> ??? - and yes - do this for all three cases, not just the METHOD case > > ok. New webrev: http://cr.openjdk.java.net/~redestad/8200238/open.01/ Thanks! /Claes From david.holmes at oracle.com Tue Mar 27 07:03:44 2018 From: david.holmes at oracle.com (David Holmes) Date: Tue, 27 Mar 2018 17:03:44 +1000 Subject: RFR: 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull In-Reply-To: References: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> <5829E498-2176-49C2-ACE8-5E7F232D2632@oracle.com> <2414aaf1-c7b0-56f0-58cd-84ee852e749f@oracle.com> Message-ID: Hi Claes, This seems reasonable. Clearing the exception only when speculatively resolving is reasonable (it's similar to compilation clearing exceptions and falling back to interpreted mode). Thanks, David On 27/03/2018 4:49 PM, Claes Redestad wrote: > > > On 2018-03-26 17:51, Claes Redestad wrote: >> Karen, >> >> On 2018-03-26 17:15, Karen Kinnear wrote: >>> Claes, >>> >>> Discussed with Lois. We think that it would make more sense to pass >>> the new argument into MethodHandles::resolve_MemberName and at all >>> three places that we currently CHECK_PENDING_EXCEPTION/return null there >>> ??? - if speculative flag is set - CLEAR_PENDING_EXCEPTION before you >>> return null >>> ??? - and yes - do this for all three cases, not just the METHOD case >> >> ok. > > New webrev: > > http://cr.openjdk.java.net/~redestad/8200238/open.01/ > > Thanks! > > /Claes From claes.redestad at oracle.com Tue Mar 27 07:26:59 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 27 Mar 2018 09:26:59 +0200 Subject: RFR: 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull In-Reply-To: References: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> <5829E498-2176-49C2-ACE8-5E7F232D2632@oracle.com> <2414aaf1-c7b0-56f0-58cd-84ee852e749f@oracle.com> Message-ID: On 2018-03-27 09:03, David Holmes wrote: > Hi Claes, > > This seems reasonable. Clearing the exception only when speculatively > resolving is reasonable (it's similar to compilation clearing > exceptions and falling back to interpreted mode). Thanks David! For the record, it seems that in my (synthetic) tests we're often hitting the case where resolve_MemberName returns quickly due to the requested signature not being known to exist anywhere in the VM (the class we're resolving into is loaded and all signatures that can exist should be known). In these cases the linkResolver isn't even called and MHN_resolve_Mem returns empty(). Thus explaining why we are hitting the if (speculative_resolve) in MHN_resolve_Mem so often and confuse everyone. Thus for a certain type of speculative resolve, it seems we're actually down to throwing no exceptions at all, now. /Claes > > Thanks, > David From chris.hegarty at oracle.com Tue Mar 27 08:55:26 2018 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Tue, 27 Mar 2018 09:55:26 +0100 Subject: RFR: {@docRoot} reference need to be updated to reflect new module structure In-Reply-To: <5AB989CD.4020008@oracle.com> References: <5AB989CD.4020008@oracle.com> Message-ID: > On 27 Mar 2018, at 01:01, Jonathan Gibbons wrote: > > This is fixing up some links in the java.base module, following a recent change > in javadoc to the organization of the generated files. While the change was mostly > transparent, links within the documentation using {@docRoot} need to be updated. > > All the changes were done automatically, by the following sed commands, to insert > "/java.base" into the affected links. > > 's|{@docRoot}/java/lang/|{@docRoot}/java.base/java/lang/|' > 's|{@docRoot}/java/util/|{@docRoot}/java.base/java/util/|' > > JBS: https://bugs.openjdk.java.net/browse/JDK-8199465 > Webrev: http://cr.openjdk.java.net/~jjg/8199465/webrev.00/ Looks good to me Jon. -Chris. From Alan.Bateman at oracle.com Tue Mar 27 09:00:39 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 27 Mar 2018 10:00:39 +0100 Subject: RFR: {@docRoot} reference need to be updated to reflect new module structure In-Reply-To: <5AB989CD.4020008@oracle.com> References: <5AB989CD.4020008@oracle.com> Message-ID: On 27/03/2018 01:01, Jonathan Gibbons wrote: > This is fixing up some links in the java.base module, following a > recent change > in javadoc to the organization of the generated files. While the > change was mostly > transparent, links within the documentation using {@docRoot} need to > be updated. Looks okay to me. I assume Doug or Martin will need to update the java.util.concurrent classes in the jsr166 CVS too. -Alan From claes.redestad at oracle.com Tue Mar 27 10:20:24 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 27 Mar 2018 12:20:24 +0200 Subject: RFR: 8200289: Reduce number of exceptions created when calling Lookup::canBeCached Message-ID: <22d17936-7c9b-5217-c7a7-36ed38bf2e09@oracle.com> Hi, a simple refactoring of Lookup::canBeCached avoids throwing ~315 IAEs on nashorn/jjs bootstrap, and likely helpful elsewhere too. Bug: https://bugs.openjdk.java.net/browse/JDK-8200289 Webrev: http://cr.openjdk.java.net/~redestad/8200289/open.00/ Thanks! /Claes From sundararajan.athijegannathan at oracle.com Tue Mar 27 11:23:31 2018 From: sundararajan.athijegannathan at oracle.com (Sundararajan Athijegannathan) Date: Tue, 27 Mar 2018 16:53:31 +0530 Subject: RFR: 8200289: Reduce number of exceptions created when calling Lookup::canBeCached In-Reply-To: <22d17936-7c9b-5217-c7a7-36ed38bf2e09@oracle.com> References: <22d17936-7c9b-5217-c7a7-36ed38bf2e09@oracle.com> Message-ID: <5ABA29B3.7060701@oracle.com> Hi, + if (caller != null&& !VerifyAccess.isClassAccessible(refc, caller, allowedModes)) { + return false; + } + return true; can be return caller == null || VerifyAccess.isClassAccessible(refc, caller, allowedModes); +1 -Sundar On 27/03/18, 3:50 PM, Claes Redestad wrote: > Hi, > > a simple refactoring of Lookup::canBeCached avoids throwing ~315 IAEs > on nashorn/jjs bootstrap, and likely helpful elsewhere too. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8200289 > > Webrev: http://cr.openjdk.java.net/~redestad/8200289/open.00/ > > Thanks! > > /Claes > From claes.redestad at oracle.com Tue Mar 27 12:02:44 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 27 Mar 2018 14:02:44 +0200 Subject: RFR: 8200289: Reduce number of exceptions created when calling Lookup::canBeCached In-Reply-To: <5ABA29B3.7060701@oracle.com> References: <22d17936-7c9b-5217-c7a7-36ed38bf2e09@oracle.com> <5ABA29B3.7060701@oracle.com> Message-ID: Sundar, On 2018-03-27 13:23, Sundararajan Athijegannathan wrote: > Hi, > > +??????????? if (caller != null&& > !VerifyAccess.isClassAccessible(refc, caller, allowedModes)) { > +??????????????? return false; > +??????????? } > +??????????? return true; > > > can be > > ??? return caller == null || VerifyAccess.isClassAccessible(refc, > caller, allowedModes); agreed, updated in-place. > > +1 Thanks for reviewing! /Claes From Ulf.Zibis at CoSoCo.de Tue Mar 27 13:48:58 2018 From: Ulf.Zibis at CoSoCo.de (Ulf Zibis) Date: Tue, 27 Mar 2018 15:48:58 +0200 Subject: RFR: Some patches for sherman In-Reply-To: References: Message-ID: <484464ea-e7aa-9168-6a91-88ac15164a3c@CoSoCo.de> Fine enhancement! See also: JDK-6862158 : Make sun.nio.cs.* charset objects light-weight JDK-6796087 : Speed-up sun.nio.cs.StandardCharsets JDK-6790402 : Speed-up FastCharsetProvider -Ulf Am 27.03.2018 um 02:21 schrieb Martin Buchholz: > Motivation: I ran into trouble using reflection via > StandardCharsets. too early during bootstrap with a local mod. > > 00000000: Avoid charset lookup machinery in StandardCharsets > http://cr.openjdk.java.net/~martin/webrevs/jdk/StandardCharsets/ > From Alan.Bateman at oracle.com Tue Mar 27 15:10:33 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 27 Mar 2018 16:10:33 +0100 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> <10728b43-110c-5dc3-1fdb-2e0241e3a0ff@oracle.com> Message-ID: On 27/03/2018 00:09, David Lloyd wrote: > : > I think they may have use in some cases e.g. reading a dictionary from > a file, and generally in code which prefers byte buffers over arrays > (completely outside of the direct/heap buffer question), and they were > easy enough to implement. But I'm okay dropping these methods if that > is what is desired. I'm in two minds on the setDictionary methods. No objection to including them for consistency reasons, I'm just not sure if they will really be used. > : >> I also wonder if the parameter should be renamed to "input" or "source". > I was going for some kind of consistency with the array variants (that > is, name the parameter what it is), though they simply use "b" for > their parameter name so that interpretation might be a stretch. > Should I update them all? I think this would be good, if you don't mind doing it. > : > I'm not 100% familiar with the new JavaDoc categories (ok I'm 0% > familiar), but the JEP for these says "This category consists of > commentary, rationale, or examples pertaining to the API.". But this > feels more like specification to me since it is "specifications that > apply to all valid implementations, including preconditions, > postconditions, etc.". Which is to say, if you don't provide enough > remaining space in the output buffer, you will have incorrect > operation as a result. WDYT? The current wording (which pre-dates your changes of course) reads more like API advice. I think it's a bit confusing too as it doesn't define what a "flush marker" is. I think we will need to re-word that sentence to make it clearer. > >> I don't have cycles just now to go through all the implementation but I >> think Sherman is doing that. It will need careful review to avoid being >> abused to attack memory outside of the buffer. I did check the use of >> position() and limit() to calculate the remaining and these need correct. > I hope this was a typo of "these seem correct" and not a typo of > "these need correcting"? Oops, this was indeed a typo in my mail. -Alan From sean.mullan at oracle.com Tue Mar 27 15:15:59 2018 From: sean.mullan at oracle.com (Sean Mullan) Date: Tue, 27 Mar 2018 11:15:59 -0400 Subject: [11] RFR: 8193032: Remove terminally deprecated SecurityManager APIs Message-ID: Please remove this change to remove several SecurityManager methods that have been marked for removal since Java SE 9: checkTopLevelWindow, checkSystemClipboardAccess, checkAwtEventQueueAccess, and checkMemberAccess. These methods no longer have any benefit, and removing them will follow through on the the plan to remove them. We believe the compatibility risk is fairly low - we have only found a very small number of custom SecurityManager implementations that are overriding the methods and using @Override or calling the methods directly that will need to change their code. See the CSR for more info. webrev: http://cr.openjdk.java.net/~mullan/webrevs/8193032/webrev.00/ CSR: https://bugs.openjdk.java.net/browse/JDK-8200185 Thanks, Sean From Alan.Bateman at oracle.com Tue Mar 27 15:26:19 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 27 Mar 2018 16:26:19 +0100 Subject: [11] RFR: 8193032: Remove terminally deprecated SecurityManager APIs In-Reply-To: References: Message-ID: <452c3dc8-fb8e-2e67-05eb-96d5ec34175a@oracle.com> On 27/03/2018 16:15, Sean Mullan wrote: > Please remove this change to remove several SecurityManager methods > that have been marked for removal since Java SE 9: > checkTopLevelWindow, checkSystemClipboardAccess, > checkAwtEventQueueAccess, and checkMemberAccess. These methods no > longer have any benefit, and removing them will follow through on the > the plan to remove them. Right, these method were degraded to check AllPermission and I don't recall anyone screaming. This gives some confidence that they aren't widely used. So I think looks good. -Alan From sean.mullan at oracle.com Tue Mar 27 15:28:44 2018 From: sean.mullan at oracle.com (Sean Mullan) Date: Tue, 27 Mar 2018 11:28:44 -0400 Subject: [11] RFR: 8193032: Remove terminally deprecated SecurityManager APIs In-Reply-To: <452c3dc8-fb8e-2e67-05eb-96d5ec34175a@oracle.com> References: <452c3dc8-fb8e-2e67-05eb-96d5ec34175a@oracle.com> Message-ID: <6a4f26e9-06c1-b5cf-3585-3e8079530ad3@oracle.com> On 3/27/18 11:26 AM, Alan Bateman wrote: > On 27/03/2018 16:15, Sean Mullan wrote: >> Please remove this change to remove several SecurityManager methods >> that have been marked for removal since Java SE 9: >> checkTopLevelWindow, checkSystemClipboardAccess, >> checkAwtEventQueueAccess, and checkMemberAccess. These methods no >> longer have any benefit, and removing them will follow through on the >> the plan to remove them. > Right, these method were degraded to check AllPermission and I don't > recall anyone screaming. This gives some confidence that they aren't > widely used. So I think looks good. Thanks, and I obviously meant to say "Please *review* this change" above :) --Sean From martinrb at google.com Tue Mar 27 15:30:48 2018 From: martinrb at google.com (Martin Buchholz) Date: Tue, 27 Mar 2018 08:30:48 -0700 Subject: RFR: {@docRoot} reference need to be updated to reflect new module structure In-Reply-To: References: <5AB989CD.4020008@oracle.com> Message-ID: On Tue, Mar 27, 2018 at 2:00 AM, Alan Bateman wrote: > On 27/03/2018 01:01, Jonathan Gibbons wrote: > >> This is fixing up some links in the java.base module, following a recent >> change >> in javadoc to the organization of the generated files. While the change >> was mostly >> transparent, links within the documentation using {@docRoot} need to be >> updated. >> > Looks okay to me. I assume Doug or Martin will need to update the > java.util.concurrent classes in the jsr166 CVS too. Yes, this will cause some work for us, but go ahead and submit. These references with docRoot have always been trouble, since they're very brittle. Can't we fix these for real in the javadoc tool itself by by introducing a variant of @link that works for any anchor?! {@linkplain Collection#optional-restrictions optional} (You can fiddle with the syntax) Something like this should be easier to implement than all the docRoot fiddling we've been doing over the years. From jonathan.gibbons at oracle.com Tue Mar 27 15:34:04 2018 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Tue, 27 Mar 2018 08:34:04 -0700 Subject: RFR: {@docRoot} reference need to be updated to reflect new module structure In-Reply-To: References: <5AB989CD.4020008@oracle.com> Message-ID: On 3/27/18 8:30 AM, Martin Buchholz wrote: > > > On Tue, Mar 27, 2018 at 2:00 AM, Alan Bateman > wrote: > > On 27/03/2018 01:01, Jonathan Gibbons wrote: > > This is fixing up some links in the java.base module, > following a recent change > in javadoc to the organization of the generated files. While > the change was mostly > transparent, links within the documentation using {@docRoot} > need to be updated. > > Looks okay to me. I assume Doug or Martin will need to update the > java.util.concurrent classes in the jsr166 CVS too. > > > Yes, this will cause some work for us, but go ahead and submit. > These references with docRoot have always been trouble, since they're > very brittle. > Can't we fix these for real in the javadoc tool itself by by > introducing a variant of @link that works for any anchor?! > > {@linkplain Collection#optional-restrictions optional} > > (You can fiddle with the syntax) > Something like this should be easier to implement than all the docRoot > fiddling we've been doing over the years. Martin, Thanks for the review, and yes, the same desire to avoid these {@docRoot} links has already occurred to use. One suggestion that has been proposed is '##', such that ??? {@link package.class#member} works as before, but ??? {@link package.class##id} would allow references to user-defined anchors. -- Jon From lois.foltan at oracle.com Tue Mar 27 15:57:43 2018 From: lois.foltan at oracle.com (Lois Foltan) Date: Tue, 27 Mar 2018 11:57:43 -0400 Subject: RFR: 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull In-Reply-To: References: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> <5829E498-2176-49C2-ACE8-5E7F232D2632@oracle.com> <2414aaf1-c7b0-56f0-58cd-84ee852e749f@oracle.com> Message-ID: On 3/27/2018 2:49 AM, Claes Redestad wrote: > > > On 2018-03-26 17:51, Claes Redestad wrote: >> Karen, >> >> On 2018-03-26 17:15, Karen Kinnear wrote: >>> Claes, >>> >>> Discussed with Lois. We think that it would make more sense to pass >>> the new argument into MethodHandles::resolve_MemberName and at all >>> three places that we currently CHECK_PENDING_EXCEPTION/return null >>> there >>> ??? - if speculative flag is set - CLEAR_PENDING_EXCEPTION before >>> you return null >>> ??? - and yes - do this for all three cases, not just the METHOD case >> >> ok. > > New webrev: > > http://cr.openjdk.java.net/~redestad/8200238/open.01/ Hi Claes, Looks good.? One minor comment. hotspot/share/prims/methodHandles.cpp: - line #1237.? Consider putting some explanation in the assert statement instead of a blank string.? Something like "speculative resolve mode has encountered an unexpected pending exception" I don't need to see another webrev. Thanks, Lois > > Thanks! > > /Claes From martinrb at google.com Tue Mar 27 16:07:34 2018 From: martinrb at google.com (Martin Buchholz) Date: Tue, 27 Mar 2018 09:07:34 -0700 Subject: RFR: {@docRoot} reference need to be updated to reflect new module structure In-Reply-To: References: <5AB989CD.4020008@oracle.com> Message-ID: On Tue, Mar 27, 2018 at 8:34 AM, Jonathan Gibbons < jonathan.gibbons at oracle.com> wrote: > On 3/27/18 8:30 AM, Martin Buchholz wrote: > > > > On Tue, Mar 27, 2018 at 2:00 AM, Alan Bateman > wrote: > >> On 27/03/2018 01:01, Jonathan Gibbons wrote: >> >>> This is fixing up some links in the java.base module, following a recent >>> change >>> in javadoc to the organization of the generated files. While the change >>> was mostly >>> transparent, links within the documentation using {@docRoot} need to be >>> updated. >>> >> Looks okay to me. I assume Doug or Martin will need to update the >> java.util.concurrent classes in the jsr166 CVS too. > > > Yes, this will cause some work for us, but go ahead and submit. > These references with docRoot have always been trouble, since they're very > brittle. > Can't we fix these for real in the javadoc tool itself by by introducing a > variant of @link that works for any anchor?! > > {@linkplain Collection#optional-restrictions optional} > > (You can fiddle with the syntax) > Something like this should be easier to implement than all the docRoot > fiddling we've been doing over the years. > > > Martin, > > Thanks for the review, and yes, the same desire to avoid these {@docRoot} > links has already occurred to use. > > One suggestion that has been proposed is '##', such that > > {@link package.class#member} > > works as before, but > > {@link package.class##id} > > would allow references to user-defined anchors. > That syntax seems reasonable. I don't have a strong feeling about how to do it. As always with software, there are details to worry about. Unlike with @link there's no generated text, so caller must provide the text to be linkified. Maybe only linkplain should be supported. Maybe if there's no ambiguity and we can use a single '#' and using a '-' in the id guarantees no ambiguity? From paul.sandoz at oracle.com Tue Mar 27 16:07:39 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 27 Mar 2018 09:07:39 -0700 Subject: RFR: 8200289: Reduce number of exceptions created when calling Lookup::canBeCached In-Reply-To: References: <22d17936-7c9b-5217-c7a7-36ed38bf2e09@oracle.com> <5ABA29B3.7060701@oracle.com> Message-ID: 2038 MemberName resolveOrNull(byte refKind, MemberName member) throws ReflectiveOperationException { 2039 // do this before attempting to resolve 2040 if (!isClassAccessible(member.getDeclaringClass())) { 2041 return null; 2042 } 2043 Objects.requireNonNull(member.getName()); 2044 Objects.requireNonNull(member.getType()); 2045 return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull()); 2046 } 2047 2048 void checkSymbolicClass(Class refc) throws IllegalAccessException { 2049 if (!isClassAccessible(refc)) { 2050 throw new MemberName(refc).makeAccessException("symbolic reference class is not accessible", this); 2051 } 2052 } ... 2499 try { 2500 MemberName resolved2 = publicLookup().resolveOrNull(refKind, 2501 new MemberName(refKind, defc, member.getName(), member.getType())); 2502 if (resolved2 == null) { 2503 return false; 2504 } 2505 checkSecurityManager(defc, resolved2); 2506 } catch (ReflectiveOperationException | SecurityException ex) { 2507 return false; 2508 } Is it (or was it ever) possible for these methods paths to throw IllegalAccessException / ReflectiveOperationException? Paul. > On Mar 27, 2018, at 5:02 AM, Claes Redestad wrote: > > Sundar, > > On 2018-03-27 13:23, Sundararajan Athijegannathan wrote: >> Hi, >> >> + if (caller != null&& !VerifyAccess.isClassAccessible(refc, caller, allowedModes)) { >> + return false; >> + } >> + return true; >> >> >> can be >> >> return caller == null || VerifyAccess.isClassAccessible(refc, caller, allowedModes); > > agreed, updated in-place. > >> >> +1 > > Thanks for reviewing! > > /Claes From xueming.shen at oracle.com Tue Mar 27 16:24:24 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Tue, 27 Mar 2018 09:24:24 -0700 Subject: RFR: Some patches for sherman In-Reply-To: References: Message-ID: <5ABA7038.5050404@oracle.com> looks good for me. On 3/26/18, 5:21 PM, Martin Buchholz wrote: > > 8200116: ConstructInflaterOutput, ConstructDeflaterInput still > spamming test logs > http://cr.openjdk.java.net/~martin/webrevs/jdk/ConstructInflaterOutput/ > https://bugs.openjdk.java.net/browse/JDK-8200116 > > 8200124: Various cleanups in jar/zip > http://cr.openjdk.java.net/~martin/webrevs/jdk/zip-cleanup/ > > https://bugs.openjdk.java.net/browse/JDK-8200124 don't see any change in ZipCoder.java though. > > This one I'm not too sure about: > The public fields of StandardCharsets are part of the public API, so > they definitely need to exist. So let's create them directly (i.e. > using "new", not Charset.forName) and don't bother putting these > fields anywhere else. > > Motivation: I ran into trouble using reflection via > StandardCharsets. too early during bootstrap with a local mod. > > 00000000: Avoid charset lookup machinery in StandardCharsets > http://cr.openjdk.java.net/~martin/webrevs/jdk/StandardCharsets/ > > From claes.redestad at oracle.com Tue Mar 27 17:01:38 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Tue, 27 Mar 2018 19:01:38 +0200 Subject: RFR: 8200289: Reduce number of exceptions created when calling Lookup::canBeCached In-Reply-To: References: <22d17936-7c9b-5217-c7a7-36ed38bf2e09@oracle.com> <5ABA29B3.7060701@oracle.com> Message-ID: <6c65d997-41b3-c88f-02f1-8bca3937d1e4@oracle.com> Paul, On 2018-03-27 18:07, Paul Sandoz wrote: > 2047 > 2048 void checkSymbolicClass(Class refc) throws IllegalAccessException { > 2049 if (!isClassAccessible(refc)) { > 2050 throw new MemberName(refc).makeAccessException("symbolic reference class is not accessible", this); > 2051 } > 2052 } this one still throws IllegalAccessException, which extends ROE... > 2038 MemberName resolveOrNull(byte refKind, MemberName member) throws ReflectiveOperationException { > 2039 // do this before attempting to resolve > 2040 if (!isClassAccessible(member.getDeclaringClass())) { > 2041 return null; > 2042 } > 2043 Objects.requireNonNull(member.getName()); > 2044 Objects.requireNonNull(member.getType()); > 2045 return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull()); > 2046 } ... but is no longer used here. I'll remove the throws. > ... > 2499 try { > 2500 MemberName resolved2 = publicLookup().resolveOrNull(refKind, > 2501 new MemberName(refKind, defc, member.getName(), member.getType())); > 2502 if (resolved2 == null) { > 2503 return false; > 2504 } > 2505 checkSecurityManager(defc, resolved2); > 2506 } catch (ReflectiveOperationException | SecurityException ex) { > 2507 return false; > 2508 } ... nor here, so ROE can no longer be caught here. Removing. http://cr.openjdk.java.net/~redestad/8200289/open.01/ /Claes From david.lloyd at redhat.com Tue Mar 27 16:59:06 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Tue, 27 Mar 2018 11:59:06 -0500 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> <10728b43-110c-5dc3-1fdb-2e0241e3a0ff@oracle.com> Message-ID: On Tue, Mar 27, 2018 at 10:10 AM, Alan Bateman wrote: > On 27/03/2018 00:09, David Lloyd wrote: >> I was going for some kind of consistency with the array variants (that >> is, name the parameter what it is), though they simply use "b" for >> their parameter name so that interpretation might be a stretch. >> Should I update them all? > > I think this would be good, if you don't mind doing it. OK. >> I'm not 100% familiar with the new JavaDoc categories (ok I'm 0% >> familiar), but the JEP for these says "This category consists of >> commentary, rationale, or examples pertaining to the API.". But this >> feels more like specification to me since it is "specifications that >> apply to all valid implementations, including preconditions, >> postconditions, etc.". Which is to say, if you don't provide enough >> remaining space in the output buffer, you will have incorrect >> operation as a result. WDYT? > > The current wording (which pre-dates your changes of course) reads more like > API advice. I think it's a bit confusing too as it doesn't define what a > "flush marker" is. I think we will need to re-word that sentence to make it > clearer. OK. I am at a loss for a better way to explain it though; any suggestions? >>> I don't have cycles just now to go through all the implementation but I >>> think Sherman is doing that. It will need careful review to avoid being >>> abused to attack memory outside of the buffer. I did check the use of >>> position() and limit() to calculate the remaining and these need correct. >> >> I hope this was a typo of "these seem correct" and not a typo of >> "these need correcting"? > > Oops, this was indeed a typo in my mail. OK great. -- - DML From martinrb at google.com Tue Mar 27 17:42:37 2018 From: martinrb at google.com (Martin Buchholz) Date: Tue, 27 Mar 2018 10:42:37 -0700 Subject: RFR: Some patches for sherman In-Reply-To: <5ABA7038.5050404@oracle.com> References: <5ABA7038.5050404@oracle.com> Message-ID: On Tue, Mar 27, 2018 at 9:24 AM, Xueming Shen wrote: > >> 8200124: Various cleanups in jar/zip >> http://cr.openjdk.java.net/~martin/webrevs/jdk/zip-cleanup/ < >> http://cr.openjdk.java.net/%7Emartin/webrevs/jdk/zip-cleanup/> >> https://bugs.openjdk.java.net/browse/JDK-8200124 >> > > don't see any change in ZipCoder.java though. > > Whitespace only. > > >> This one I'm not too sure about: >> The public fields of StandardCharsets are part of the public API, so they >> definitely need to exist. So let's create them directly (i.e. using "new", >> not Charset.forName) and don't bother putting these fields anywhere else. >> >> Motivation: I ran into trouble using reflection via >> StandardCharsets. too early during bootstrap with a local mod. >> >> 00000000: Avoid charset lookup machinery in StandardCharsets >> http://cr.openjdk.java.net/~martin/webrevs/jdk/StandardCharsets/ < >> http://cr.openjdk.java.net/%7Emartin/webrevs/jdk/StandardCharsets/> >> > OK, this now has a real bug: 8200310: Avoid charset lookup machinery in java.nio.charset.StandardCharsets http://cr.openjdk.java.net/~martin/webrevs/jdk/StandardCharsets/ https://bugs.openjdk.java.net/browse/JDK-8200310 From martinrb at google.com Tue Mar 27 17:47:06 2018 From: martinrb at google.com (Martin Buchholz) Date: Tue, 27 Mar 2018 10:47:06 -0700 Subject: RFR: Some patches for sherman In-Reply-To: <484464ea-e7aa-9168-6a91-88ac15164a3c@CoSoCo.de> References: <484464ea-e7aa-9168-6a91-88ac15164a3c@CoSoCo.de> Message-ID: On Tue, Mar 27, 2018 at 6:48 AM, Ulf Zibis wrote: > Fine enhancement > Thanks. > See also: > JDK-6862158 : Make > sun.nio.cs.* charset objects light-weight > JDK-6796087 : > Speed-up sun.nio.cs.StandardCharsets > JDK-6790402 : > Speed-up FastCharsetProvider I guess Nelson Dcosta had a plan to improve charsets many years ago, but the project was never finished? (hmmmm ... me too ...) From martinrb at google.com Tue Mar 27 18:28:43 2018 From: martinrb at google.com (Martin Buchholz) Date: Tue, 27 Mar 2018 11:28:43 -0700 Subject: RFR: Here are some Thread cleanup patches Message-ID: The usual story when I change Thread.java is that I'm missing something and I end up reverting, so I was extra careful this time. 8200122: Remove unused field Thread.threadQ http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-threadQ/ https://bugs.openjdk.java.net/browse/JDK-8200122 8200123: Replace Thread.init with telescoping constructor http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-init/ https://bugs.openjdk.java.net/browse/JDK-8200123 From sergei.tsypanov at yandex.ru Tue Mar 27 20:41:06 2018 From: sergei.tsypanov at yandex.ru (=?utf-8?B?0KHQtdGA0LPQtdC5INCm0YvQv9Cw0L3QvtCy?=) Date: Tue, 27 Mar 2018 22:41:06 +0200 Subject: Inefficient indexOf called inside of CopyOnWriteArrayList$COWSubList.remove(Object) In-Reply-To: References: <3867991521785065@web23g.yandex.ru> Message-ID: <1026151522183266@web28g.yandex.ru> Thanks! 26.03.2018, 20:58, "Martin Buchholz" : > I filed > https://bugs.openjdk.java.net/browse/JDK-8200258 > and added comment: > > I agree that CopyOnWriteArrayList subList code can be improved. > We should stop subclassing AbstractList. > We should add more tests. > We should have more guidance about when to use index-based API - only when quiescent?or thread-confined. Explain how to most efficiently create a snapshot - probably > ?snapshot = new CopyOnWriteArrayList(sharedCOWAL) From paul.sandoz at oracle.com Tue Mar 27 20:45:09 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Tue, 27 Mar 2018 13:45:09 -0700 Subject: RFR: 8200289: Reduce number of exceptions created when calling Lookup::canBeCached In-Reply-To: <6c65d997-41b3-c88f-02f1-8bca3937d1e4@oracle.com> References: <22d17936-7c9b-5217-c7a7-36ed38bf2e09@oracle.com> <5ABA29B3.7060701@oracle.com> <6c65d997-41b3-c88f-02f1-8bca3937d1e4@oracle.com> Message-ID: +1 Paul. > On Mar 27, 2018, at 10:01 AM, Claes Redestad wrote: > > Paul, > > On 2018-03-27 18:07, Paul Sandoz wrote: > >> 2047 >> 2048 void checkSymbolicClass(Class refc) throws IllegalAccessException { >> 2049 if (!isClassAccessible(refc)) { >> 2050 throw new MemberName(refc).makeAccessException("symbolic reference class is not accessible", this); >> 2051 } >> 2052 } > > this one still throws IllegalAccessException, which extends ROE... > >> 2038 MemberName resolveOrNull(byte refKind, MemberName member) throws ReflectiveOperationException { >> 2039 // do this before attempting to resolve >> 2040 if (!isClassAccessible(member.getDeclaringClass())) { >> 2041 return null; >> 2042 } >> 2043 Objects.requireNonNull(member.getName()); >> 2044 Objects.requireNonNull(member.getType()); >> 2045 return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull()); >> 2046 } > > ... but is no longer used here. I'll remove the throws. > > >> ... >> 2499 try { >> 2500 MemberName resolved2 = publicLookup().resolveOrNull(refKind, >> 2501 new MemberName(refKind, defc, member.getName(), member.getType())); >> 2502 if (resolved2 == null) { >> 2503 return false; >> 2504 } >> 2505 checkSecurityManager(defc, resolved2); >> 2506 } catch (ReflectiveOperationException | SecurityException ex) { >> 2507 return false; >> 2508 } > > ... nor here, so ROE can no longer be caught here. Removing. > > http://cr.openjdk.java.net/~redestad/8200289/open.01/ > > /Claes From jonathan.gibbons at oracle.com Tue Mar 27 21:11:21 2018 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Tue, 27 Mar 2018 14:11:21 -0700 Subject: RFR: {@docRoot} reference need to be updated to reflect new module structure In-Reply-To: References: <5AB989CD.4020008@oracle.com> Message-ID: On 3/27/18 9:07 AM, Martin Buchholz wrote: > > > On Tue, Mar 27, 2018 at 8:34 AM, Jonathan Gibbons > > wrote: > > On 3/27/18 8:30 AM, Martin Buchholz wrote: > >> >> >> On Tue, Mar 27, 2018 at 2:00 AM, Alan Bateman >> > wrote: >> >> On 27/03/2018 01:01, Jonathan Gibbons wrote: >> >> This is fixing up some links in the java.base module, >> following a recent change >> in javadoc to the organization of the generated files. >> While the change was mostly >> transparent, links within the documentation using >> {@docRoot} need to be updated. >> >> Looks okay to me. I assume Doug or Martin will need to update >> the java.util.concurrent classes in the jsr166 CVS too. >> >> >> Yes, this will cause some work for us, but go ahead and submit. >> These references with docRoot have always been trouble, since >> they're very brittle. >> Can't we fix these for real in the javadoc tool itself by by >> introducing a variant of @link that works for any anchor?! >> >> {@linkplain Collection#optional-restrictions optional} >> >> (You can fiddle with the syntax) >> Something like this should be easier to implement than all the >> docRoot fiddling we've been doing over the years. > > Martin, > > Thanks for the review, and yes, the same desire to avoid these > {@docRoot} links has already occurred to use. > > One suggestion that has been proposed is '##', such that > > ??? {@link package.class#member} > > works as before, but > > ??? {@link package.class##id} > > would allow references to user-defined anchors. > > > That syntax seems reasonable.? I don't have a strong feeling about how > to do it.? As always with software, there are details to worry about.? > Unlike with @link there's no generated text, so caller must provide > the text to be linkified. Maybe only linkplain should be supported.? > Maybe if? there's no ambiguity and we can use a single '#' and using a > '-' in the id guarantees no ambiguity? > JDK-8200337 -- Jon From mandy.chung at oracle.com Tue Mar 27 22:12:03 2018 From: mandy.chung at oracle.com (mandy chung) Date: Wed, 28 Mar 2018 06:12:03 +0800 Subject: [11] RFR: 8193032: Remove terminally deprecated SecurityManager APIs In-Reply-To: References: Message-ID: <0f734830-1fef-caa2-59b0-d64ffccc8212@oracle.com> On 3/27/18 11:15 PM, Sean Mullan wrote: > Please remove this change to remove several SecurityManager methods > that have been marked for removal since Java SE 9: > checkTopLevelWindow, checkSystemClipboardAccess, > checkAwtEventQueueAccess, and checkMemberAccess. These methods no > longer have any benefit, and removing them will follow through on the > the plan to remove them. > > We believe the compatibility risk is fairly low - we have only found a > very small number of custom SecurityManager implementations that are > overriding the methods and using @Override or calling the methods > directly that will need to change their code. See the CSR for more info. > > webrev: http://cr.openjdk.java.net/~mullan/webrevs/8193032/webrev.00/ > CSR: https://bugs.openjdk.java.net/browse/JDK-8200185 This looks good to me. Mandy From david.holmes at oracle.com Tue Mar 27 23:42:24 2018 From: david.holmes at oracle.com (David Holmes) Date: Wed, 28 Mar 2018 09:42:24 +1000 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: References: Message-ID: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> Hi Martin, On 28/03/2018 4:28 AM, Martin Buchholz wrote: > The usual story when I change Thread.java is that I'm missing something and > I end up reverting, so I was extra careful this time. > > 8200122: Remove unused field Thread.threadQ > http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-threadQ/ > https://bugs.openjdk.java.net/browse/JDK-8200122 Looks fine. > 8200123: Replace Thread.init with telescoping constructor > http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-init/ > https://bugs.openjdk.java.net/browse/JDK-8200123 Looks fine - for some reason I thought we had a direct VM call to init() but we don't. What is the effect of @stable? I'm just thinking about any possible impact on initialization order. Thanks, David From weijun.wang at oracle.com Tue Mar 27 23:52:40 2018 From: weijun.wang at oracle.com (Weijun Wang) Date: Wed, 28 Mar 2018 07:52:40 +0800 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <32db4add-8a59-03db-0074-e7df0aed14b8@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> <86488d2c-61e3-e489-d9fc-976178c35775@oracle.com> <2329dea1-a75e-bb70-95a6-242a93006c6d@oracle.com> <32db4add-8a59-03db-0074-e7df0aed14b8@oracle.com> Message-ID: > On Mar 24, 2018, at 6:03 AM, Magnus Ihse Bursie wrote: > > https://bugs.openjdk.java.net/browse/JDK-8200193 -- for jdk.security.auth There is only one function to export and it already has JNIEXPORT, so you can just remove the new $(LIBJAAS_CFLAGS) [1]. Are you going to update your webrev? Thanks Max [1] http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01/make/lib/Lib-jdk.security.auth.gmk.sdiff.html From martinrb at google.com Wed Mar 28 00:48:09 2018 From: martinrb at google.com (Martin Buchholz) Date: Tue, 27 Mar 2018 17:48:09 -0700 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> Message-ID: On Tue, Mar 27, 2018 at 4:42 PM, David Holmes wrote: > Hi Martin, > > 8200123: Replace Thread.init with telescoping constructor >> http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-init/ >> https://bugs.openjdk.java.net/browse/JDK-8200123 >> > > Looks fine - for some reason I thought we had a direct VM call to init() > but we don't. > > What is the effect of @stable? I'm just thinking about any possible impact > on initialization order. > @Stable final just means the VM can really truly assume the value will only ever change from the default value once. Like a per-field -XX:+TrustFinalNonStaticFields http://www.progdoc.de/papers/JET2015/How_final_is_final.pdf http://hg.openjdk.java.net/jdk/jdk/file/b6671a111395/src/java.base/share/classes/jdk/internal/vm/annotation/Stable.java From david.holmes at oracle.com Wed Mar 28 00:56:56 2018 From: david.holmes at oracle.com (David Holmes) Date: Wed, 28 Mar 2018 10:56:56 +1000 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> Message-ID: On 28/03/2018 10:48 AM, Martin Buchholz wrote: > On Tue, Mar 27, 2018 at 4:42 PM, David Holmes > wrote: > > Hi Martin, > > 8200123: Replace Thread.init with telescoping constructor > http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-init/ > > https://bugs.openjdk.java.net/browse/JDK-8200123 > > > > Looks fine - for some reason I thought we had a direct VM call to > init() but we don't. > > What is the effect of @stable? I'm just thinking about any possible > impact on initialization order. > > > @Stable final > just means the VM can really truly assume the value will only ever > change from the default value once. > Like a per-field -XX:+TrustFinalNonStaticFields > http://www.progdoc.de/papers/JET2015/How_final_is_final.pdf > http://hg.openjdk.java.net/jdk/jdk/file/b6671a111395/src/java.base/share/classes/jdk/internal/vm/annotation/Stable.java Yep I grok the semantics, but am wondering about the actual runtime impact. Is the Stable annotation class going to have to be loaded and processed when Thread is initialized? Will this change the initialization order? Thanks, David From martinrb at google.com Wed Mar 28 01:24:20 2018 From: martinrb at google.com (Martin Buchholz) Date: Tue, 27 Mar 2018 18:24:20 -0700 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> Message-ID: On Tue, Mar 27, 2018 at 5:56 PM, David Holmes wrote: > >> @Stable final >> just means the VM can really truly assume the value will only ever change >> from the default value once. >> Like a per-field -XX:+TrustFinalNonStaticFields >> http://www.progdoc.de/papers/JET2015/How_final_is_final.pdf >> http://hg.openjdk.java.net/jdk/jdk/file/b6671a111395/src/jav >> a.base/share/classes/jdk/internal/vm/annotation/Stable.java >> > > Yep I grok the semantics, but am wondering about the actual runtime > impact. Is the Stable annotation class going to have to be loaded and > processed when Thread is initialized? Will this change the initialization > order? > I don't know. But given that the annotation only works with the bootstrap loader, we had better hope it is safe with Thread. At least the VM doesn't have to run any risky java code, and is also free to ignore the annotation if it's too early. From martinrb at google.com Wed Mar 28 01:50:31 2018 From: martinrb at google.com (Martin Buchholz) Date: Tue, 27 Mar 2018 18:50:31 -0700 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> Message-ID: On Tue, Mar 27, 2018 at 6:24 PM, Martin Buchholz wrote: > At least the VM doesn't have to run any risky java code > ?? Why is Martin so sure ?? Let's check: java -Xlog:class+load=trace -version |& grep -Ew 'annotation|lang.Thread' [0.010s][info ][class,load] java.lang.Thread source: jrt:/java.base [0.010s][info ][class,load] java.lang.Thread$UncaughtExceptionHandler source: jrt:/java.base [0.012s][info ][class,load] java.lang.annotation.Annotation source: jrt:/java.base So Stable does __not__ have to be class-loaded when Thread is class-loaded. From david.holmes at oracle.com Wed Mar 28 01:59:13 2018 From: david.holmes at oracle.com (David Holmes) Date: Wed, 28 Mar 2018 11:59:13 +1000 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> Message-ID: <4661e623-27a2-ff4b-32eb-8c989adb52ec@oracle.com> On 28/03/2018 11:50 AM, Martin Buchholz wrote: > > > On Tue, Mar 27, 2018 at 6:24 PM, Martin Buchholz > wrote: > > ?At least the VM doesn't have to run any risky java code > > > ??? Why is Martin so sure ?? > Let's check: > > java -Xlog:class+load=trace -version |& grep -Ew 'annotation|lang.Thread' > [0.010s][info ][class,load] java.lang.Thread source: jrt:/java.base > [0.010s][info ][class,load] java.lang.Thread$UncaughtExceptionHandler > source: jrt:/java.base > [0.012s][info ][class,load] java.lang.annotation.Annotation source: > jrt:/java.base > > So Stable does __not__ have to be class-loaded when Thread is class-loaded. Can you check with class+initialization please. Thanks, David From martinrb at google.com Wed Mar 28 02:07:13 2018 From: martinrb at google.com (Martin Buchholz) Date: Tue, 27 Mar 2018 19:07:13 -0700 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: <4661e623-27a2-ff4b-32eb-8c989adb52ec@oracle.com> References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> <4661e623-27a2-ff4b-32eb-8c989adb52ec@oracle.com> Message-ID: java -Xlog:class+init=trace -version |& grep -Ew 'annotation|lang.Thread|Stable' [0.019s][info][class,init] 10 Initializing 'java/lang/Thread' (0x00000007c0006400) Intuitively, class+init should be a subset of class+load, and the experiment above supports that. On Tue, Mar 27, 2018 at 6:59 PM, David Holmes wrote: > On 28/03/2018 11:50 AM, Martin Buchholz wrote: > >> >> >> On Tue, Mar 27, 2018 at 6:24 PM, Martin Buchholz > > wrote: >> >> At least the VM doesn't have to run any risky java code >> >> >> ?? Why is Martin so sure ?? >> Let's check: >> >> java -Xlog:class+load=trace -version |& grep -Ew 'annotation|lang.Thread' >> [0.010s][info ][class,load] java.lang.Thread source: jrt:/java.base >> [0.010s][info ][class,load] java.lang.Thread$UncaughtExceptionHandler >> source: jrt:/java.base >> [0.012s][info ][class,load] java.lang.annotation.Annotation source: >> jrt:/java.base >> >> So Stable does __not__ have to be class-loaded when Thread is >> class-loaded. >> > > Can you check with class+initialization please. > > Thanks, > David > > From david.holmes at oracle.com Wed Mar 28 02:21:22 2018 From: david.holmes at oracle.com (David Holmes) Date: Wed, 28 Mar 2018 12:21:22 +1000 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> <4661e623-27a2-ff4b-32eb-8c989adb52ec@oracle.com> Message-ID: <178a4d1b-6ff6-677f-90c7-aa1bfafab6e0@oracle.com> On 28/03/2018 12:07 PM, Martin Buchholz wrote: > java -Xlog:class+init=trace -version |& grep -Ew > 'annotation|lang.Thread|Stable' > [0.019s][info][class,init] 10 Initializing 'java/lang/Thread' > (0x00000007c0006400) Thanks. > Intuitively, class+init should be a subset of class+load, and the > experiment above supports that. The initialization order can be quite different to the load order. David > On Tue, Mar 27, 2018 at 6:59 PM, David Holmes > wrote: > > On 28/03/2018 11:50 AM, Martin Buchholz wrote: > > > > On Tue, Mar 27, 2018 at 6:24 PM, Martin Buchholz > > >> wrote: > > ? ? ??At least the VM doesn't have to run any risky java code > > > ??? Why is Martin so sure ?? > Let's check: > > java -Xlog:class+load=trace -version |& grep -Ew > 'annotation|lang.Thread' > [0.010s][info ][class,load] java.lang.Thread source: jrt:/java.base > [0.010s][info ][class,load] > java.lang.Thread$UncaughtExceptionHandler source: jrt:/java.base > [0.012s][info ][class,load] java.lang.annotation.Annotation > source: jrt:/java.base > > So Stable does __not__ have to be class-loaded when Thread is > class-loaded. > > > Can you check with class+initialization please. > > Thanks, > David > > From peter.levart at gmail.com Wed Mar 28 06:37:16 2018 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 28 Mar 2018 08:37:16 +0200 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: <178a4d1b-6ff6-677f-90c7-aa1bfafab6e0@oracle.com> References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> <4661e623-27a2-ff4b-32eb-8c989adb52ec@oracle.com> <178a4d1b-6ff6-677f-90c7-aa1bfafab6e0@oracle.com> Message-ID: <7cddbe60-c091-c87b-74c5-796e46294fe4@gmail.com> Hi, As far as I think (but please prove me wrong), Stable class is not loaded until someone explicitly asks for it in Java code (referring to Stable type in bytecode like with Stable.class literal or parsing annotations of a field that contains such annotation triggered by Java API for annotations). The VM code that parses some annotations like @Stable, @CallerSensitive, @ForceInline, etc... works by matching the Symbol names of annotation classes and doesn't need the to load the annotation class for that. See parse_annotations in classFileParser.cpp... Regards, Peter On 03/28/18 04:21, David Holmes wrote: > On 28/03/2018 12:07 PM, Martin Buchholz wrote: >> java -Xlog:class+init=trace -version |& grep -Ew >> 'annotation|lang.Thread|Stable' >> [0.019s][info][class,init] 10 Initializing 'java/lang/Thread' >> (0x00000007c0006400) > > Thanks. > >> Intuitively, class+init should be a subset of class+load, and the >> experiment above supports that. > > The initialization order can be quite different to the load order. > > David > >> On Tue, Mar 27, 2018 at 6:59 PM, David Holmes >> > wrote: >> >> ??? On 28/03/2018 11:50 AM, Martin Buchholz wrote: >> >> >> >> ??????? On Tue, Mar 27, 2018 at 6:24 PM, Martin Buchholz >> ??????? >> ??????? >> >> wrote: >> >> ???????? ? ? ??At least the VM doesn't have to run any risky java code >> >> >> ??????? ??? Why is Martin so sure ?? >> ??????? Let's check: >> >> ??????? java -Xlog:class+load=trace -version |& grep -Ew >> ??????? 'annotation|lang.Thread' >> ??????? [0.010s][info ][class,load] java.lang.Thread source: >> jrt:/java.base >> ??????? [0.010s][info ][class,load] >> ??????? java.lang.Thread$UncaughtExceptionHandler source: jrt:/java.base >> ??????? [0.012s][info ][class,load] java.lang.annotation.Annotation >> ??????? source: jrt:/java.base >> >> ??????? So Stable does __not__ have to be class-loaded when Thread is >> ??????? class-loaded. >> >> >> ??? Can you check with class+initialization please. >> >> ??? Thanks, >> ??? David >> >> From ivan.gerasimov at oracle.com Wed Mar 28 07:10:22 2018 From: ivan.gerasimov at oracle.com (Ivan Gerasimov) Date: Wed, 28 Mar 2018 00:10:22 -0700 Subject: [11] RFR: 8191410 : Unicode 10.0.0 In-Reply-To: <6d3c2e65-c144-280d-cd31-3eeb6ed3417d@oracle.com> References: <6d3c2e65-c144-280d-cd31-3eeb6ed3417d@oracle.com> Message-ID: <838debf9-8007-723c-4464-710b51565db3@oracle.com> Thanks Rachna! On 3/13/18 2:28 AM, Rachna Goel wrote: > > Hi Roger, Ivan, > > There is no change in algorithm as such but there has been mainly > stability improvements, defects fixed, performance enhancements. e.g > Updated header check, version and loading for latest binary files, > Simple case mappings will be more efficient as unnecessary checking > has been removed. > complete list of changes can be found at: > > http://bugs.icu-project.org/trac/query?status=closed&resolution=fixed&resolution=fixedbyotherticket&milestone=60.1&milestone=60.2&group=project&max=999&col=id&col=summary&col=resolution&col=milestone&col=status&col=owner&col=type&col=priority&col=project&col=weeks&order=priority > > Also, I have incorporated suggestions given from Ivan. > Kindly have a look at updated webrev: > > http://cr.openjdk.java.net/~rgoel/JDK-8191410/webrev.01/ > Please update the comment at the line 675 in Character.java: * 638 - the expected number of entities Please also update the test test/jdk/java/lang/Character/UnicodeBlock/OptimalMapSize.java: the expected capacity 510 needs to be replaced with 638 With kind regards, Ivan > Thanks, > Rachna > > > On 3/8/18 9:47 PM, Roger Riggs wrote: >> Hi Rachna, >> >> sun/text/normalizer/NormalizerImpl.java: >> >> Is there a higher level description of the algorithmic changes? >> >> 102-105: These look like accidental changes: the space should not >> be removed and the trailing "{" doesn't make sense in a comment. >> >> Regards, Roger >> >> >> On 3/8/2018 6:56 AM, Rachna Goel wrote: >>> Hi, >>> >>> Please review the proposed changes for JDK-819410. >>> >>> Bug : https://bugs.openjdk.java.net/browse/JDK-8191410 >>> >>> proposed changeset is located at : >>> >>> http://cr.openjdk.java.net/~rgoel/JDK-8191410/webrev/ >>> >>> This serves as the implementation for JEP 327. >>> >> > > -- > Thanks, > Rachna -- With kind regards, Ivan Gerasimov From mandy.chung at oracle.com Wed Mar 28 09:32:15 2018 From: mandy.chung at oracle.com (mandy chung) Date: Wed, 28 Mar 2018 17:32:15 +0800 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> Message-ID: On 28/03/2018 4:28 AM, Martin Buchholz wrote: > The usual story when I change Thread.java is that I'm missing something and > I end up reverting, so I was extra careful this time. > > 8200122: Remove unused field Thread.threadQ > http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-threadQ/ > https://bugs.openjdk.java.net/browse/JDK-8200122 Looks fine. > 8200123: Replace Thread.init with telescoping constructor > http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-init/ > https://bugs.openjdk.java.net/browse/JDK-8200123 Looks good too. Did you see any performance difference with and without @Stable? Mandy From mandy.chung at oracle.com Wed Mar 28 09:33:58 2018 From: mandy.chung at oracle.com (mandy chung) Date: Wed, 28 Mar 2018 17:33:58 +0800 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: <7cddbe60-c091-c87b-74c5-796e46294fe4@gmail.com> References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> <4661e623-27a2-ff4b-32eb-8c989adb52ec@oracle.com> <178a4d1b-6ff6-677f-90c7-aa1bfafab6e0@oracle.com> <7cddbe60-c091-c87b-74c5-796e46294fe4@gmail.com> Message-ID: <714c8c02-157e-a343-f8e6-9c4408d68e50@oracle.com> On 3/28/18 2:37 PM, Peter Levart wrote: > Hi, > > As far as I think (but please prove me wrong), Stable class is not > loaded until someone explicitly asks for it in Java code (referring to > Stable type in bytecode like with Stable.class literal or parsing > annotations of a field that contains such annotation triggered by Java > API for annotations). > > The VM code that parses some annotations like @Stable, > @CallerSensitive, @ForceInline, etc... works by matching the Symbol > names of annotation classes and doesn't need the to load the > annotation class for that. See parse_annotations in > classFileParser.cpp... > This is what I understand too.? VM parses the annotation attributes directly and no need to load any annotation class. Mandy From magnus.ihse.bursie at oracle.com Wed Mar 28 10:31:49 2018 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Wed, 28 Mar 2018 12:31:49 +0200 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> <86488d2c-61e3-e489-d9fc-976178c35775@oracle.com> <2329dea1-a75e-bb70-95a6-242a93006c6d@oracle.com> <32db4add-8a59-03db-0074-e7df0aed14b8@oracle.com> Message-ID: <3fce1a22-39e4-b8ba-0713-03cd013a6709@oracle.com> On 2018-03-28 01:52, Weijun Wang wrote: > >> On Mar 24, 2018, at 6:03 AM, Magnus Ihse Bursie wrote: >> >> https://bugs.openjdk.java.net/browse/JDK-8200193 -- for jdk.security.auth > There is only one function to export and it already has JNIEXPORT, so you can just remove the new $(LIBJAAS_CFLAGS) [1]. Ok, thanks Max! > Are you going to update your webrev? Here is a new webrev. It includes your recommended change in Lib-jdk.security.auth.gmk. It is also updated to keep track of changes in shared native libraries that has happend in the mainline since my first webrev. Most notably is the addition of libjsig. For now, I have just added the JNIEXPORT markers for the platforms that need it. Hopefully we can unify libjsig across all platforms, but that seems to be more complicated than I thought, so that'll have to wait. I have also recieved word from Phil Race that there were no testing issues for client, so he's happy as well. Updated webrev: http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.03 /Magnus > > Thanks > Max > > [1] http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01/make/lib/Lib-jdk.security.auth.gmk.sdiff.html From peter.levart at gmail.com Wed Mar 28 10:34:16 2018 From: peter.levart at gmail.com (Peter Levart) Date: Wed, 28 Mar 2018 12:34:16 +0200 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> Message-ID: On 03/28/2018 11:32 AM, mandy chung wrote: > On 28/03/2018 4:28 AM, Martin Buchholz wrote: > > The usual story when I change Thread.java is that I'm missing > something and > > I end up reverting, so I was extra careful this time. > > > > 8200122: Remove unused field Thread.threadQ > > http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-threadQ/ > > https://bugs.openjdk.java.net/browse/JDK-8200122 > > Looks fine. > > > 8200123: Replace Thread.init with telescoping constructor > > http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-init/ > > https://bugs.openjdk.java.net/browse/JDK-8200123 > > Looks good too. > > Did you see any performance difference with and without @Stable? > > Mandy I doubt there would be any. @Stable is only effective when the reference to an object containing the annotated field can be constant folded by JIT. And Thread objects are typically not assigned to static final field(s) or (by transitivity) to @Stable fields. Thread.currentThread() could be an exception, but it's not a constant. It's a thread-local constant, so a possible optimization would be for JIT to cache Thread's @Stable fields in a thread-local storage, but I doubt it is programmed to do so. VM experts, please advise! Regards, Peter From mandy.chung at oracle.com Wed Mar 28 11:30:24 2018 From: mandy.chung at oracle.com (mandy chung) Date: Wed, 28 Mar 2018 19:30:24 +0800 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> Message-ID: <25cf9047-8169-5864-6b24-4a1a32997c1c@oracle.com> On 3/28/18 6:34 PM, Peter Levart wrote: > > > On 03/28/2018 11:32 AM, mandy chung wrote: >> On 28/03/2018 4:28 AM, Martin Buchholz wrote: >> > The usual story when I change Thread.java is that I'm missing >> something and >> > I end up reverting, so I was extra careful this time. >> > >> > 8200122: Remove unused field Thread.threadQ >> > http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-threadQ/ >> > https://bugs.openjdk.java.net/browse/JDK-8200122 >> >> Looks fine. >> >> > 8200123: Replace Thread.init with telescoping constructor >> > http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-init/ >> > https://bugs.openjdk.java.net/browse/JDK-8200123 >> >> Looks good too. >> >> Did you see any performance difference with and without @Stable? >> >> Mandy > > I doubt there would be any. @Stable is only effective when the > reference to an object containing the annotated field can be constant > folded by JIT. And Thread objects are typically not assigned to static > final field(s) or (by transitivity) to @Stable fields. > Thread.currentThread() could be an exception, but it's not a constant. > It's a thread-local constant, so a possible optimization would be for > JIT to cache Thread's @Stable fields in a thread-local storage, but I > doubt it is programmed to do so. > I was wondering how Martin made the decision to mark it with @Stable. In addition to the above, the ID is mostly used in tracing.? I'd like to see performance number for adding @Stable. Mandy > VM experts, please advise! > > Regards, Peter > From david.lloyd at redhat.com Wed Mar 28 13:14:39 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 28 Mar 2018 08:14:39 -0500 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> <10728b43-110c-5dc3-1fdb-2e0241e3a0ff@oracle.com> Message-ID: On Tue, Mar 27, 2018 at 11:59 AM, David Lloyd wrote: > On Tue, Mar 27, 2018 at 10:10 AM, Alan Bateman wrote: >> On 27/03/2018 00:09, David Lloyd wrote: >>> I was going for some kind of consistency with the array variants (that >>> is, name the parameter what it is), though they simply use "b" for >>> their parameter name so that interpretation might be a stretch. >>> Should I update them all? >> >> I think this would be good, if you don't mind doing it. > > OK. > >>> I'm not 100% familiar with the new JavaDoc categories (ok I'm 0% >>> familiar), but the JEP for these says "This category consists of >>> commentary, rationale, or examples pertaining to the API.". But this >>> feels more like specification to me since it is "specifications that >>> apply to all valid implementations, including preconditions, >>> postconditions, etc.". Which is to say, if you don't provide enough >>> remaining space in the output buffer, you will have incorrect >>> operation as a result. WDYT? >> >> The current wording (which pre-dates your changes of course) reads more like >> API advice. I think it's a bit confusing too as it doesn't define what a >> "flush marker" is. I think we will need to re-word that sentence to make it >> clearer. > > OK. I am at a loss for a better way to explain it though; any suggestions? I've implemented all the other changes except for this one. Latest version is attached, online version is here [1]. [1] https://github.com/dmlloyd/openjdk/commit/zlib-bytebuffer-v18 -- - DML -------------- next part -------------- commit 55e4df2ab3c7ccb68426bc90f3cc5d2d1a3de96e Author: David M. Lloyd Date: Fri Feb 16 11:00:10 2018 -0600 [JDK-6341887] Update Inflater/Deflater to handle ByteBuffer diff --git a/make/mapfiles/libzip/mapfile-vers b/make/mapfiles/libzip/mapfile-vers index d711d8e17f4..11ccc2d6ecb 100644 --- a/make/mapfiles/libzip/mapfile-vers +++ b/make/mapfiles/libzip/mapfile-vers @@ -33,20 +33,28 @@ SUNWprivate_1.1 { Java_java_util_zip_CRC32_update; Java_java_util_zip_CRC32_updateBytes0; Java_java_util_zip_CRC32_updateByteBuffer0; - Java_java_util_zip_Deflater_deflateBytes; + Java_java_util_zip_Deflater_deflateBytesBytes; + Java_java_util_zip_Deflater_deflateBytesBuffer; + Java_java_util_zip_Deflater_deflateBufferBytes; + Java_java_util_zip_Deflater_deflateBufferBuffer; Java_java_util_zip_Deflater_end; Java_java_util_zip_Deflater_getAdler; Java_java_util_zip_Deflater_init; Java_java_util_zip_Deflater_initIDs; Java_java_util_zip_Deflater_reset; Java_java_util_zip_Deflater_setDictionary; + Java_java_util_zip_Deflater_setDictionaryBuffer; Java_java_util_zip_Inflater_end; Java_java_util_zip_Inflater_getAdler; - Java_java_util_zip_Inflater_inflateBytes; + Java_java_util_zip_Inflater_inflateBytesBytes; + Java_java_util_zip_Inflater_inflateBytesBuffer; + Java_java_util_zip_Inflater_inflateBufferBytes; + Java_java_util_zip_Inflater_inflateBufferBuffer; Java_java_util_zip_Inflater_init; Java_java_util_zip_Inflater_initIDs; Java_java_util_zip_Inflater_reset; Java_java_util_zip_Inflater_setDictionary; + Java_java_util_zip_Inflater_setDictionaryBuffer; ZIP_Close; ZIP_CRC32; ZIP_FreeEntry; diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java b/src/java.base/share/classes/java/util/zip/Deflater.java index c75dd4a33f0..85e3debb393 100644 --- a/src/java.base/share/classes/java/util/zip/Deflater.java +++ b/src/java.base/share/classes/java/util/zip/Deflater.java @@ -26,7 +26,13 @@ package java.util.zip; import java.lang.ref.Cleaner.Cleanable; +import java.lang.ref.Reference; +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; +import java.util.Objects; + import jdk.internal.ref.CleanerFactory; +import sun.nio.ch.DirectBuffer; /** * This class provides support for general purpose compression using the @@ -92,8 +98,9 @@ import jdk.internal.ref.CleanerFactory; public class Deflater { private final DeflaterZStreamRef zsRef; - private byte[] buf = new byte[0]; - private int off, len; + private ByteBuffer input = ZipUtils.defaultBuf; + private byte[] inputArray; + private int inputPos, inputLim; private int level, strategy; private boolean setParams; private boolean finish, finished; @@ -170,9 +177,14 @@ public class Deflater { */ public static final int FULL_FLUSH = 3; + /** + * Flush mode to use at the end of output. Can only be provided by the + * user by way of {@link #finish()}. + */ + private static final int FINISH = 4; + static { ZipUtils.loadLibrary(); - initIDs(); } /** @@ -210,33 +222,58 @@ public class Deflater { /** * Sets input data for compression. This should be called whenever * needsInput() returns true indicating that more input data is required. - * @param b the input data bytes + * @param input the input data bytes * @param off the start offset of the data * @param len the length of the data * @see Deflater#needsInput */ - public void setInput(byte[] b, int off, int len) { - if (b== null) { - throw new NullPointerException(); - } - if (off < 0 || len < 0 || off > b.length - len) { + public void setInput(byte[] input, int off, int len) { + if (off < 0 || len < 0 || off > input.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { - this.buf = b; - this.off = off; - this.len = len; + this.input = null; + this.inputArray = input; + this.inputPos = off; + this.inputLim = off + len; } } /** * Sets input data for compression. This should be called whenever * needsInput() returns true indicating that more input data is required. - * @param b the input data bytes + * @param input the input data bytes + * @see Deflater#needsInput + */ + public void setInput(byte[] input) { + setInput(input, 0, input.length); + } + + /** + * Sets input data for compression. This should be called whenever + * needsInput() returns true indicating that more input data is required. + *

+ * The given buffer's position will be advanced as deflate + * operations are performed, up to the buffer's limit. + * The input buffer may be modified (refilled) between deflate + * operations; doing so is equivalent to creating a new buffer + * and setting it with this method. + *

+ * Modifying the input buffer's contents, position, or limit + * concurrently with an deflate operation will result in + * undefined behavior, which may include incorrect operation + * results or operation failure. + * + * @param input the input data bytes * @see Deflater#needsInput + * @since 11 */ - public void setInput(byte[] b) { - setInput(b, 0, b.length); + public void setInput(ByteBuffer input) { + Objects.requireNonNull(input); + synchronized (zsRef) { + this.input = input; + this.inputArray = null; + } } /** @@ -245,22 +282,19 @@ public class Deflater { * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called * in order to get the Adler-32 value of the dictionary required for * decompression. - * @param b the dictionary data bytes + * @param dictionary the dictionary data bytes * @param off the start offset of the data * @param len the length of the data * @see Inflater#inflate * @see Inflater#getAdler */ - public void setDictionary(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } - if (off < 0 || len < 0 || off > b.length - len) { + public void setDictionary(byte[] dictionary, int off, int len) { + if (off < 0 || len < 0 || off > dictionary.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { ensureOpen(); - setDictionary(zsRef.address(), b, off, len); + setDictionary(zsRef.address(), dictionary, off, len); } } @@ -270,12 +304,47 @@ public class Deflater { * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called * in order to get the Adler-32 value of the dictionary required for * decompression. - * @param b the dictionary data bytes + * @param dictionary the dictionary data bytes + * @see Inflater#inflate + * @see Inflater#getAdler + */ + public void setDictionary(byte[] dictionary) { + setDictionary(dictionary, 0, dictionary.length); + } + + /** + * Sets preset dictionary for compression. A preset dictionary is used + * when the history buffer can be predetermined. When the data is later + * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called + * in order to get the Adler-32 value of the dictionary required for + * decompression. + *

+ * The bytes in given byte buffer will be fully consumed by this method. On + * return, its position will equal its limit. + * + * @param dictionary the dictionary data bytes * @see Inflater#inflate * @see Inflater#getAdler */ - public void setDictionary(byte[] b) { - setDictionary(b, 0, b.length); + public void setDictionary(ByteBuffer dictionary) { + synchronized (zsRef) { + int position = dictionary.position(); + int remaining = Math.max(dictionary.limit() - position, 0); + ensureOpen(); + if (dictionary.isDirect()) { + long address = ((DirectBuffer) dictionary).address(); + try { + setDictionaryBuffer(zsRef.address(), address + position, remaining); + } finally { + Reference.reachabilityFence(dictionary); + } + } else { + byte[] array = ZipUtils.getBufferArray(dictionary); + int offset = ZipUtils.getBufferOffset(dictionary); + setDictionary(zsRef.address(), array, offset + position, remaining); + } + dictionary.position(position + remaining); + } } /** @@ -331,14 +400,17 @@ public class Deflater { } /** - * Returns true if the input data buffer is empty and setInput() - * should be called in order to provide more input. + * Returns true if no data remains in the input buffer. This can + * be used to determine if one of the {@code setInput()} methods should be + * called in order to provide more input. + * * @return true if the input data buffer is empty and setInput() * should be called in order to provide more input */ public boolean needsInput() { synchronized (zsRef) { - return len <= 0; + ByteBuffer input = this.input; + return input == null ? inputLim == inputPos : ! input.hasRemaining(); } } @@ -375,14 +447,14 @@ public class Deflater { * yields the same result as the invocation of * {@code deflater.deflate(b, off, len, Deflater.NO_FLUSH)}. * - * @param b the buffer for the compressed data + * @param output the buffer for the compressed data * @param off the start offset of the data * @param len the maximum number of bytes of compressed data * @return the actual number of bytes of compressed data written to the * output buffer */ - public int deflate(byte[] b, int off, int len) { - return deflate(b, off, len, NO_FLUSH); + public int deflate(byte[] output, int off, int len) { + return deflate(output, off, len, NO_FLUSH); } /** @@ -396,12 +468,32 @@ public class Deflater { * yields the same result as the invocation of * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}. * - * @param b the buffer for the compressed data + * @param output the buffer for the compressed data + * @return the actual number of bytes of compressed data written to the + * output buffer + */ + public int deflate(byte[] output) { + return deflate(output, 0, output.length, NO_FLUSH); + } + + /** + * Compresses the input data and fills specified buffer with compressed + * data. Returns actual number of bytes of compressed data. A return value + * of 0 indicates that {@link #needsInput() needsInput} should be called + * in order to determine if more input data is required. + * + *

This method uses {@link #NO_FLUSH} as its compression flush mode. + * An invocation of this method of the form {@code deflater.deflate(output)} + * yields the same result as the invocation of + * {@code deflater.deflate(output, Deflater.NO_FLUSH)}. + * + * @param output the buffer for the compressed data * @return the actual number of bytes of compressed data written to the * output buffer + * @since 11 */ - public int deflate(byte[] b) { - return deflate(b, 0, b.length, NO_FLUSH); + public int deflate(ByteBuffer output) { + return deflate(output, NO_FLUSH); } /** @@ -441,7 +533,11 @@ public class Deflater { * repeatedly output to the output buffer every time this method is * invoked. * - * @param b the buffer for the compressed data + *

If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation. + * + * @param output the buffer for the compressed data * @param off the start offset of the data * @param len the maximum number of bytes of compressed data * @param flush the compression flush mode @@ -451,25 +547,248 @@ public class Deflater { * @throws IllegalArgumentException if the flush mode is invalid * @since 1.7 */ - public int deflate(byte[] b, int off, int len, int flush) { - if (b == null) { - throw new NullPointerException(); - } - if (off < 0 || len < 0 || off > b.length - len) { + public int deflate(byte[] output, int off, int len, int flush) { + if (off < 0 || len < 0 || off > output.length - len) { throw new ArrayIndexOutOfBoundsException(); } + if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) { + throw new IllegalArgumentException(); + } synchronized (zsRef) { ensureOpen(); - if (flush == NO_FLUSH || flush == SYNC_FLUSH || - flush == FULL_FLUSH) { - int thisLen = this.len; - int n = deflateBytes(zsRef.address(), b, off, len, flush); - bytesWritten += n; - bytesRead += (thisLen - this.len); - return n; + + ByteBuffer input = this.input; + if (finish) { + // disregard given flush mode in this case + flush = FINISH; + } + int params; + if (setParams) { + // bit 0: true to set params + // bit 1-2: strategy (0, 1, or 2) + // bit 3-31: level (0..9 or -1) + params = 1 | strategy << 1 | level << 3; + } else { + params = 0; + } + int inputPos; + long result; + if (input == null) { + inputPos = this.inputPos; + result = deflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + output, off, len, + flush, params); + } else { + inputPos = input.position(); + int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + try { + long inputAddress = ((DirectBuffer) input).address(); + result = deflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + output, off, len, + flush, params); + } finally { + Reference.reachabilityFence(input); + } + } else { + byte[] inputArray = ZipUtils.getBufferArray(input); + int inputOffset = ZipUtils.getBufferOffset(input); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + output, off, len, + flush, params); + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; } + if (params != 0 && (result >>> 63 & 1) == 0) { + setParams = false; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + bytesWritten += written; + bytesRead += read; + return written; + } + } + + /** + * Compresses the input data and fills the specified buffer with compressed + * data. Returns actual number of bytes of data compressed. + * + *

Compression flush mode is one of the following three modes: + * + *

    + *
  • {@link #NO_FLUSH}: allows the deflater to decide how much data + * to accumulate, before producing output, in order to achieve the best + * compression (should be used in normal use scenario). A return value + * of 0 in this flush mode indicates that {@link #needsInput()} should + * be called in order to determine if more input data is required. + * + *
  • {@link #SYNC_FLUSH}: all pending output in the deflater is flushed, + * to the specified output buffer, so that an inflater that works on + * compressed data can get all input data available so far (In particular + * the {@link #needsInput()} returns {@code true} after this invocation + * if enough output space is provided). Flushing with {@link #SYNC_FLUSH} + * may degrade compression for some compression algorithms and so it + * should be used only when necessary. + * + *
  • {@link #FULL_FLUSH}: all pending output is flushed out as with + * {@link #SYNC_FLUSH}. The compression state is reset so that the inflater + * that works on the compressed output data can restart from this point + * if previous compressed data has been damaged or if random access is + * desired. Using {@link #FULL_FLUSH} too often can seriously degrade + * compression. + *
+ * + *

In the case of {@link #FULL_FLUSH} or {@link #SYNC_FLUSH}, if + * the return value is equal to the {@linkplain ByteBuffer#remaining() remaining space} + * of the buffer, this method should be invoked again with the same + * {@code flush} parameter and more output space. Make sure that + * the buffer has at least 6 bytes of remaining space to avoid the + * flush marker (5 bytes) being repeatedly output to the output buffer + * every time this method is invoked. + * + *

On success, the position of the given {@code output} byte buffer will be + * advanced by as many bytes as were produced by the operation, which is equal + * to the number returned by this method. + * + *

If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation. + * + * @param output the buffer for the compressed data + * @param flush the compression flush mode + * @return the actual number of bytes of compressed data written to + * the output buffer + * + * @throws IllegalArgumentException if the flush mode is invalid + * @since 11 + */ + public int deflate(ByteBuffer output, int flush) { + if (output.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + if (flush != NO_FLUSH && flush != SYNC_FLUSH && flush != FULL_FLUSH) { throw new IllegalArgumentException(); } + synchronized (zsRef) { + ensureOpen(); + + ByteBuffer input = this.input; + if (finish) { + // disregard given flush mode in this case + flush = FINISH; + } + int params; + if (setParams) { + // bit 0: true to set params + // bit 1-2: strategy (0, 1, or 2) + // bit 3-31: level (0..9 or -1) + params = 1 | strategy << 1 | level << 3; + } else { + params = 0; + } + int outputPos = output.position(); + int outputRem = Math.max(output.limit() - outputPos, 0); + int inputPos; + long result; + if (input == null) { + inputPos = this.inputPos; + if (output.isDirect()) { + long outputAddress = ((DirectBuffer) output).address(); + try { + result = deflateBytesBuffer(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputAddress + outputPos, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + byte[] outputArray = ZipUtils.getBufferArray(output); + int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } else { + inputPos = input.position(); + int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + long inputAddress = ((DirectBuffer) input).address(); + try { + if (output.isDirect()) { + long outputAddress = outputPos + ((DirectBuffer) output).address(); + try { + result = deflateBufferBuffer(zsRef.address(), + inputAddress + inputPos, inputRem, + outputAddress, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + byte[] outputArray = ZipUtils.getBufferArray(output); + int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } finally { + Reference.reachabilityFence(input); + } + } else { + byte[] inputArray = ZipUtils.getBufferArray(input); + int inputOffset = ZipUtils.getBufferOffset(input); + if (output.isDirect()) { + long outputAddress = ((DirectBuffer) output).address(); + try { + result = deflateBytesBuffer(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputAddress + outputPos, outputRem, + flush, params); + } finally { + Reference.reachabilityFence(output); + } + } else { + byte[] outputArray = ZipUtils.getBufferArray(output); + int outputOffset = ZipUtils.getBufferOffset(output); + result = deflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem, + flush, params); + } + } + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if (params != 0 && (result >>> 63 & 1) == 0) { + setParams = false; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + output.position(outputPos + written); + bytesWritten += written; + bytesRead += read; + return written; + } } /** @@ -545,7 +864,8 @@ public class Deflater { reset(zsRef.address()); finish = false; finished = false; - off = len = 0; + input = ZipUtils.defaultBuf; + inputArray = null; bytesRead = bytesWritten = 0; } } @@ -560,7 +880,7 @@ public class Deflater { public void end() { synchronized (zsRef) { zsRef.clean(); - buf = null; + input = ZipUtils.defaultBuf; } } @@ -585,11 +905,26 @@ public class Deflater { throw new NullPointerException("Deflater has been closed"); } - private static native void initIDs(); private static native long init(int level, int strategy, boolean nowrap); - private static native void setDictionary(long addr, byte[] b, int off, int len); - private native int deflateBytes(long addr, byte[] b, int off, int len, - int flush); + private static native void setDictionary(long addr, byte[] b, int off, + int len); + private static native void setDictionaryBuffer(long addr, long bufAddress, int len); + private native long deflateBytesBytes(long addr, + byte[] inputArray, int inputOff, int inputLen, + byte[] outputArray, int outputOff, int outputLen, + int flush, int params); + private native long deflateBytesBuffer(long addr, + byte[] inputArray, int inputOff, int inputLen, + long outputAddress, int outputLen, + int flush, int params); + private native long deflateBufferBytes(long addr, + long inputAddress, int inputLen, + byte[] outputArray, int outputOff, int outputLen, + int flush, int params); + private native long deflateBufferBuffer(long addr, + long inputAddress, int inputLen, + long outputAddress, int outputLen, + int flush, int params); private static native int getAdler(long addr); private static native void reset(long addr); private static native void end(long addr); diff --git a/src/java.base/share/classes/java/util/zip/Inflater.java b/src/java.base/share/classes/java/util/zip/Inflater.java index 9c6d8aa3d83..4e3e898a11e 100644 --- a/src/java.base/share/classes/java/util/zip/Inflater.java +++ b/src/java.base/share/classes/java/util/zip/Inflater.java @@ -26,7 +26,13 @@ package java.util.zip; import java.lang.ref.Cleaner.Cleanable; +import java.lang.ref.Reference; +import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; +import java.util.Objects; + import jdk.internal.ref.CleanerFactory; +import sun.nio.ch.DirectBuffer; /** * This class provides support for general purpose decompression using the @@ -92,14 +98,20 @@ import jdk.internal.ref.CleanerFactory; public class Inflater { private final InflaterZStreamRef zsRef; - private byte[] buf = defaultBuf; - private int off, len; + private ByteBuffer input = ZipUtils.defaultBuf; + private byte[] inputArray; + private int inputPos, inputLim; private boolean finished; private boolean needDict; private long bytesRead; private long bytesWritten; - private static final byte[] defaultBuf = new byte[0]; + /* + * These fields are used as an "out" parameter from JNI when a + * DataFormatException is thrown during the inflate operation. + */ + private int inputConsumed; + private int outputConsumed; static { ZipUtils.loadLibrary(); @@ -132,22 +144,20 @@ public class Inflater { * Sets input data for decompression. Should be called whenever * needsInput() returns true indicating that more input data is * required. - * @param b the input data bytes + * @param input the input data bytes * @param off the start offset of the input data * @param len the length of the input data * @see Inflater#needsInput */ - public void setInput(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } - if (off < 0 || len < 0 || off > b.length - len) { + public void setInput(byte[] input, int off, int len) { + if (off < 0 || len < 0 || off > input.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { - this.buf = b; - this.off = off; - this.len = len; + this.input = null; + this.inputArray = input; + this.inputPos = off; + this.inputLim = off + len; } } @@ -155,11 +165,39 @@ public class Inflater { * Sets input data for decompression. Should be called whenever * needsInput() returns true indicating that more input data is * required. - * @param b the input data bytes + * @param input the input data bytes * @see Inflater#needsInput */ - public void setInput(byte[] b) { - setInput(b, 0, b.length); + public void setInput(byte[] input) { + setInput(input, 0, input.length); + } + + /** + * Sets input data for decompression. Should be called whenever + * needsInput() returns true indicating that more input data is + * required. + *

+ * The given buffer's position will be advanced as inflate + * operations are performed, up to the buffer's limit. + * The input buffer may be modified (refilled) between inflate + * operations; doing so is equivalent to creating a new buffer + * and setting it with this method. + *

+ * Modifying the input buffer's contents, position, or limit + * concurrently with an inflate operation will result in + * undefined behavior, which may include incorrect operation + * results or operation failure. + * + * @param input the input data bytes + * @see Inflater#needsInput + * @since 11 + */ + public void setInput(ByteBuffer input) { + Objects.requireNonNull(input); + synchronized (zsRef) { + this.input = input; + this.inputArray = null; + } } /** @@ -167,22 +205,19 @@ public class Inflater { * called when inflate() returns 0 and needsDictionary() returns true * indicating that a preset dictionary is required. The method getAdler() * can be used to get the Adler-32 value of the dictionary needed. - * @param b the dictionary data bytes + * @param dictionary the dictionary data bytes * @param off the start offset of the data * @param len the length of the data * @see Inflater#needsDictionary * @see Inflater#getAdler */ - public void setDictionary(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } - if (off < 0 || len < 0 || off > b.length - len) { + public void setDictionary(byte[] dictionary, int off, int len) { + if (off < 0 || len < 0 || off > dictionary.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { ensureOpen(); - setDictionary(zsRef.address(), b, off, len); + setDictionary(zsRef.address(), dictionary, off, len); needDict = false; } } @@ -192,12 +227,48 @@ public class Inflater { * called when inflate() returns 0 and needsDictionary() returns true * indicating that a preset dictionary is required. The method getAdler() * can be used to get the Adler-32 value of the dictionary needed. - * @param b the dictionary data bytes + * @param dictionary the dictionary data bytes + * @see Inflater#needsDictionary + * @see Inflater#getAdler + */ + public void setDictionary(byte[] dictionary) { + setDictionary(dictionary, 0, dictionary.length); + } + + /** + * Sets the preset dictionary to the bytes in the given buffer. Should be + * called when inflate() returns 0 and needsDictionary() returns true + * indicating that a preset dictionary is required. The method getAdler() + * can be used to get the Adler-32 value of the dictionary needed. + *

+ * The bytes in given byte buffer will be fully consumed by this method. On + * return, its position will equal its limit. + * + * @param dictionary the dictionary data bytes * @see Inflater#needsDictionary * @see Inflater#getAdler + * @since 11 */ - public void setDictionary(byte[] b) { - setDictionary(b, 0, b.length); + public void setDictionary(ByteBuffer dictionary) { + synchronized (zsRef) { + int position = dictionary.position(); + int remaining = Math.max(dictionary.limit() - position, 0); + ensureOpen(); + if (dictionary.isDirect()) { + long address = ((DirectBuffer) dictionary).address(); + try { + setDictionaryBuffer(zsRef.address(), address + position, remaining); + } finally { + Reference.reachabilityFence(dictionary); + } + } else { + byte[] array = ZipUtils.getBufferArray(dictionary); + int offset = ZipUtils.getBufferOffset(dictionary); + setDictionary(zsRef.address(), array, offset + position, remaining); + } + dictionary.position(position + remaining); + needDict = false; + } } /** @@ -208,19 +279,22 @@ public class Inflater { */ public int getRemaining() { synchronized (zsRef) { - return len; + ByteBuffer input = this.input; + return input == null ? inputLim - inputPos : input.remaining(); } } /** * Returns true if no data remains in the input buffer. This can - * be used to determine if #setInput should be called in order - * to provide more input. + * be used to determine if one of the {@code setInput()} methods should be + * called in order to provide more input. + * * @return true if no data remains in the input buffer */ public boolean needsInput() { synchronized (zsRef) { - return len <= 0; + ByteBuffer input = this.input; + return input == null ? inputLim == inputPos : ! input.hasRemaining(); } } @@ -254,30 +328,103 @@ public class Inflater { * determine if more input data or a preset dictionary is required. * In the latter case, getAdler() can be used to get the Adler-32 * value of the dictionary required. - * @param b the buffer for the uncompressed data + *

+ * If the {@link #setInput(ByteBuffer)} method was called to provide a buffer + * for input, the input buffer's position will be advanced by the number of bytes + * consumed by this operation, even in the event that a {@link DataFormatException} + * is thrown. + *

+ * The {@linkplain #getRemaining() remaining byte count} will be reduced by + * the number of consumed input bytes. If the {@link #setInput(ByteBuffer)} + * method was called to provide a buffer for input, the input buffer's position + * will be advanced the number of consumed bytes. + *

+ * These byte totals, as well as + * the {@linkplain #getBytesRead() total bytes read} + * and the {@linkplain #getBytesWritten() total bytes written} + * values, will be updated even in the event that a {@link DataFormatException} + * is thrown to reflect the amount of data consumed and produced before the + * exception occurred. + * + * @param output the buffer for the uncompressed data * @param off the start offset of the data * @param len the maximum number of uncompressed bytes * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid + * @throws DataFormatException if the compressed data format is invalid * @see Inflater#needsInput * @see Inflater#needsDictionary */ - public int inflate(byte[] b, int off, int len) + public int inflate(byte[] output, int off, int len) throws DataFormatException { - if (b == null) { - throw new NullPointerException(); - } - if (off < 0 || len < 0 || off > b.length - len) { + if (off < 0 || len < 0 || off > output.length - len) { throw new ArrayIndexOutOfBoundsException(); } synchronized (zsRef) { ensureOpen(); - int thisLen = this.len; - int n = inflateBytes(zsRef.address(), b, off, len); - bytesWritten += n; - bytesRead += (thisLen - this.len); - return n; + ByteBuffer input = this.input; + long result; + int inputPos; + try { + if (input == null) { + inputPos = this.inputPos; + try { + result = inflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + output, off, len); + } catch (DataFormatException e) { + this.inputPos = inputPos + inputConsumed; + throw e; + } + } else { + inputPos = input.position(); + try { + int inputRem = Math.max(input.limit() - inputPos, 0); + if (input.isDirect()) { + try { + long inputAddress = ((DirectBuffer) input).address(); + result = inflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + output, off, len); + } finally { + Reference.reachabilityFence(input); + } + } else { + byte[] inputArray = ZipUtils.getBufferArray(input); + int inputOffset = ZipUtils.getBufferOffset(input); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + output, off, len); + } + } catch (DataFormatException e) { + input.position(inputPos + inputConsumed); + throw e; + } + } + } catch (DataFormatException e) { + bytesRead += inputConsumed; + inputConsumed = 0; + int written = outputConsumed; + bytesWritten += written; + outputConsumed = 0; + throw e; + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if ((result >>> 63 & 1) != 0) { + needDict = true; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + bytesWritten += written; + bytesRead += read; + return written; } } @@ -288,14 +435,177 @@ public class Inflater { * determine if more input data or a preset dictionary is required. * In the latter case, getAdler() can be used to get the Adler-32 * value of the dictionary required. - * @param b the buffer for the uncompressed data + *

+ * The {@linkplain #getRemaining() remaining byte count} will be reduced by + * the number of consumed input bytes. If the {@link #setInput(ByteBuffer)} + * method was called to provide a buffer for input, the input buffer's position + * will be advanced the number of consumed bytes. + *

+ * These byte totals, as well as + * the {@linkplain #getBytesRead() total bytes read} + * and the {@linkplain #getBytesWritten() total bytes written} + * values, will be updated even in the event that a {@link DataFormatException} + * is thrown to reflect the amount of data consumed and produced before the + * exception occurred. + * + * @param output the buffer for the uncompressed data + * @return the actual number of uncompressed bytes + * @throws DataFormatException if the compressed data format is invalid + * @see Inflater#needsInput + * @see Inflater#needsDictionary + */ + public int inflate(byte[] output) throws DataFormatException { + return inflate(output, 0, output.length); + } + + /** + * Uncompresses bytes into specified buffer. Returns actual number + * of bytes uncompressed. A return value of 0 indicates that + * needsInput() or needsDictionary() should be called in order to + * determine if more input data or a preset dictionary is required. + * In the latter case, getAdler() can be used to get the Adler-32 + * value of the dictionary required. + *

+ * On success, the position of the given {@code output} byte buffer will be + * advanced by as many bytes as were produced by the operation, which is equal + * to the number returned by this method. Note that the position of the + * {@code output} buffer will be advanced even in the event that a + * {@link DataFormatException} is thrown. + *

+ * The {@linkplain #getRemaining() remaining byte count} will be reduced by + * the number of consumed input bytes. If the {@link #setInput(ByteBuffer)} + * method was called to provide a buffer for input, the input buffer's position + * will be advanced the number of consumed bytes. + *

+ * These byte totals, as well as + * the {@linkplain #getBytesRead() total bytes read} + * and the {@linkplain #getBytesWritten() total bytes written} + * values, will be updated even in the event that a {@link DataFormatException} + * is thrown to reflect the amount of data consumed and produced before the + * exception occurred. + * + * @param output the buffer for the uncompressed data * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid + * @throws DataFormatException if the compressed data format is invalid + * @throws ReadOnlyBufferException if the given output buffer is read-only * @see Inflater#needsInput * @see Inflater#needsDictionary + * @since 11 */ - public int inflate(byte[] b) throws DataFormatException { - return inflate(b, 0, b.length); + public int inflate(ByteBuffer output) throws DataFormatException { + if (output.isReadOnly()) { + throw new ReadOnlyBufferException(); + } + synchronized (zsRef) { + ensureOpen(); + ByteBuffer input = this.input; + long result; + int inputPos; + int outputPos = output.position(); + int outputRem = Math.max(output.limit() - outputPos, 0); + try { + if (input == null) { + inputPos = this.inputPos; + try { + if (output.isDirect()) { + long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBytesBuffer(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + byte[] outputArray = ZipUtils.getBufferArray(output); + int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputPos, inputLim - inputPos, + outputArray, outputOffset + outputPos, outputRem); + } + } catch (DataFormatException e) { + this.inputPos = inputPos + inputConsumed; + throw e; + } + } else { + inputPos = input.position(); + int inputRem = Math.max(input.limit() - inputPos, 0); + try { + if (input.isDirect()) { + long inputAddress = ((DirectBuffer) input).address(); + try { + if (output.isDirect()) { + long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBufferBuffer(zsRef.address(), + inputAddress + inputPos, inputRem, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + byte[] outputArray = ZipUtils.getBufferArray(output); + int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBufferBytes(zsRef.address(), + inputAddress + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem); + } + } finally { + Reference.reachabilityFence(input); + } + } else { + byte[] inputArray = ZipUtils.getBufferArray(input); + int inputOffset = ZipUtils.getBufferOffset(input); + if (output.isDirect()) { + long outputAddress = ((DirectBuffer) output).address(); + try { + result = inflateBytesBuffer(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputAddress + outputPos, outputRem); + } finally { + Reference.reachabilityFence(output); + } + } else { + byte[] outputArray = ZipUtils.getBufferArray(output); + int outputOffset = ZipUtils.getBufferOffset(output); + result = inflateBytesBytes(zsRef.address(), + inputArray, inputOffset + inputPos, inputRem, + outputArray, outputOffset + outputPos, outputRem); + } + } + } catch (DataFormatException e) { + input.position(inputPos + inputConsumed); + throw e; + } + } + } catch (DataFormatException e) { + bytesRead += inputConsumed; + inputConsumed = 0; + int written = outputConsumed; + output.position(outputPos + written); + bytesWritten += written; + outputConsumed = 0; + throw e; + } + int read = (int) (result & 0x7fff_ffffL); + int written = (int) (result >>> 31 & 0x7fff_ffffL); + if ((result >>> 62 & 1) != 0) { + finished = true; + } + if ((result >>> 63 & 1) != 0) { + needDict = true; + } + if (input != null) { + input.position(inputPos + read); + } else { + this.inputPos = inputPos + read; + } + // Note: this method call also serves to keep the byteBuffer ref alive + output.position(outputPos + written); + bytesWritten += written; + bytesRead += read; + return written; + } } /** @@ -368,10 +678,10 @@ public class Inflater { synchronized (zsRef) { ensureOpen(); reset(zsRef.address()); - buf = defaultBuf; + input = ZipUtils.defaultBuf; + inputArray = null; finished = false; needDict = false; - off = len = 0; bytesRead = bytesWritten = 0; } } @@ -386,7 +696,8 @@ public class Inflater { public void end() { synchronized (zsRef) { zsRef.clean(); - buf = null; + input = ZipUtils.defaultBuf; + inputArray = null; } } @@ -416,18 +727,23 @@ public class Inflater { throw new NullPointerException("Inflater has been closed"); } - boolean ended() { - synchronized (zsRef) { - return zsRef.address() == 0; - } - } - private static native void initIDs(); private static native long init(boolean nowrap); private static native void setDictionary(long addr, byte[] b, int off, int len); - private native int inflateBytes(long addr, byte[] b, int off, int len) - throws DataFormatException; + private static native void setDictionaryBuffer(long addr, long bufAddress, int len); + private native long inflateBytesBytes(long addr, + byte[] inputArray, int inputOff, int inputLen, + byte[] outputArray, int outputOff, int outputLen) throws DataFormatException; + private native long inflateBytesBuffer(long addr, + byte[] inputArray, int inputOff, int inputLen, + long outputAddress, int outputLen) throws DataFormatException; + private native long inflateBufferBytes(long addr, + long inputAddress, int inputLen, + byte[] outputArray, int outputOff, int outputLen) throws DataFormatException; + private native long inflateBufferBuffer(long addr, + long inputAddress, int inputLen, + long outputAddress, int outputLen) throws DataFormatException; private static native int getAdler(long addr); private static native void reset(long addr); private static native void end(long addr); diff --git a/src/java.base/share/classes/java/util/zip/ZipUtils.java b/src/java.base/share/classes/java/util/zip/ZipUtils.java index 45c5d8dbb67..07e64e4fa92 100644 --- a/src/java.base/share/classes/java/util/zip/ZipUtils.java +++ b/src/java.base/share/classes/java/util/zip/ZipUtils.java @@ -25,6 +25,8 @@ package java.util.zip; +import java.nio.Buffer; +import java.nio.ByteBuffer; import java.nio.file.attribute.FileTime; import java.security.AccessController; import java.security.PrivilegedAction; @@ -37,6 +39,9 @@ import java.util.concurrent.TimeUnit; import static java.util.zip.ZipConstants.ENDHDR; +import jdk.internal.misc.Unsafe; +import sun.nio.ch.DirectBuffer; + class ZipUtils { // used to adjust values between Windows and java epoch @@ -45,6 +50,8 @@ class ZipUtils { // used to indicate the corresponding windows time is not available public static final long WINDOWS_TIME_NOT_AVAILABLE = Long.MIN_VALUE; + static final ByteBuffer defaultBuf = ByteBuffer.allocateDirect(0); + /** * Converts Windows time (in microseconds, UTC/GMT) time to FileTime. */ @@ -281,4 +288,17 @@ class ZipUtils { AccessController.doPrivileged(pa); } } + + private static final Unsafe unsafe = Unsafe.getUnsafe(); + + private static final long byteBufferArrayOffset = unsafe.objectFieldOffset(ByteBuffer.class, "hb"); + private static final long byteBufferOffsetOffset = unsafe.objectFieldOffset(ByteBuffer.class, "offset"); + + static byte[] getBufferArray(ByteBuffer byteBuffer) { + return (byte[]) unsafe.getObject(byteBuffer, byteBufferArrayOffset); + } + + static int getBufferOffset(ByteBuffer byteBuffer) { + return unsafe.getInt(byteBuffer, byteBufferOffsetOffset); + } } diff --git a/src/java.base/share/native/libzip/Deflater.c b/src/java.base/share/native/libzip/Deflater.c index b666a16145a..b56df5ecc1b 100644 --- a/src/java.base/share/native/libzip/Deflater.c +++ b/src/java.base/share/native/libzip/Deflater.c @@ -38,34 +38,6 @@ #define DEF_MEM_LEVEL 8 -static jfieldID levelID; -static jfieldID strategyID; -static jfieldID setParamsID; -static jfieldID finishID; -static jfieldID finishedID; -static jfieldID bufID, offID, lenID; - -JNIEXPORT void JNICALL -Java_java_util_zip_Deflater_initIDs(JNIEnv *env, jclass cls) -{ - levelID = (*env)->GetFieldID(env, cls, "level", "I"); - CHECK_NULL(levelID); - strategyID = (*env)->GetFieldID(env, cls, "strategy", "I"); - CHECK_NULL(strategyID); - setParamsID = (*env)->GetFieldID(env, cls, "setParams", "Z"); - CHECK_NULL(setParamsID); - finishID = (*env)->GetFieldID(env, cls, "finish", "Z"); - CHECK_NULL(finishID); - finishedID = (*env)->GetFieldID(env, cls, "finished", "Z"); - CHECK_NULL(finishedID); - bufID = (*env)->GetFieldID(env, cls, "buf", "[B"); - CHECK_NULL(bufID); - offID = (*env)->GetFieldID(env, cls, "off", "I"); - CHECK_NULL(offID); - lenID = (*env)->GetFieldID(env, cls, "len", "I"); - CHECK_NULL(lenID); -} - JNIEXPORT jlong JNICALL Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level, jint strategy, jboolean nowrap) @@ -104,17 +76,9 @@ Java_java_util_zip_Deflater_init(JNIEnv *env, jclass cls, jint level, } } -JNIEXPORT void JNICALL -Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, - jarray b, jint off, jint len) +static void doSetDictionary(JNIEnv *env, jlong addr, jbyte *buf, jint len) { - Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - int res; - if (buf == 0) {/* out of memory */ - return; - } - res = deflateSetDictionary((z_stream *)jlong_to_ptr(addr), buf + off, len); - (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); + int res = deflateSetDictionary(jlong_to_ptr(addr), (Bytef *) buf, len); switch (res) { case Z_OK: break; @@ -127,94 +91,169 @@ Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, } } -JNIEXPORT jint JNICALL -Java_java_util_zip_Deflater_deflateBytes(JNIEnv *env, jobject this, jlong addr, - jarray b, jint off, jint len, jint flush) +JNIEXPORT void JNICALL +Java_java_util_zip_Deflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, + jbyteArray b, jint off, jint len) +{ + jbyte *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); + if (buf == NULL) /* out of memory */ + return; + doSetDictionary(env, addr, buf + off, len); + (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); +} + +JNIEXPORT void JNICALL +Java_java_util_zip_Deflater_setDictionaryBuffer(JNIEnv *env, jclass cls, jlong addr, + jlong bufferAddr, jint len) +{ + jbyte *buf = jlong_to_ptr(bufferAddr); + doSetDictionary(env, addr, buf, len); +} + +static jlong doDeflate(JNIEnv *env, jobject this, jlong addr, + jbyte *input, jint inputLen, + jbyte *output, jint outputLen, + jint flush, jint params) { z_stream *strm = jlong_to_ptr(addr); + jint inputUsed = 0, outputUsed = 0; - jarray this_buf = (*env)->GetObjectField(env, this, bufID); - jint this_off = (*env)->GetIntField(env, this, offID); - jint this_len = (*env)->GetIntField(env, this, lenID); - jbyte *in_buf; - jbyte *out_buf; - int res; - if ((*env)->GetBooleanField(env, this, setParamsID)) { - int level = (*env)->GetIntField(env, this, levelID); - int strategy = (*env)->GetIntField(env, this, strategyID); - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - // Throw OOME only when length is not zero - if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } + strm->next_in = (Bytef *) input; + strm->next_out = (Bytef *) output; + strm->avail_in = inputLen; + strm->avail_out = outputLen; + + int finished = 0; + int setParams = params & 1; - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - res = deflateParams(strm, level, strategy); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + if (setParams) { + int strategy = (params >> 1) & 3; + int level = params >> 3; + int res = deflateParams(strm, level, strategy); switch (res) { case Z_OK: - (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE); + setParams = 0; + /* fall through */ case Z_BUF_ERROR: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return (jint) (len - strm->avail_out); + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; default: JNU_ThrowInternalError(env, strm->msg); return 0; } } else { - jboolean finish = (*env)->GetBooleanField(env, this, finishID); - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - if (this_len != 0) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0) - JNU_ThrowOutOfMemoryError(env, 0); - - return 0; - } - - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - res = deflate(strm, finish ? Z_FINISH : flush); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + int res = deflate(strm, flush); switch (res) { case Z_STREAM_END: - (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); + finished = 1; /* fall through */ case Z_OK: case Z_BUF_ERROR: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return len - strm->avail_out; + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; default: JNU_ThrowInternalError(env, strm->msg); return 0; } } + return ((jlong)inputUsed) | (((jlong)outputUsed) << 31) | (((jlong)finished) << 62) | (((jlong)setParams) << 63); +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBytesBytes(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen, + jint flush, jint params) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doDeflate(env, this, addr, + input + inputOff, inputLen, + output + outputOff, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0); + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBytesBuffer(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jlong outputBuffer, jint outputLen, + jint flush, jint params) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = jlong_to_ptr(outputBuffer); + + jlong retVal = doDeflate(env, this, addr, + input + inputOff, inputLen, + output, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBufferBytes(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen, + jint flush, jint params) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doDeflate(env, this, addr, + input, inputLen, + output + outputOff, outputLen, + flush, params); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Deflater_deflateBufferBuffer(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jlong outputBuffer, jint outputLen, + jint flush, jint params) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = jlong_to_ptr(outputBuffer); + + return doDeflate(env, this, addr, + input, inputLen, + output, outputLen, + flush, params); } JNIEXPORT jint JNICALL diff --git a/src/java.base/share/native/libzip/Inflater.c b/src/java.base/share/native/libzip/Inflater.c index 2e21d084b39..465e2534e47 100644 --- a/src/java.base/share/native/libzip/Inflater.c +++ b/src/java.base/share/native/libzip/Inflater.c @@ -42,23 +42,16 @@ #define ThrowDataFormatException(env, msg) \ JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg) -static jfieldID needDictID; -static jfieldID finishedID; -static jfieldID bufID, offID, lenID; +static jfieldID inputConsumedID; +static jfieldID outputConsumedID; JNIEXPORT void JNICALL Java_java_util_zip_Inflater_initIDs(JNIEnv *env, jclass cls) { - needDictID = (*env)->GetFieldID(env, cls, "needDict", "Z"); - CHECK_NULL(needDictID); - finishedID = (*env)->GetFieldID(env, cls, "finished", "Z"); - CHECK_NULL(finishedID); - bufID = (*env)->GetFieldID(env, cls, "buf", "[B"); - CHECK_NULL(bufID); - offID = (*env)->GetFieldID(env, cls, "off", "I"); - CHECK_NULL(offID); - lenID = (*env)->GetFieldID(env, cls, "len", "I"); - CHECK_NULL(lenID); + inputConsumedID = (*env)->GetFieldID(env, cls, "inputConsumed", "I"); + outputConsumedID = (*env)->GetFieldID(env, cls, "outputConsumed", "I"); + CHECK_NULL(inputConsumedID); + CHECK_NULL(outputConsumedID); } JNIEXPORT jlong JNICALL @@ -94,16 +87,9 @@ Java_java_util_zip_Inflater_init(JNIEnv *env, jclass cls, jboolean nowrap) } } -JNIEXPORT void JNICALL -Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, - jarray b, jint off, jint len) +static void doSetDictionary(JNIEnv *env, jlong addr, jbyte *buf, jint len) { - Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - int res; - if (buf == 0) /* out of memory */ - return; - res = inflateSetDictionary(jlong_to_ptr(addr), buf + off, len); - (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); + int res = inflateSetDictionary(jlong_to_ptr(addr), (Bytef *) buf, len); switch (res) { case Z_OK: break; @@ -117,68 +103,159 @@ Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, } } -JNIEXPORT jint JNICALL -Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr, - jarray b, jint off, jint len) +JNIEXPORT void JNICALL +Java_java_util_zip_Inflater_setDictionary(JNIEnv *env, jclass cls, jlong addr, + jbyteArray b, jint off, jint len) +{ + jbyte *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); + if (buf == NULL) /* out of memory */ + return; + doSetDictionary(env, addr, buf + off, len); + (*env)->ReleasePrimitiveArrayCritical(env, b, buf, 0); +} + +JNIEXPORT void JNICALL +Java_java_util_zip_Inflater_setDictionaryBuffer(JNIEnv *env, jclass cls, jlong addr, + jlong bufferAddr, jint len) +{ + jbyte *buf = jlong_to_ptr(bufferAddr); + doSetDictionary(env, addr, buf, len); +} + +static jlong doInflate(JNIEnv *env, jobject this, jlong addr, + jbyte *input, jint inputLen, + jbyte *output, jint outputLen) { z_stream *strm = jlong_to_ptr(addr); - jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID); - jint this_off = (*env)->GetIntField(env, this, offID); - jint this_len = (*env)->GetIntField(env, this, lenID); + jint inputUsed = 0, outputUsed = 0; - jbyte *in_buf; - jbyte *out_buf; - int ret; + strm->next_in = (Bytef *) input; + strm->next_out = (Bytef *) output; + strm->avail_in = inputLen; + strm->avail_out = outputLen; - in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); - if (in_buf == NULL) { - if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); - if (out_buf == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); - if (len != 0 && (*env)->ExceptionOccurred(env) == NULL) - JNU_ThrowOutOfMemoryError(env, 0); - return 0; - } - strm->next_in = (Bytef *) (in_buf + this_off); - strm->next_out = (Bytef *) (out_buf + off); - strm->avail_in = this_len; - strm->avail_out = len; - ret = inflate(strm, Z_PARTIAL_FLUSH); - (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0); - (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); + int ret = inflate(strm, Z_PARTIAL_FLUSH); + int finished = 0; + int needDict = 0; switch (ret) { case Z_STREAM_END: - (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE); + finished = 1; /* fall through */ case Z_OK: - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return (jint) (len - strm->avail_out); + inputUsed = inputLen - strm->avail_in; + outputUsed = outputLen - strm->avail_out; + break; case Z_NEED_DICT: - (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE); + needDict = 1; /* Might have consumed some input here! */ - this_off += this_len - strm->avail_in; - (*env)->SetIntField(env, this, offID, this_off); - (*env)->SetIntField(env, this, lenID, strm->avail_in); - return 0; + inputUsed = inputLen - strm->avail_in; + /* zlib is unclear about whether output may be produced */ + outputUsed = outputLen - strm->avail_out; + break; case Z_BUF_ERROR: - return 0; + break; case Z_DATA_ERROR: + inputUsed = inputLen - strm->avail_in; + (*env)->SetIntField(env, this, inputConsumedID, inputUsed); + outputUsed = outputLen - strm->avail_out; + (*env)->SetIntField(env, this, outputConsumedID, outputUsed); ThrowDataFormatException(env, strm->msg); - return 0; + break; case Z_MEM_ERROR: JNU_ThrowOutOfMemoryError(env, 0); - return 0; + break; default: JNU_ThrowInternalError(env, strm->msg); - return 0; + break; + } + return ((jlong)inputUsed) | (((jlong)outputUsed) << 31) | (((jlong)finished) << 62) | (((jlong)needDict) << 63); +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBytesBytes(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + + jlong retVal = doInflate(env, this, addr, + input + inputOff, inputLen, + output + outputOff, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0); + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBytesBuffer(JNIEnv *env, jobject this, jlong addr, + jbyteArray inputArray, jint inputOff, jint inputLen, + jlong outputBuffer, jint outputLen) +{ + jbyte *input = (*env)->GetPrimitiveArrayCritical(env, inputArray, 0); + if (input == NULL) { + if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; + } + jbyte *output = jlong_to_ptr(outputBuffer); + + jlong retVal = doInflate(env, this, addr, + input + inputOff, inputLen, + output, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBufferBytes(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jbyteArray outputArray, jint outputOff, jint outputLen) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); + if (output == NULL) { + if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + JNU_ThrowOutOfMemoryError(env, 0); + return 0L; } + + jlong retVal = doInflate(env, this, addr, + input, inputLen, + output + outputOff, outputLen); + + (*env)->ReleasePrimitiveArrayCritical(env, outputArray, input, 0); + + return retVal; +} + +JNIEXPORT jlong JNICALL +Java_java_util_zip_Inflater_inflateBufferBuffer(JNIEnv *env, jobject this, jlong addr, + jlong inputBuffer, jint inputLen, + jlong outputBuffer, jint outputLen) +{ + jbyte *input = jlong_to_ptr(inputBuffer); + jbyte *output = jlong_to_ptr(outputBuffer); + + return doInflate(env, this, addr, + input, inputLen, + output, outputLen); } JNIEXPORT jint JNICALL diff --git a/test/jdk/java/util/zip/FlaterTest.java b/test/jdk/java/util/zip/FlaterTest.java index 7245440d033..b5aff0319b3 100644 --- a/test/jdk/java/util/zip/FlaterTest.java +++ b/test/jdk/java/util/zip/FlaterTest.java @@ -29,7 +29,6 @@ * @key randomness */ -import java.io.*; import java.nio.*; import java.util.*; import java.util.zip.*; @@ -41,35 +40,37 @@ import java.util.zip.*; */ public class FlaterTest extends Thread { private static final int DATA_LEN = 1024 * 128; - private static byte[] data; + + private static ByteBuffer dataDirect; + private static ByteBuffer dataHeap; // If true, print extra info. private static final boolean debug = false; // Set of Flater threads running. - private static Set flaters = - Collections.synchronizedSet(new HashSet()); + private static Set flaters = + Collections.synchronizedSet(new HashSet<>()); /** Fill in {@code data} with random values. */ static void createData() { - ByteBuffer bb = ByteBuffer.allocate(8); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - for (int i = 0; i < DATA_LEN; i++) { - bb.putDouble(0, Math.random()); - baos.write(bb.array(), 0, 8); + ByteBuffer bb = ByteBuffer.allocateDirect(DATA_LEN * 8); + for (int i = 0; i < DATA_LEN * 8; i += 8) { + bb.putDouble(i, Math.random()); } - data = baos.toByteArray(); - if (debug) System.out.println("data length is " + data.length); + dataDirect = bb; + final ByteBuffer hb = ByteBuffer.allocate(bb.capacity()); + hb.duplicate().put(bb.duplicate()); + dataHeap = hb; + if (debug) System.out.println("data length is " + bb.capacity()); } /** @return the length of the deflated {@code data}. */ - private static int getDeflatedLength() throws Throwable { - int rc = 0; + private static int getDeflatedLength() { Deflater deflater = new Deflater(); - deflater.setInput(data); + deflater.setInput(dataDirect.duplicate()); deflater.finish(); - byte[] out = new byte[data.length]; - rc = deflater.deflate(out); + byte[] out = new byte[dataDirect.capacity()]; + int rc = deflater.deflate(out); deflater.end(); if (debug) System.out.println("deflatedLength is " + rc); return rc; @@ -78,70 +79,98 @@ public class FlaterTest extends Thread { /** Compares given bytes with those in {@code data}. * @throws Exception if given bytes don't match {@code data}. */ - private static void validate(byte[] buf, int offset, int len) throws Exception { + private static void validate(ByteBuffer buf, int offset, int len) throws Exception { for (int i = 0; i < len; i++ ) { - if (buf[i] != data[offset+i]) { + if (buf.get(i) != dataDirect.get(offset+i)) { throw new Exception("mismatch at " + (offset + i)); } } } - public static void realMain(String[] args) throws Throwable { - createData(); + public static void realMain(String[] args) { int numThreads = args.length > 0 ? Integer.parseInt(args[0]) : 5; - new FlaterTest().go(numThreads); + createData(); + for (int srcMode = 0; srcMode <= 2; srcMode ++) { + for (int dstMode = 0; dstMode <= 2; dstMode ++) { + new FlaterTest().go(numThreads, srcMode, dstMode); + } + } } - private synchronized void go(int numThreads) throws Throwable { + private synchronized void go(int numThreads, int srcMode, int dstMode) { int deflatedLength = getDeflatedLength(); long time = System.currentTimeMillis(); for (int i = 0; i < numThreads; i++) { - Flater f = new Flater(deflatedLength); + Flater f = new Flater(deflatedLength, srcMode, dstMode); flaters.add(f); f.start(); } - while (flaters.size() != 0) { - try { - Thread.currentThread().sleep(10); - } catch (InterruptedException ex) { - unexpected(ex); + synchronized (flaters) { + while (flaters.size() != 0) { + try { + flaters.wait(); + } catch (InterruptedException ex) { + unexpected(ex); + } } } time = System.currentTimeMillis() - time; System.out.println("Time needed for " + numThreads - + " threads to deflate/inflate: " + time + " ms."); + + " threads to deflate/inflate: " + time + " ms (srcMode="+srcMode+",dstMode="+dstMode+")"); } /** Deflates and inflates data. */ static class Flater extends Thread { private final int deflatedLength; + private final int srcMode, dstMode; - private Flater(int length) { + private Flater(int length, int srcMode, int dstMode) { this.deflatedLength = length; + this.srcMode = srcMode; + this.dstMode = dstMode; } /** Deflates and inflates {@code data}. */ public void run() { if (debug) System.out.println(getName() + " starting run()"); try { - byte[] deflated = DeflateData(deflatedLength); + ByteBuffer deflated = DeflateData(deflatedLength); InflateData(deflated); } catch (Throwable t) { t.printStackTrace(); fail(getName() + " failed"); } finally { - flaters.remove(this); + synchronized (flaters) { + flaters.remove(this); + if (flaters.isEmpty()) { + flaters.notifyAll(); + } + } } } /** Returns a copy of {@code data} in deflated form. */ - private byte[] DeflateData(int length) throws Throwable { + private ByteBuffer DeflateData(int length) { Deflater deflater = new Deflater(); - deflater.setInput(data); + if (srcMode == 0) { + deflater.setInput(dataHeap.array()); + } else if (srcMode == 1) { + deflater.setInput(dataHeap.duplicate()); + } else { + assert srcMode == 2; + deflater.setInput(dataDirect.duplicate()); + } deflater.finish(); - byte[] out = new byte[length]; - deflater.deflate(out); + ByteBuffer out = dstMode == 2 ? ByteBuffer.allocateDirect(length) : ByteBuffer.allocate(length); + int deflated; + if (dstMode == 0) { + deflated = deflater.deflate(out.array(), 0, length); + out.position(deflated); + } else { + deflater.deflate(out); + } + out.flip(); return out; } @@ -149,14 +178,30 @@ public class FlaterTest extends Thread { * inflation. * @throws Exception if inflated bytes don't match {@code data}. */ - private void InflateData(byte[] bytes) throws Throwable { + private void InflateData(ByteBuffer bytes) throws Throwable { Inflater inflater = new Inflater(); - inflater.setInput(bytes, 0, bytes.length); + if (dstMode == 0) { + inflater.setInput(bytes.array(), 0, bytes.remaining()); + } else { + inflater.setInput(bytes); + } + if (inflater.getRemaining() == 0) { + throw new Exception("Nothing to inflate (bytes=" + bytes + ")"); + } int len = 1024 * 8; int offset = 0; + ByteBuffer buf = srcMode == 2 ? ByteBuffer.allocateDirect(len) : ByteBuffer.allocate(len); while (inflater.getRemaining() > 0) { - byte[] buf = new byte[len]; - int inflated = inflater.inflate(buf, 0, len); + buf.clear(); + int inflated; + if (srcMode == 0) { + inflated = inflater.inflate(buf.array(), 0, buf.remaining()); + } else { + inflated = inflater.inflate(buf); + } + if (inflated == 0) { + throw new Exception("Nothing inflated (dst=" + buf + ",offset=" + offset + ",rem=" + inflater.getRemaining() + ",srcMode="+srcMode+",dstMode="+dstMode+")"); + } validate(buf, offset, inflated); offset += inflated; } From karen.kinnear at oracle.com Wed Mar 28 13:43:13 2018 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Wed, 28 Mar 2018 09:43:13 -0400 Subject: RFR: 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull In-Reply-To: References: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> <5829E498-2176-49C2-ACE8-5E7F232D2632@oracle.com> <2414aaf1-c7b0-56f0-58cd-84ee852e749f@oracle.com> Message-ID: <69E1D6AF-84D5-46DC-9BD9-BD9CCA49F4C4@oracle.com> Claes, Thank you for this fix. Glad it makes a startup difference. Agree with Lois. thanks, Karen p.s. haven?t had a chance to trace the logic of your explanation below in a debugger - I don?t quite follow it. But the fix makes sense. > On Mar 27, 2018, at 11:57 AM, Lois Foltan wrote: > > On 3/27/2018 2:49 AM, Claes Redestad wrote: > >> >> >> On 2018-03-26 17:51, Claes Redestad wrote: >>> Karen, >>> >>> On 2018-03-26 17:15, Karen Kinnear wrote: >>>> Claes, >>>> >>>> Discussed with Lois. We think that it would make more sense to pass the new argument into MethodHandles::resolve_MemberName and at all three places that we currently CHECK_PENDING_EXCEPTION/return null there >>>> - if speculative flag is set - CLEAR_PENDING_EXCEPTION before you return null >>>> - and yes - do this for all three cases, not just the METHOD case >>> >>> ok. >> >> New webrev: >> >> http://cr.openjdk.java.net/~redestad/8200238/open.01/ > > Hi Claes, > Looks good. One minor comment. > > hotspot/share/prims/methodHandles.cpp: > - line #1237. Consider putting some explanation in the assert statement instead of a blank string. Something like "speculative resolve mode has encountered an unexpected pending exception" > > I don't need to see another webrev. > > Thanks, > Lois > >> >> Thanks! >> >> /Claes From Roger.Riggs at Oracle.com Wed Mar 28 17:27:42 2018 From: Roger.Riggs at Oracle.com (Roger Riggs) Date: Wed, 28 Mar 2018 13:27:42 -0400 Subject: RFR 8197595: Serialization javadoc should link to security best practices In-Reply-To: References: <203836fb-abd6-1191-9499-b96e6a29ad3d@Oracle.com> Message-ID: Hi, Updated with editorial suggestions. webrev: http://cr.openjdk.java.net/~rriggs/webrev-serialwarn-8197595/index.html javadoc: http://cr.openjdk.java.net/~rriggs/serialwarn/api/java.base/java/io/package-summary.html Thanks for the reviews, Roger On 3/23/2018 12:57 PM, Lance Andersen wrote: > Looks good to me also Roger with Sean?s suggestions :-) > >> On Mar 23, 2018, at 10:12 AM, Roger Riggs > > wrote: >> >> Please review adding a warning and a link to the Secure Coding Guidelines >> and the new Serial Filter guide[2] included in the JDK 10 docs. >> The warnings are added to Serializable, ObjectInputStream, >> ObjectInputFilter and >> the java.io package summary. >> >> webrev: >> http://cr.openjdk.java.net/~rriggs/webrev-serialwarn-8197595/index.html >> >> >> javadoc: >> http://cr.openjdk.java.net/~rriggs/serialwarn/api/java.base/java/io/package-summary.html >> >> Thanks, Roger >> >> [2] >> https://docs.oracle.com/javase/10/core/serialization-filtering1.htm#JSCOR-GUID-3ECB288D-E5BD-4412-892F-E9BB11D4C98A >> >> > > > > Lance > Andersen| Principal Member of Technical Staff | +1.781.442.2037 > Oracle?Java Engineering > 1 Network Drive > Burlington, MA 01803 > Lance.Andersen at oracle.com > > > From martinrb at google.com Wed Mar 28 17:54:51 2018 From: martinrb at google.com (Martin Buchholz) Date: Wed, 28 Mar 2018 10:54:51 -0700 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: <25cf9047-8169-5864-6b24-4a1a32997c1c@oracle.com> References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> <25cf9047-8169-5864-6b24-4a1a32997c1c@oracle.com> Message-ID: On Wed, Mar 28, 2018 at 4:30 AM, mandy chung wrote: > > I was wondering how Martin made the decision to mark it with @Stable. In > addition to the above, the ID is mostly used in tracing. I'd like to see > performance number for adding @Stable. > OK, I had "no good reason" for using @Stable here, except that all these core library classes are fundamentally performance sensitive. @Stable has been removed. 8200123: Replace Thread.init with telescoping constructor http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-init/ https://bugs.openjdk.java.net/browse/JDK-8200123 From lance.andersen at oracle.com Wed Mar 28 18:13:13 2018 From: lance.andersen at oracle.com (Lance Andersen) Date: Wed, 28 Mar 2018 14:13:13 -0400 Subject: RFR 8197595: Serialization javadoc should link to security best practices In-Reply-To: References: <203836fb-abd6-1191-9499-b96e6a29ad3d@Oracle.com> Message-ID: <7EF629C0-28E0-40E0-A069-F9155AE8911F@oracle.com> Hi Roger, Looks good to go to me! Best Lance > On Mar 28, 2018, at 1:27 PM, Roger Riggs wrote: > > Hi, > > Updated with editorial suggestions. > > webrev: > http://cr.openjdk.java.net/~rriggs/webrev-serialwarn-8197595/index.html > > javadoc: > http://cr.openjdk.java.net/~rriggs/serialwarn/api/java.base/java/io/package-summary.html > > Thanks for the reviews, Roger > > On 3/23/2018 12:57 PM, Lance Andersen wrote: >> Looks good to me also Roger with Sean?s suggestions :-) >> >>> On Mar 23, 2018, at 10:12 AM, Roger Riggs > wrote: >>> >>> Please review adding a warning and a link to the Secure Coding Guidelines >>> and the new Serial Filter guide[2] included in the JDK 10 docs. >>> The warnings are added to Serializable, ObjectInputStream, ObjectInputFilter and >>> the java.io package summary. >>> >>> webrev: >>> http://cr.openjdk.java.net/~rriggs/webrev-serialwarn-8197595/index.html >>> >>> javadoc: >>> http://cr.openjdk.java.net/~rriggs/serialwarn/api/java.base/java/io/package-summary.html >>> >>> Thanks, Roger >>> >>> [2] https://docs.oracle.com/javase/10/core/serialization-filtering1.htm#JSCOR-GUID-3ECB288D-E5BD-4412-892F-E9BB11D4C98A >>> >>> >> >> >> >> 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 erik.joelsson at oracle.com Wed Mar 28 20:17:39 2018 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Wed, 28 Mar 2018 13:17:39 -0700 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <3fce1a22-39e4-b8ba-0713-03cd013a6709@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> <86488d2c-61e3-e489-d9fc-976178c35775@oracle.com> <2329dea1-a75e-bb70-95a6-242a93006c6d@oracle.com> <32db4add-8a59-03db-0074-e7df0aed14b8@oracle.com> <3fce1a22-39e4-b8ba-0713-03cd013a6709@oracle.com> Message-ID: Build changes still look good to me. /Erik On 2018-03-28 03:31, Magnus Ihse Bursie wrote: > On 2018-03-28 01:52, Weijun Wang wrote: >> >>> On Mar 24, 2018, at 6:03 AM, Magnus Ihse Bursie >>> wrote: >>> >>> https://bugs.openjdk.java.net/browse/JDK-8200193 -- for >>> jdk.security.auth >> There is only one function to export and it already has JNIEXPORT, so >> you can just remove the new $(LIBJAAS_CFLAGS) [1]. > Ok, thanks Max! >> Are you going to update your webrev? > Here is a new webrev. It includes your recommended change in > Lib-jdk.security.auth.gmk. > > It is also updated to keep track of changes in shared native libraries > that has happend in the mainline since my first webrev. Most notably > is the addition of libjsig. For now, I have just added the JNIEXPORT > markers for the platforms that need it. Hopefully we can unify libjsig > across all platforms, but that seems to be more complicated than I > thought, so that'll have to wait. > > I have also recieved word from Phil Race that there were no testing > issues for client, so he's happy as well. > > Updated webrev: > http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.03 > > /Magnus > >> >> Thanks >> Max >> >> [1] >> http://cr.openjdk.java.net/~ihse/JDK-8200178-remove-mapfiles/webrev.01/make/lib/Lib-jdk.security.auth.gmk.sdiff.html > From martinrb at google.com Wed Mar 28 21:53:10 2018 From: martinrb at google.com (Martin Buchholz) Date: Wed, 28 Mar 2018 14:53:10 -0700 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> Message-ID: I can't find any documentation for what JNIEXPORT and friends actually do. People including myself have been cargo-culting JNIEXPORT and JNICALL for decades. Why aren't they in the JNI spec? --- It's fishy that the attribute externally_visible (which seems very interesting!) is ARM specific. #ifdef ARM #define JNIEXPORT __attribute__((externally_visible,visibility("default"))) #define JNIIMPORT __attribute__((externally_visible,visibility("default"))) #else #define JNIEXPORT __attribute__((visibility("default"))) #define JNIIMPORT __attribute__((visibility("default"))) #endif From magnus.ihse.bursie at oracle.com Wed Mar 28 22:14:13 2018 From: magnus.ihse.bursie at oracle.com (Magnus Ihse Bursie) Date: Thu, 29 Mar 2018 00:14:13 +0200 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> Message-ID: <5e7f7a0c-bf52-e095-ede6-a2599376cb22@oracle.com> On 2018-03-28 23:53, Martin Buchholz wrote: > I can't find any documentation for what JNIEXPORT and friends actually do. > People including myself have been cargo-culting JNIEXPORT and JNICALL > for decades. > Why aren't they in the JNI spec? That surprises me. I'm quite certain that javah (or rather, java -h nowadays) generate header files with JNIEXPORT and JNICALL. As you can see in the jni.h and jni_md.h files, JNIEXPORT equals __attribute__((visibility("default"))) for compilers that support it (gcc and friends), and __declspec(dllexport) for Windows. This means, that the symbol should be exported. (And it's ignored if you use mapfiles aka linker scripts.) As for JNICALL, it's empty on most compilers, but evaluates to __stdcall on Windows. This defines the calling convention to use. This is required for JNI calls from Java. (Ask the JVM team why.) While it's not technically required for calling from one dll to another, it's good practice to use it all time to be consistent. In any way, it doesn't hurt us. > > --- > > It's fishy that the attribute externally_visible (which seems very > interesting!) is ARM specific. > > ? #ifdef ARM > ? ? #define JNIEXPORT > ?__attribute__((externally_visible,visibility("default"))) > ? ? #define JNIIMPORT > ?__attribute__((externally_visible,visibility("default"))) Yeah, this is broken on so many levels. :-( The ARM here goes back to the old Oracle proprietary arm32 port. This used lto, link time optimization, to get an absolutely minimal runtime, at expense of a extremely long built time. (I think linking libjvm took like 20 minutes.) But when using lto, you also need to decorate your functions with the externally_visible attribute. So this was added to get hotspot to export the proper symbols (since they, too, used the jni.h file). So, in short, we should: 1) have used a special, local jni.h file for the proprietary arm port, and/or 2) added the externally_visible attribute not based on platform, but on the existence of lto. At this point in time, we're not building the old 32-bit arm port, and I doubt anyone does. And even if so, we could probably remove the lto part, and thus remove this from jni_md.h. If you want, please file a bug. /Magnus > ? #else > ? ? #define JNIEXPORT ?__attribute__((visibility("default"))) > ? ? #define JNIIMPORT ?__attribute__((visibility("default"))) > ? #endif > From mandy.chung at oracle.com Wed Mar 28 22:36:45 2018 From: mandy.chung at oracle.com (mandy chung) Date: Thu, 29 Mar 2018 06:36:45 +0800 Subject: RFR: Here are some Thread cleanup patches In-Reply-To: References: <59ed6521-6cab-3d2a-5105-635c726251a6@oracle.com> <25cf9047-8169-5864-6b24-4a1a32997c1c@oracle.com> Message-ID: On 3/29/18 1:54 AM, Martin Buchholz wrote: > > > On Wed, Mar 28, 2018 at 4:30 AM, mandy chung > wrote: > > > I was wondering how Martin made the decision to mark it with > @Stable. In addition to the above, the ID is mostly used in > tracing.? I'd like to see performance number for adding @Stable. > > > OK, I had "no good reason" for using @Stable here, except that all > these core library classes are fundamentally performance sensitive.? > @Stable has been removed. > +1 > 8200123: Replace Thread.init with telescoping constructor > http://cr.openjdk.java.net/~martin/webrevs/jdk/Thread-init/ > > https://bugs.openjdk.java.net/browse/JDK-8200123 Looks good. Mandy From xu.y.yin at oracle.com Thu Mar 29 01:59:33 2018 From: xu.y.yin at oracle.com (Chris Yin) Date: Thu, 29 Mar 2018 09:59:33 +0800 Subject: RFR 8196668: revisit test SunPackageAccess and GrantedSunPackageAccess Message-ID: Please review the change to merge 2 package access tests and move to OpenJDK, thanks bug: https://bugs.openjdk.java.net/browse/JDK-8196668 webrev: http://cr.openjdk.java.net/~xyin/8196668/webrev.00/ Regards, Chris From xueming.shen at oracle.com Thu Mar 29 04:38:39 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Wed, 28 Mar 2018 21:38:39 -0700 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> <10728b43-110c-5dc3-1fdb-2e0241e3a0ff@oracle.com> Message-ID: <5ABC6DCF.10504@oracle.com> On 3/28/18, 6:14 AM, David Lloyd wrote: > >>> The current wording (which pre-dates your changes of course) reads more like >>> API advice. I think it's a bit confusing too as it doesn't define what a >>> "flush marker" is. I think we will need to re-word that sentence to make it >>> clearer. >> OK. I am at a loss for a better way to explain it though; any suggestions? > I've implemented all the other changes except for this one. Latest > version is attached, online version is here [1]. > > "flush marker" was copy/pasted from the original zlib.h api doc when I added the support for different flush options. It might be better to put it is a apiNote. A "flush marker" in this case is a 5-byte empty block, which will be output if the deflater does not have enough space to output the bytes and it is in full_flush or sync_flush mode. I think you can leave it as is for now and I will try to see if I can move it around or add some understandable wording, if I can. -Sherman From mandy.chung at oracle.com Thu Mar 29 04:48:32 2018 From: mandy.chung at oracle.com (mandy chung) Date: Thu, 29 Mar 2018 12:48:32 +0800 Subject: RFR 8196668: revisit test SunPackageAccess and GrantedSunPackageAccess In-Reply-To: References: Message-ID: On 3/29/18 9:59 AM, Chris Yin wrote: > Please review the change to merge 2 package access tests and move to OpenJDK, thanks > > bug: https://bugs.openjdk.java.net/browse/JDK-8196668 > webrev: http://cr.openjdk.java.net/~xyin/8196668/webrev.00/ > Looks okay.? Minor comments: 88 throw new RuntimeException("Unexpected AccessControlException", 89 ace); 92 throw new RuntimeException("Test failed with unexpected exception", 93 ex); Nit: each throw statement can be merged in 1 line. test/jdk/java/lang/SecurityManager/empty.policy can you add a comment saying this is an empty policy. No need to generate a new webrev. You can fix it before you push. Mandy From xu.y.yin at oracle.com Thu Mar 29 05:45:20 2018 From: xu.y.yin at oracle.com (Chris Yin) Date: Thu, 29 Mar 2018 13:45:20 +0800 Subject: RFR 8196668: revisit test SunPackageAccess and GrantedSunPackageAccess In-Reply-To: References: Message-ID: <1878DD3B-4E5E-4235-A749-4C5CFD43F087@oracle.com> Thank you, Mandy. I just fixed it follow your comments and get it pushed. Regards, Chris > On 29 Mar 2018, at 12:48 PM, mandy chung > wrote: > > > > On 3/29/18 9:59 AM, Chris Yin wrote: >> Please review the change to merge 2 package access tests and move to OpenJDK, thanks >> >> bug: https://bugs.openjdk.java.net/browse/JDK-8196668 >> webrev: http://cr.openjdk.java.net/~xyin/8196668/webrev.00/ >> > > Looks okay. Minor comments: > 88 throw new RuntimeException("Unexpected AccessControlException", > 89 ace); > > 92 throw new RuntimeException("Test failed with unexpected exception", > 93 ex); > > Nit: each throw statement can be merged in 1 line. > > test/jdk/java/lang/SecurityManager/empty.policy > can you add a comment saying this is an empty policy. > > No need to generate a new webrev. You can fix it before you push. > > Mandy From martinrb at google.com Thu Mar 29 06:16:18 2018 From: martinrb at google.com (Martin Buchholz) Date: Wed, 28 Mar 2018 23:16:18 -0700 Subject: RFR: JDK-8200178 Remove mapfiles for JDK native libraries In-Reply-To: <5e7f7a0c-bf52-e095-ede6-a2599376cb22@oracle.com> References: <9b6ec99a-1f75-3302-36cb-679b59291a20@oracle.com> <5e7f7a0c-bf52-e095-ede6-a2599376cb22@oracle.com> Message-ID: On Wed, Mar 28, 2018 at 3:14 PM, Magnus Ihse Bursie < magnus.ihse.bursie at oracle.com> wrote: > On 2018-03-28 23:53, Martin Buchholz wrote: > > I can't find any documentation for what JNIEXPORT and friends actually do. > People including myself have been cargo-culting JNIEXPORT and JNICALL for > decades. > Why aren't they in the JNI spec? > > That surprises me. I'm quite certain that javah (or rather, java -h > nowadays) generate header files with JNIEXPORT and JNICALL. > > As you can see in the jni.h and jni_md.h files, JNIEXPORT equals > __attribute__((visibility("default"))) for compilers that support it (gcc > and friends), and __declspec(dllexport) for Windows. This means, that the > symbol should be exported. (And it's ignored if you use mapfiles aka linker > scripts.) > > As for JNICALL, it's empty on most compilers, but evaluates to __stdcall > on Windows. This defines the calling convention to use. This is required > for JNI calls from Java. (Ask the JVM team why.) While it's not technically > required for calling from one dll to another, it's good practice to use it > all time to be consistent. In any way, it doesn't hurt us. > Sure, I can see how JNIEXPORT and JNICALL are implemented, but what do they *mean?* For example, one might expect from the JNI prefix that these macros are exclusively for use by JNI linking, i.e. unsupported except in the output of javac -h. But of course in practice they are used with arbitrary symbols to communicate between components of user native code, not just to communicate with the JVM. Is that a bug? From claes.redestad at oracle.com Thu Mar 29 07:40:07 2018 From: claes.redestad at oracle.com (Claes Redestad) Date: Thu, 29 Mar 2018 09:40:07 +0200 Subject: RFR: 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull In-Reply-To: References: <3f8518e5-a44c-d344-be05-121ae1a4468a@oracle.com> <5829E498-2176-49C2-ACE8-5E7F232D2632@oracle.com> <2414aaf1-c7b0-56f0-58cd-84ee852e749f@oracle.com> Message-ID: <2deb3730-f064-8cbd-9d9f-46a38e2c230f@oracle.com> On 2018-03-27 17:57, Lois Foltan wrote: >> >> http://cr.openjdk.java.net/~redestad/8200238/open.01/ > > Hi Claes, > Looks good.? One minor comment. > > hotspot/share/prims/methodHandles.cpp: > - line #1237.? Consider putting some explanation in the assert > statement instead of a blank string.? Something like "speculative > resolve mode has encountered an unexpected pending exception" Will do! > > I don't need to see another webrev. Thanks! /Claes From david.lloyd at redhat.com Thu Mar 29 12:18:30 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Thu, 29 Mar 2018 07:18:30 -0500 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: <5ABC6DCF.10504@oracle.com> References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> <10728b43-110c-5dc3-1fdb-2e0241e3a0ff@oracle.com> <5ABC6DCF.10504@oracle.com> Message-ID: On Wed, Mar 28, 2018 at 11:38 PM, Xueming Shen wrote: > On 3/28/18, 6:14 AM, David Lloyd wrote: >> I've implemented all the other changes except for this one. Latest >> version is attached, online version is here [1]. > > "flush marker" was copy/pasted from the original zlib.h api doc when I added the > support for different flush options. It might be better to put it is a apiNote. A > "flush marker" in this case is a 5-byte empty block, which will be output if the > deflater does not have enough space to output the bytes and it is in full_flush or > sync_flush mode. I think you can leave it as is for now and I will try to see if I > can move it around or add some understandable wording, if I can. OK great. In that case, I think all feedback has been accounted for, and this should be ready to go AFAIK. Thanks! -- - DML From brian.burkhalter at oracle.com Thu Mar 29 19:01:23 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Thu, 29 Mar 2018 12:01:23 -0700 Subject: 8200449: ReadAllReadNTransferTo fails occasionally Message-ID: <9122D6AB-6D2C-418C-8722-296772BDB4AC@oracle.com> https://bugs.openjdk.java.net/browse/JDK-8200449 Problem is due to passing zero to Random.nextInt(int). Diff included below. Thanks, Brian --- a/test/jdk/java/io/ByteArrayInputStream/ReadAllReadNTransferTo.java +++ b/test/jdk/java/io/ByteArrayInputStream/ReadAllReadNTransferTo.java @@ -43,22 +43,22 @@ private static Random random = RandomFactory.getRandom(); public static void main(String... args) throws IOException { byte[] buf = new byte[SIZE]; random.nextBytes(buf); int position = random.nextInt(SIZE/2); int size = random.nextInt(SIZE - position); ByteArrayInputStream bais = new ByteArrayInputStream(buf, position, size); - int off = random.nextInt(size / 2); - int len = random.nextInt(size - off); + int off = size < 2 ? 0 : random.nextInt(size / 2); + int len = size - off < 1 ? 0 : random.nextInt(size - off); byte[] bN = new byte[off + len]; if (bais.readNBytes(bN, off, len) != len) { throw new RuntimeException("readNBytes return value"); } if (!Arrays.equals(bN, off, off + len, buf, position, position + len)) { throw new RuntimeException("readNBytes content"); } From chris.hegarty at oracle.com Thu Mar 29 19:07:09 2018 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Thu, 29 Mar 2018 20:07:09 +0100 Subject: 8200449: ReadAllReadNTransferTo fails occasionally In-Reply-To: <9122D6AB-6D2C-418C-8722-296772BDB4AC@oracle.com> References: <9122D6AB-6D2C-418C-8722-296772BDB4AC@oracle.com> Message-ID: <75DB8509-2A8F-4035-82ED-156A8FA75ACC@oracle.com> +1 -Chris. > On 29 Mar 2018, at 20:01, Brian Burkhalter wrote: > > https://bugs.openjdk.java.net/browse/JDK-8200449 > > Problem is due to passing zero to Random.nextInt(int). Diff included below. > > Thanks, > > Brian > > --- a/test/jdk/java/io/ByteArrayInputStream/ReadAllReadNTransferTo.java > +++ b/test/jdk/java/io/ByteArrayInputStream/ReadAllReadNTransferTo.java > @@ -43,22 +43,22 @@ > private static Random random = RandomFactory.getRandom(); > > public static void main(String... args) throws IOException { > byte[] buf = new byte[SIZE]; > random.nextBytes(buf); > int position = random.nextInt(SIZE/2); > int size = random.nextInt(SIZE - position); > > ByteArrayInputStream bais = > new ByteArrayInputStream(buf, position, size); > - int off = random.nextInt(size / 2); > - int len = random.nextInt(size - off); > + int off = size < 2 ? 0 : random.nextInt(size / 2); > + int len = size - off < 1 ? 0 : random.nextInt(size - off); > > byte[] bN = new byte[off + len]; > if (bais.readNBytes(bN, off, len) != len) { > throw new RuntimeException("readNBytes return value"); > } > if (!Arrays.equals(bN, off, off + len, > buf, position, position + len)) { > throw new RuntimeException("readNBytes content"); > } > From stuart.marks at oracle.com Fri Mar 30 01:12:13 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Thu, 29 Mar 2018 18:12:13 -0700 Subject: RFR: 8195649: reorganize tests for java.util.Optional Message-ID: <99114b70-464e-c757-3665-8f1058feb68d@oracle.com> Hi all, Please review this changeset, which reorganizes (basically rewrites) the tests for Optional and Optional{Double,Int,Long}. The new arrangement clusters all the assertions together into check* methods. These are then called on the results of the various factories and other monadic operations. This reduced the amount of test code and actually increased the test coverage slightly. Bug: https://bugs.openjdk.java.net/browse/JDK-8195649 Webrev: http://cr.openjdk.java.net/~smarks/reviews/8195649/webrev.0/ Thanks, s'marks From martinrb at google.com Fri Mar 30 01:55:50 2018 From: martinrb at google.com (Martin Buchholz) Date: Thu, 29 Mar 2018 18:55:50 -0700 Subject: RFR: More cleanup patches Message-ID: 8199800: Optimize Boolean.parseBoolean(String) http://cr.openjdk.java.net/~martin/webrevs/jdk/Boolean-parseBoolean/ https://bugs.openjdk.java.net/browse/JDK-8199800 8200364: Remove unnecessary boxing via primitive wrapper valueOf(String) methods http://cr.openjdk.java.net/~martin/webrevs/jdk/valueOf-boxing/ https://bugs.openjdk.java.net/browse/JDK-8200364 8199947: Rename HTML element id in ClassLoader javadoc to avoid name conflict with private elements http://cr.openjdk.java.net/~martin/webrevs/jdk/ClassLoader-binary-name-anchor/ https://bugs.openjdk.java.net/browse/JDK-8199947 8200125: Fix some classloader/module typos http://cr.openjdk.java.net/~martin/webrevs/jdk/loader-typos/ https://bugs.openjdk.java.net/browse/JDK-8200125 8200127: Replace collection.stream().forEach() with collection.forEach() http://cr.openjdk.java.net/~martin/webrevs/jdk/redundant-stream/ https://bugs.openjdk.java.net/browse/JDK-8200127 Who knew it could be so hard to spell "annotation"? 8200128: Fix some "annoations" typos http://cr.openjdk.java.net/~martin/webrevs/jdk/annoations/ https://bugs.openjdk.java.net/browse/JDK-8200128 8200131: Improve lazy init of InetAddress.canonicalHostName and NativeObject.pageSize http://cr.openjdk.java.net/~martin/webrevs/jdk/lazy-init-local-vars/ https://bugs.openjdk.java.net/browse/JDK-8200131 Apologies to Alan - I had never looked at a topological sort before and got carried away. 8200134: Improve ModuleHashesBuilder http://cr.openjdk.java.net/~martin/webrevs/jdk/ModuleHashesBuilder/ https://bugs.openjdk.java.net/browse/JDK-8200134 From peter.levart at gmail.com Fri Mar 30 08:16:56 2018 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 30 Mar 2018 10:16:56 +0200 Subject: Fwd: Re: RFR: Some patches for sherman In-Reply-To: References: Message-ID: <26c8ce5e-4872-e5b9-00bb-8ea92a5c5fc4@gmail.com> I'm forwarding this private message to core-libs-dev so a qualified person may read it... Regards, Peter -------- Forwarded Message -------- Subject: Re: RFR: Some patches for sherman Date: Fri, 30 Mar 2018 06:18:26 +0000 From: Peter Levart To: Martin Buchholz Hi Martin, On Fri, 30 Mar 2018, 05:28 Martin Buchholz, > wrote: On Thu, Mar 29, 2018 at 7:57 AM, Peter Levart > wrote: Hi Martin, On 03/27/2018 02:21 AM, Martin Buchholz wrote: > 8200124: Various cleanups in jar/zip > http://cr.openjdk.java.net/~martin/webrevs/jdk/zip-cleanup/ > > https://bugs.openjdk.java.net/browse/JDK-8200124 As I already mentioned for your Thread cleanup patch, do you think that ZipFile objects are something that ever gets assigned to static final or @Stable fields? Only in that case would @Stable have any effect for ZipFile fields. @Stable should really be reserved for classes which instances are normally assigned to static final fields, such as ThreadLocal, ClassValue, etc... If the holder of the @Stable field can not be made constant, then neither can the value of that field. Peter, I was very surprised by your reply.? I re-read the doc for Stable and it says to me that in ZipFile z = ... while (...) { ? z.res ... } z.res only needs to be read once. This is true even without @Stable on res field. And JIT already does all it can without it. What JIT cannot do in above situation is make the value of res a compile-time constant embedded in generated code, possibly triggering other optimizations that arrise from the value of the field. And the reason is not the absense of @Stable but the fact that ZipFile instance can not be prooved to be constant. If hotspot only optimizes @Stable for static fields, I would regard that as a bug. Only being able to optimize static fields is not very useful. It optimizes (constant-folds) @Stable static fields and @Stable instance fields for which it can proove that the holder object can not change during the lifetime of generated code. In practice this means that there has to be a chain of @Stable fields leading to optimized value, rooted at some static final or static @Stable field. Maybe the same optimization could also be applied for locals that are accessed in a loop for which the JIT could proove that it never ends or if it ends that the generated code is deoptimized. But I doubt this is what current JIT does. In your ZipFile case this would mean JIT would be generating separate code blob for each ZipFile instance. All above is just a speculation and how I understand the @ Stable amnotation. Someone more qualified could chime-in clear things a bit. Regards, Peter From daniel.fuchs at oracle.com Fri Mar 30 09:59:40 2018 From: daniel.fuchs at oracle.com (Daniel Fuchs) Date: Fri, 30 Mar 2018 10:59:40 +0100 Subject: RFR: More cleanup patches In-Reply-To: References: Message-ID: Hi Martin, On 30/03/2018 02:55, Martin Buchholz wrote: > 8200364: Remove unnecessary boxing via primitive wrapper valueOf(String) > methods > http://cr.openjdk.java.net/~martin/webrevs/jdk/valueOf-boxing/ > https://bugs.openjdk.java.net/browse/JDK-8200364 The changes above look fine to me. I'll let other reviewers give feedback for the other changes. best regards, -- daniel From Alan.Bateman at oracle.com Fri Mar 30 10:53:30 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 30 Mar 2018 11:53:30 +0100 Subject: RFR: More cleanup patches In-Reply-To: References: Message-ID: <9244499d-625e-e191-4304-9e37f12dbfee@oracle.com> On 30/03/2018 02:55, Martin Buchholz wrote: > 8199800: Optimize Boolean.parseBoolean(String) > http://cr.openjdk.java.net/~martin/webrevs/jdk/Boolean-parseBoolean/ > https://bugs.openjdk.java.net/browse/JDK-8199800 Looks okay. > 8200364: Remove unnecessary boxing via primitive wrapper valueOf(String) > methods > http://cr.openjdk.java.net/~martin/webrevs/jdk/valueOf-boxing/ > https://bugs.openjdk.java.net/browse/JDK-8200364 Looks okay. > > 8199947: Rename HTML element id in ClassLoader javadoc to avoid name > conflict with private elements > http://cr.openjdk.java.net/~martin/webrevs/jdk/ClassLoader-binary-name-anchor/ > https://bugs.openjdk.java.net/browse/JDK-8199947 Looks okay. > 8200125: Fix some classloader/module typos > http://cr.openjdk.java.net/~martin/webrevs/jdk/loader-typos/ > https://bugs.openjdk.java.net/browse/JDK-8200125 Most of these are okay but you've dropped the text "defined to this ClassLoader" from the findClassInModuleOrNull methods. Can we leave that text as they really mean "this" class loader, these methods do not delegate. > > 8200127: Replace collection.stream().forEach() with collection.forEach() > http://cr.openjdk.java.net/~martin/webrevs/jdk/redundant-stream/ > https://bugs.openjdk.java.net/browse/JDK-8200127 Looks okay. > > Who knew it could be so hard to spell "annotation"? > > 8200128: Fix some "annoations" typos > http://cr.openjdk.java.net/~martin/webrevs/jdk/annoations/ > https://bugs.openjdk.java.net/browse/JDK-8200128 Looks okay. > > 8200131: Improve lazy init of InetAddress.canonicalHostName and > NativeObject.pageSize > http://cr.openjdk.java.net/~martin/webrevs/jdk/lazy-init-local-vars/ > https://bugs.openjdk.java.net/browse/JDK-8200131 Looks okay. > Apologies to Alan - I had never looked at a topological sort before and got > carried away. > > 8200134: Improve ModuleHashesBuilder > http://cr.openjdk.java.net/~martin/webrevs/jdk/ModuleHashesBuilder/ > https://bugs.openjdk.java.net/browse/JDK-8200134 I suspect Mandy will want to look at this one. We also need to decide if there is a better place for it as it is only used by tools (`jar`, `jmod`, ...), it is not part of the runtime support. -Alan From mandy.chung at oracle.com Fri Mar 30 11:31:23 2018 From: mandy.chung at oracle.com (mandy chung) Date: Fri, 30 Mar 2018 19:31:23 +0800 Subject: RFR: More cleanup patches In-Reply-To: <9244499d-625e-e191-4304-9e37f12dbfee@oracle.com> References: <9244499d-625e-e191-4304-9e37f12dbfee@oracle.com> Message-ID: <4d8fd171-d2fe-7f62-48ab-0b6ed65960f7@oracle.com> On 3/30/18 6:53 PM, Alan Bateman wrote: > >> >> 8200134: Improve ModuleHashesBuilder >> http://cr.openjdk.java.net/~martin/webrevs/jdk/ModuleHashesBuilder/ >> https://bugs.openjdk.java.net/browse/JDK-8200134 > I suspect Mandy will want to look at this one. We also need to decide > if there is a better place for it as it is only used by tools (`jar`, > `jmod`, ...), it is not part of the runtime support. It's in java.base to avoid duplicating this class in both jdk.jar and jdk.jlink module.? It's not a small method.? It's not part of the runtime support.? I can't think of any better place. For this change, I am okay with most of the changes except I prefer the while loop to the for-loop with the local variable declaration. Mandy From peter.levart at gmail.com Fri Mar 30 11:38:25 2018 From: peter.levart at gmail.com (Peter Levart) Date: Fri, 30 Mar 2018 13:38:25 +0200 Subject: RFR: More cleanup patches In-Reply-To: <4d8fd171-d2fe-7f62-48ab-0b6ed65960f7@oracle.com> References: <9244499d-625e-e191-4304-9e37f12dbfee@oracle.com> <4d8fd171-d2fe-7f62-48ab-0b6ed65960f7@oracle.com> Message-ID: <59104ff3-b5a6-d345-1ef7-d52105f93a15@gmail.com> On 03/30/2018 01:31 PM, mandy chung wrote: > > > On 3/30/18 6:53 PM, Alan Bateman wrote: >> >>> >>> 8200134: Improve ModuleHashesBuilder >>> http://cr.openjdk.java.net/~martin/webrevs/jdk/ModuleHashesBuilder/ >>> https://bugs.openjdk.java.net/browse/JDK-8200134 >> I suspect Mandy will want to look at this one. We also need to decide >> if there is a better place for it as it is only used by tools (`jar`, >> `jmod`, ...), it is not part of the runtime support. > > It's in java.base to avoid duplicating this class in both jdk.jar and > jdk.jlink module.? It's not a small method.? It's not part of the > runtime support.? I can't think of any better place. New module jdk.tools.internal ? Peter > > For this change, I am okay with most of the changes except I prefer > the while loop to the for-loop with the local variable declaration. > > Mandy > From mandy.chung at oracle.com Fri Mar 30 11:55:54 2018 From: mandy.chung at oracle.com (mandy chung) Date: Fri, 30 Mar 2018 19:55:54 +0800 Subject: RFR: More cleanup patches In-Reply-To: <59104ff3-b5a6-d345-1ef7-d52105f93a15@gmail.com> References: <9244499d-625e-e191-4304-9e37f12dbfee@oracle.com> <4d8fd171-d2fe-7f62-48ab-0b6ed65960f7@oracle.com> <59104ff3-b5a6-d345-1ef7-d52105f93a15@gmail.com> Message-ID: <92b095ec-2921-6a47-517a-7e32ee92119c@oracle.com> On 3/30/18 7:38 PM, Peter Levart wrote: > > > On 03/30/2018 01:31 PM, mandy chung wrote: >> >> >> On 3/30/18 6:53 PM, Alan Bateman wrote: >>> >>>> >>>> 8200134: Improve ModuleHashesBuilder >>>> http://cr.openjdk.java.net/~martin/webrevs/jdk/ModuleHashesBuilder/ >>>> https://bugs.openjdk.java.net/browse/JDK-8200134 >>> I suspect Mandy will want to look at this one. We also need to >>> decide if there is a better place for it as it is only used by tools >>> (`jar`, `jmod`, ...), it is not part of the runtime support. >> >> It's in java.base to avoid duplicating this class in both jdk.jar and >> jdk.jlink module.? It's not a small method.? It's not part of the >> runtime support.? I can't think of any better place. > > New module jdk.tools.internal ? I considered it while I fear that this would become a dumping ground for tools utility although we start with one class.? The name would be jdk.internal.xxx. Mandy From ramanand.patil at oracle.com Fri Mar 30 12:35:52 2018 From: ramanand.patil at oracle.com (Ramanand Patil) Date: Fri, 30 Mar 2018 05:35:52 -0700 (PDT) Subject: RFR: 8200359: (tz) Upgrade time-zone data to tzdata2018d Message-ID: <8cc4d720-e231-42d0-ab34-7b56b58b5b74@default> Hi all, Please review the latest TZDATA integration (tzdata2018d) into JDK11. Bug: https://bugs.openjdk.java.net/browse/JDK-8200359 Webrev: http://cr.openjdk.java.net/~rpatil/8200359/webrev.00/ All the TimeZone related tests are passed after integration. Regards, Ramanand. From Alan.Bateman at oracle.com Fri Mar 30 14:07:24 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 30 Mar 2018 15:07:24 +0100 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: <5A999CAF.3030905@oracle.com> <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> <10728b43-110c-5dc3-1fdb-2e0241e3a0ff@oracle.com> <5ABC6DCF.10504@oracle.com> Message-ID: <6a2c6a54-9174-5815-80c1-35029931e0f2@oracle.com> On 29/03/2018 13:18, David Lloyd wrote: > : > OK great. In that case, I think all feedback has been accounted for, > and this should be ready to go AFAIK. > I skimmed through the patch attached to your last mail. I also saw Sherman's mail offering to look at the existing wording about the flush marker. So I think this the API is good and we should get the CSR submitted. I'm less sure about the tests. The patch modifies FlaterTest but it's not clear that is covers all the scenarios, ReadOnlyBufferException just one that comes to mind. Maybe we could identify additional tests while the CSR is in progress. -Alan From martinrb at google.com Fri Mar 30 16:29:37 2018 From: martinrb at google.com (Martin Buchholz) Date: Fri, 30 Mar 2018 09:29:37 -0700 Subject: RFR: More cleanup patches In-Reply-To: <4d8fd171-d2fe-7f62-48ab-0b6ed65960f7@oracle.com> References: <9244499d-625e-e191-4304-9e37f12dbfee@oracle.com> <4d8fd171-d2fe-7f62-48ab-0b6ed65960f7@oracle.com> Message-ID: On Fri, Mar 30, 2018 at 4:31 AM, mandy chung wrote: > > For this change, I am okay with most of the changes except I prefer the > while loop to the for-loop with the local variable declaration. > I prefer the idiom with the declaration in the for loop ("keep variable scope as small as possible"), but reverting: diff --git a/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java b/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java --- a/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java +++ b/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java @@ -77,7 +77,8 @@ Graph.Builder builder = new Graph.Builder<>(); Deque todo = new ArrayDeque<>(configuration.modules()); Set visited = new HashSet<>(); - for (ResolvedModule rm; (rm = todo.poll()) != null; ) { + ResolvedModule rm; + while ((rm = todo.poll()) != null) { if (visited.add(rm)) { builder.addNode(rm.name()); for (ResolvedModule dm : rm.reads()) { @@ -211,7 +212,8 @@ public Set dfs(Set roots) { ArrayDeque todo = new ArrayDeque<>(roots); Set visited = new HashSet<>(); - for (T u; (u = todo.poll()) != null; ) { + T u; + while ((u = todo.poll()) != null) { if (visited.add(u) && contains(u)) { adjacentNodes(u).stream() .filter(v -> !visited.contains(v)) From martinrb at google.com Fri Mar 30 16:39:43 2018 From: martinrb at google.com (Martin Buchholz) Date: Fri, 30 Mar 2018 09:39:43 -0700 Subject: RFR: More cleanup patches In-Reply-To: <92b095ec-2921-6a47-517a-7e32ee92119c@oracle.com> References: <9244499d-625e-e191-4304-9e37f12dbfee@oracle.com> <4d8fd171-d2fe-7f62-48ab-0b6ed65960f7@oracle.com> <59104ff3-b5a6-d345-1ef7-d52105f93a15@gmail.com> <92b095ec-2921-6a47-517a-7e32ee92119c@oracle.com> Message-ID: On Fri, Mar 30, 2018 at 4:55 AM, mandy chung wrote: > > > On 3/30/18 7:38 PM, Peter Levart wrote: > > > > On 03/30/2018 01:31 PM, mandy chung wrote: > > > > On 3/30/18 6:53 PM, Alan Bateman wrote: > > > > 8200134: Improve ModuleHashesBuilder > http://cr.openjdk.java.net/~martin/webrevs/jdk/ModuleHashesBuilder/ > https://bugs.openjdk.java.net/browse/JDK-8200134 > > I suspect Mandy will want to look at this one. We also need to decide if > there is a better place for it as it is only used by tools (`jar`, `jmod`, > ...), it is not part of the runtime support. > > > It's in java.base to avoid duplicating this class in both jdk.jar and > jdk.jlink module. It's not a small method. It's not part of the runtime > support. I can't think of any better place. > > > New module jdk.tools.internal ? > > > I considered it while I fear that this would become a dumping ground for > tools utility although we start with one class. The name would be > jdk.internal.xxx. > Right now the jdk has 10^2 modules. Why not 10^4? ModuleHashesBuilder could be in its own dedicated module. The good news is that ModuleHashesBuilder improvements in this change will itself avoid any future performance problems with a large number of modules! But that could/should be done in a separate change. From raffaello.giulietti at gmail.com Fri Mar 30 16:50:31 2018 From: raffaello.giulietti at gmail.com (raffaello.giulietti at gmail.com) Date: Fri, 30 Mar 2018 18:50:31 +0200 Subject: Clean-room implementation of Double::toString(double) and Float::toString(float) Message-ID: <5c8944fa-4941-79b4-9320-a04ecb93b27a@gmail.com> Hi, the topic I would like to work on is to solve the bugs described at https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4511638 about the results produced by the current implementation of Double::toString(double). I noticed that after all these years most of the issues illustrated in the bug report still remain unsolved in the latest OpenJDK. To that end, I have worked on a clean-room implementation that: * Could be used as a drop-in replacement for Double::toString(double) * Solves *all* the anomalies still present in OpenJDK. * Produces identical results otherwise. * Has extensive mathematical documentation on the inner workings. * Is way faster than the current OpenJDK implementation. * Uses significantly less resources in most cases. I guess this might sound rather presumptuous, but as far as I can tell the claims are unbiased and reflect reality. The new code also has a better specification than the current one, while being mostly compatible. Indeed, the current specification leaves room for interpretation and thus cannot ensure that an implementation produces consistent and unique results from one release to the next. The newer spec ensures a unique result. If there is interest in the new implementation, I would be glad to contribute my code to the OpenJDK. I've already signed the Oracle Contributor Agreement a few days ago. The code currently sits in its own module, is mostly polished, thoroughly tested but has never been audited by people other than myself. My target is to be able to integrate it in the JDK 11 LTS release, due in late September 2018. Greetings Raffaello From xueming.shen at oracle.com Fri Mar 30 16:52:26 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 30 Mar 2018 09:52:26 -0700 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: <6a2c6a54-9174-5815-80c1-35029931e0f2@oracle.com> References: <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> <10728b43-110c-5dc3-1fdb-2e0241e3a0ff@oracle.com> <5ABC6DCF.10504@oracle.com> <6a2c6a54-9174-5815-80c1-35029931e0f2@oracle.com> Message-ID: <5ABE6B4A.1010701@oracle.com> On 3/30/18, 7:07 AM, Alan Bateman wrote: > On 29/03/2018 13:18, David Lloyd wrote: >> : >> OK great. In that case, I think all feedback has been accounted for, >> and this should be ready to go AFAIK. >> > I skimmed through the patch attached to your last mail. I also saw > Sherman's mail offering to look at the existing wording about the > flush marker. So I think this the API is good and we should get the > CSR submitted. > > I'm less sure about the tests. The patch modifies FlaterTest but it's > not clear that is covers all the scenarios, ReadOnlyBufferException > just one that comes to mind. Maybe we could identify additional tests > while the CSR is in progress. > > -Alan CSR: https://bugs.openjdk.java.net/browse/JDK-8200527 From david.lloyd at redhat.com Fri Mar 30 16:54:25 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Fri, 30 Mar 2018 11:54:25 -0500 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: <5ABE6B4A.1010701@oracle.com> References: <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> <10728b43-110c-5dc3-1fdb-2e0241e3a0ff@oracle.com> <5ABC6DCF.10504@oracle.com> <6a2c6a54-9174-5815-80c1-35029931e0f2@oracle.com> <5ABE6B4A.1010701@oracle.com> Message-ID: Thanks! On Fri, Mar 30, 2018 at 11:52 AM, Xueming Shen wrote: > On 3/30/18, 7:07 AM, Alan Bateman wrote: >> >> On 29/03/2018 13:18, David Lloyd wrote: >>> >>> : >>> OK great. In that case, I think all feedback has been accounted for, >>> and this should be ready to go AFAIK. >>> >> I skimmed through the patch attached to your last mail. I also saw >> Sherman's mail offering to look at the existing wording about the flush >> marker. So I think this the API is good and we should get the CSR submitted. >> >> I'm less sure about the tests. The patch modifies FlaterTest but it's not >> clear that is covers all the scenarios, ReadOnlyBufferException just one >> that comes to mind. Maybe we could identify additional tests while the CSR >> is in progress. >> >> -Alan > > CSR: https://bugs.openjdk.java.net/browse/JDK-8200527 -- - DML From xueming.shen at oracle.com Fri Mar 30 17:05:40 2018 From: xueming.shen at oracle.com (Xueming Shen) Date: Fri, 30 Mar 2018 10:05:40 -0700 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: References: <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> <10728b43-110c-5dc3-1fdb-2e0241e3a0ff@oracle.com> <5ABC6DCF.10504@oracle.com> <6a2c6a54-9174-5815-80c1-35029931e0f2@oracle.com> <5ABE6B4A.1010701@oracle.com> Message-ID: <5ABE6E64.1060806@oracle.com> Hi David, (1) Deflater.setDictionary(ByteBuffer) missed a "@since 11" (2) infalte(...) may not need to catch DFE twice, better (?) to just update the inputPos/input at outsider catch as if (input == null) this.inputPos = inputPos + inputConsumed; else input.position(inputPos + inputConsumed; the if/else might be repetitive, but better than two layers of same DFE catch? -sherman On 3/30/18, 9:54 AM, David Lloyd wrote: > Thanks! > > On Fri, Mar 30, 2018 at 11:52 AM, Xueming Shen wrote: >> On 3/30/18, 7:07 AM, Alan Bateman wrote: >>> On 29/03/2018 13:18, David Lloyd wrote: >>>> : >>>> OK great. In that case, I think all feedback has been accounted for, >>>> and this should be ready to go AFAIK. >>>> >>> I skimmed through the patch attached to your last mail. I also saw >>> Sherman's mail offering to look at the existing wording about the flush >>> marker. So I think this the API is good and we should get the CSR submitted. >>> >>> I'm less sure about the tests. The patch modifies FlaterTest but it's not >>> clear that is covers all the scenarios, ReadOnlyBufferException just one >>> that comes to mind. Maybe we could identify additional tests while the CSR >>> is in progress. >>> >>> -Alan >> CSR: https://bugs.openjdk.java.net/browse/JDK-8200527 > > From naoto.sato at oracle.com Fri Mar 30 17:18:42 2018 From: naoto.sato at oracle.com (naoto.sato at oracle.com) Date: Fri, 30 Mar 2018 10:18:42 -0700 Subject: RFR: 8200359: (tz) Upgrade time-zone data to tzdata2018d In-Reply-To: <8cc4d720-e231-42d0-ab34-7b56b58b5b74@default> References: <8cc4d720-e231-42d0-ab34-7b56b58b5b74@default> Message-ID: <7e9b81c0-df92-32da-7bdb-6baaca0b6be1@oracle.com> Looks good. Naoto On 3/30/18 5:35 AM, Ramanand Patil wrote: > Hi all, > Please review the latest TZDATA integration (tzdata2018d) into JDK11. > Bug: https://bugs.openjdk.java.net/browse/JDK-8200359 > Webrev: http://cr.openjdk.java.net/~rpatil/8200359/webrev.00/ > > All the TimeZone related tests are passed after integration. > > Regards, > Ramanand. > From david.lloyd at redhat.com Fri Mar 30 17:23:32 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Fri, 30 Mar 2018 12:23:32 -0500 Subject: [JDK-6341887] RFR: Patch V3: java.util.zip: Add ByteBuffer methods to Inflater/Deflater In-Reply-To: <5ABE6E64.1060806@oracle.com> References: <5AA9D228.8070407@oracle.com> <5AB53E95.9080308@oracle.com> <10728b43-110c-5dc3-1fdb-2e0241e3a0ff@oracle.com> <5ABC6DCF.10504@oracle.com> <6a2c6a54-9174-5815-80c1-35029931e0f2@oracle.com> <5ABE6B4A.1010701@oracle.com> <5ABE6E64.1060806@oracle.com> Message-ID: On Fri, Mar 30, 2018 at 12:05 PM, Xueming Shen wrote: > > Hi David, > > (1) Deflater.setDictionary(ByteBuffer) missed a "@since 11" Oops, easy fix. > (2) infalte(...) may not need to catch DFE twice, better (?) to just update > the inputPos/input > at outsider catch as > > if (input == null) > this.inputPos = inputPos + inputConsumed; > else > input.position(inputPos + inputConsumed; > > the if/else might be repetitive, but better than two layers of same DFE > catch? I'm okay with anything at this point, but this does introduce a "inputPos possibly not initialized" problem which doesn't seem to have a clean solution. WDYT? -- - DML From paul.sandoz at oracle.com Fri Mar 30 17:35:09 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 30 Mar 2018 10:35:09 -0700 Subject: RFR: 8195649: reorganize tests for java.util.Optional In-Reply-To: <99114b70-464e-c757-3665-8f1058feb68d@oracle.com> References: <99114b70-464e-c757-3665-8f1058feb68d@oracle.com> Message-ID: <2F35CF81-5E81-4A9F-8508-37A9185F989F@oracle.com> Very nice +1. You can probably remove the "groups = ?unit?" from the @Test declarations. Paul. > On Mar 29, 2018, at 6:12 PM, Stuart Marks wrote: > > Hi all, > > Please review this changeset, which reorganizes (basically rewrites) the tests for Optional and Optional{Double,Int,Long}. The new arrangement clusters all the assertions together into check* methods. These are then called on the results of the various factories and other monadic operations. This reduced the amount of test code and actually increased the test coverage slightly. > > Bug: > > https://bugs.openjdk.java.net/browse/JDK-8195649 > > Webrev: > > http://cr.openjdk.java.net/~smarks/reviews/8195649/webrev.0/ > > Thanks, > > s'marks From stuart.marks at oracle.com Fri Mar 30 19:03:01 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Fri, 30 Mar 2018 12:03:01 -0700 Subject: RFR: 8195649: reorganize tests for java.util.Optional In-Reply-To: <2F35CF81-5E81-4A9F-8508-37A9185F989F@oracle.com> References: <99114b70-464e-c757-3665-8f1058feb68d@oracle.com> <2F35CF81-5E81-4A9F-8508-37A9185F989F@oracle.com> Message-ID: Thanks. Regarding groups="unit" I wasn't entirely sure what to do about it. My first thought was that it's disused and to remove it, but then I looked and found that a bunch of other tests also declare themselves in the "unit" group: test/jdk/java/io/BufferedReader/Lines.java test/jdk/java/lang/String/StringJoinTest.java test/jdk/java/net/Socks/SocksIPv6Test.java test/jdk/java/nio/file/Files/BytesAndLines.java test/jdk/java/nio/file/Files/StreamTest.java test/jdk/java/util/Collections/SingletonIterator.java test/jdk/java/util/Collections/UnmodifiableMapEntrySet.java test/jdk/java/util/Collections/Wrappers.java test/jdk/java/util/Comparator/BasicTest.java test/jdk/java/util/Comparator/TypeTest.java test/jdk/java/util/function/BiFunction/BiFunctionTest.java test/jdk/java/util/function/BinaryOperator/BasicTest.java test/jdk/java/util/logging/LoggerSupplierAPIsTest.java test/jdk/java/util/Map/EntryComparators.java test/jdk/java/util/StringJoiner/StringJoinerTest.java I still think it's disused -- I can't find anything in the test makefiles or test group files that mentions it. But if we get rid of it, I'd rather have all the files cleaned up at once. I'll leave it in for now. s'marks On 3/30/18 10:35 AM, Paul Sandoz wrote: > Very nice +1. > > You can probably remove the "groups = ?unit?" from the @Test declarations. > > Paul. > > >> On Mar 29, 2018, at 6:12 PM, Stuart Marks wrote: >> >> Hi all, >> >> Please review this changeset, which reorganizes (basically rewrites) the tests for Optional and Optional{Double,Int,Long}. The new arrangement clusters all the assertions together into check* methods. These are then called on the results of the various factories and other monadic operations. This reduced the amount of test code and actually increased the test coverage slightly. >> >> Bug: >> >> https://bugs.openjdk.java.net/browse/JDK-8195649 >> >> Webrev: >> >> http://cr.openjdk.java.net/~smarks/reviews/8195649/webrev.0/ >> >> Thanks, >> >> s'marks > From brian.burkhalter at oracle.com Fri Mar 30 20:42:43 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Fri, 30 Mar 2018 13:42:43 -0700 Subject: Clean-room implementation of Double::toString(double) and Float::toString(float) In-Reply-To: <5c8944fa-4941-79b4-9320-a04ecb93b27a@gmail.com> References: <5c8944fa-4941-79b4-9320-a04ecb93b27a@gmail.com> Message-ID: <8FC2F9AF-7B48-45FD-B65E-405122F1E21D@oracle.com> Hello Raffaello, On Mar 30, 2018, at 9:50 AM, raffaello.giulietti at gmail.com wrote: > the topic I would like to work on is to solve the bugs described at > https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4511638 about the > results produced by the current implementation of > Double::toString(double). I noticed that after all these years most of > the issues illustrated in the bug report still remain unsolved in the > latest OpenJDK. The JBS [1] issue is [2]. It is currently owned by me. > [?] > > The new code also has a better specification than the current one, while > being mostly compatible. Indeed, the current specification leaves room > for interpretation and thus cannot ensure that an implementation > produces consistent and unique results from one release to the next. The > newer spec ensures a unique result. Any specification change would need to go through the Compatibility and Specification Review process. [3] > If there is interest in the new implementation, I would be glad to > contribute my code to the OpenJDK. Speaking for myself, any contribution in this area would be welcome. Work could proceed under the extant JBS bug ID. > I've already signed the Oracle Contributor Agreement a few days ago. Processing the OCA should take at least two weeks [4]. > The code currently sits in its own module, is mostly polished, > thoroughly tested but has never been audited by people other than myself. > > My target is to be able to integrate it in the JDK 11 LTS release, due > in late September 2018. Per the JDK 11 schedule [5] there could well be sufficient time to run this submission through the review processes. I suggest, once your OCA has been processed, to proceed by posting your proposed changes for review on this mailing list. Note that in general attachments are scrubbed, so the patch would need either to be included inline or published as a webrev [6]. Thanks, Brian [1] https://wiki.openjdk.java.net/display/general/JBS+Overview [2] https://bugs.openjdk.java.net/browse/JDK-4511638 [3] https://wiki.openjdk.java.net/display/csr/Main [4] http://openjdk.java.net/contribute/ [5] http://mail.openjdk.java.net/pipermail/jdk-dev/2018-March/000940.html [6] http://openjdk.java.net/guide/codeReview.html From jonathan.gibbons at oracle.com Fri Mar 30 20:54:38 2018 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Fri, 30 Mar 2018 13:54:38 -0700 Subject: Clean-room implementation of Double::toString(double) and Float::toString(float) In-Reply-To: <8FC2F9AF-7B48-45FD-B65E-405122F1E21D@oracle.com> References: <5c8944fa-4941-79b4-9320-a04ecb93b27a@gmail.com> <8FC2F9AF-7B48-45FD-B65E-405122F1E21D@oracle.com> Message-ID: <5ABEA40E.6060208@oracle.com> On 03/30/2018 01:42 PM, Brian Burkhalter wrote: > Per the JDK 11 schedule [5] there could well be sufficient time to run this submission through the review processes. I suggest, once your OCA has been processed, to proceed by posting your proposed changes for review on this mailing list. Note that in general attachments are scrubbed, so the patch would need either to be included inline or published as a webrev [6]. Brian, From another mailing list: > Most OpenJDK mailing lists, including this one (code-tools-dev), > allow these attachment types: > > text/plain > text/x-diff > text/x-patch > message/rfc822 > > Attachments with the following filename extensions are dropped: > > exe > bat > cmd > com > pif > scr > vbs > cpl > > - Mark See http://mail.openjdk.java.net/pipermail/code-tools-dev/2018-March/000378.html for the original. -- Jon From brian.burkhalter at oracle.com Fri Mar 30 20:56:26 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Fri, 30 Mar 2018 13:56:26 -0700 Subject: Clean-room implementation of Double::toString(double) and Float::toString(float) In-Reply-To: <5ABEA40E.6060208@oracle.com> References: <5c8944fa-4941-79b4-9320-a04ecb93b27a@gmail.com> <8FC2F9AF-7B48-45FD-B65E-405122F1E21D@oracle.com> <5ABEA40E.6060208@oracle.com> Message-ID: <1266AC23-AE7D-4738-9AC4-3D5DE574BFC7@oracle.com> Thanks, Jon! On Mar 30, 2018, at 1:54 PM, Jonathan Gibbons wrote: > See http://mail.openjdk.java.net/pipermail/code-tools-dev/2018-March/000378.html > for the original. From martinrb at google.com Fri Mar 30 21:23:38 2018 From: martinrb at google.com (Martin Buchholz) Date: Fri, 30 Mar 2018 14:23:38 -0700 Subject: RFR: More cleanup patches In-Reply-To: <9244499d-625e-e191-4304-9e37f12dbfee@oracle.com> References: <9244499d-625e-e191-4304-9e37f12dbfee@oracle.com> Message-ID: On Fri, Mar 30, 2018 at 3:53 AM, Alan Bateman wrote: > On 30/03/2018 02:55, Martin Buchholz wrote: > >> >> 8200125: Fix some classloader/module typos >> http://cr.openjdk.java.net/~martin/webrevs/jdk/loader-typos/ >> https://bugs.openjdk.java.net/browse/JDK-8200125 >> > Most of these are okay but you've dropped the text "defined to this > ClassLoader" from the findClassInModuleOrNull methods. Can we leave that > text as they really mean "this" class loader, these methods do not delegate. Hmmm... I admit to being fuzzy on what's going on here, but: findClassInModuleOrNull(loadedModule, className) is essentially the same as defineClass(className, loadedModule) (why are the arguments reversed?) so their docs should be aligned. Both are loading from the given LoadedModule, so it seems "defined to this ClassLoader" goes without saying?! From raffaello.giulietti at gmail.com Fri Mar 30 21:57:30 2018 From: raffaello.giulietti at gmail.com (raffaello.giulietti at gmail.com) Date: Fri, 30 Mar 2018 23:57:30 +0200 Subject: Clean-room implementation of Double::toString(double) and Float::toString(float) In-Reply-To: <8FC2F9AF-7B48-45FD-B65E-405122F1E21D@oracle.com> References: <5c8944fa-4941-79b4-9320-a04ecb93b27a@gmail.com> <8FC2F9AF-7B48-45FD-B65E-405122F1E21D@oracle.com> Message-ID: <9ffa5039-82b6-6f0b-479b-307361d8ba7a@gmail.com> Hi Brian, On 2018-03-30 22:42, Brian Burkhalter wrote: > Hello Raffaello, > > On Mar 30, 2018, at 9:50 AM, raffaello.giulietti at gmail.com > wrote: > >> the topic I would like to work on is to solve the bugs described at >> https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4511638?about the >> results produced by the current implementation of >> Double::toString(double). I noticed that after all these years most of >> the issues illustrated in the bug report still remain unsolved in the >> latest OpenJDK. > > The JBS [1] issue is [2]. It is currently owned by me. > Yes, and the submission of the report was mine, far more than 10 years ago. Guys, time passes too fast... >> [?] >> >> The new code also has a better specification than the current one, while >> being mostly compatible. Indeed, the current specification leaves room >> for interpretation and thus cannot ensure that an implementation >> produces consistent and unique results from one release to the next. The >> newer spec ensures a unique result. > > Any specification change would need to go through the Compatibility and > Specification Review process. [3] > OK, as you will see, as soon as the code will be uploaded, the only thing that formally affects output is the "1.0E23" versus "9.99....E22" issue. Everything else is worded in such a way to remain compatible but is simply a little bit more rigorous. >> If there is interest in the new implementation, I would be glad to >> contribute my code to the OpenJDK. > > Speaking for myself, any contribution in this area would be welcome. > Work could proceed under the extant JBS bug ID. > OK, let's to that. >> I've already signed the Oracle?Contributor Agreement a few days ago. > > Processing the OCA should take at least two weeks [4]. > My wording was misleading: I already got the confirmation that my OCA application has been accepted, so I'm formally ready to contribute. >> The code currently sits in its own module, is mostly polished, >> thoroughly tested but has never been audited by people other than myself. >> >> My target is to be able to integrate it in the JDK 11 LTS release, due >> in late September 2018. > > Per the JDK 11 schedule [5] there could well be sufficient time to run > this submission through the review processes. I suggest, once your OCA > has been processed, to proceed by posting your proposed changes for > review on this mailing list. Note that in general attachments are > scrubbed, so the patch would need either to be included inline or > published as a webrev [6]. > OK, I'll take a look on how the mechanics works. I'm usually on Windows. Are there technical issues with it as far as Webrev is concerned? I mean, I could setup a Linux VM in VirtualBox if this simplifies my life, but I'd prefer continuing my main work in Win. > > [1]?https://wiki.openjdk.java.net/display/general/JBS+Overview > [2]?https://bugs.openjdk.java.net/browse/JDK-4511638 > [3]?https://wiki.openjdk.java.net/display/csr/Main > [4]?http://openjdk.java.net/contribute/ > [5]?http://mail.openjdk.java.net/pipermail/jdk-dev/2018-March/000940.html > [6]?http://openjdk.java.net/guide/codeReview.html From martinrb at google.com Fri Mar 30 22:07:21 2018 From: martinrb at google.com (Martin Buchholz) Date: Fri, 30 Mar 2018 15:07:21 -0700 Subject: RFR: More cleanup patches In-Reply-To: References: <9244499d-625e-e191-4304-9e37f12dbfee@oracle.com> Message-ID: Maybe I'm starting to understand. // attempt to load class in module defined to this loader assert loadedModule.loader() == this; return findClassInModuleOrNull(loadedModule, cn); Precondition of calling findClassInModuleOrNull is that loadedModule.loader() == this; so perhaps move that assert into the body of findClassInModuleOrNull ? --- // no class loading until VM is fully initialized if (!VM.isModuleSystemInited()) Here the method call is so self-documenting that we should just delete the comment? "VM is fully initialized" is not the same as "module system is initialized"?! From brian.burkhalter at oracle.com Fri Mar 30 22:17:03 2018 From: brian.burkhalter at oracle.com (Brian Burkhalter) Date: Fri, 30 Mar 2018 15:17:03 -0700 Subject: Clean-room implementation of Double::toString(double) and Float::toString(float) In-Reply-To: <9ffa5039-82b6-6f0b-479b-307361d8ba7a@gmail.com> References: <5c8944fa-4941-79b4-9320-a04ecb93b27a@gmail.com> <8FC2F9AF-7B48-45FD-B65E-405122F1E21D@oracle.com> <9ffa5039-82b6-6f0b-479b-307361d8ba7a@gmail.com> Message-ID: <3BD60996-BEC9-4179-91F8-39E002B33594@oracle.com> Hi Raffaello, On Mar 30, 2018, at 2:57 PM, raffaello.giulietti at gmail.com wrote: >>> [?] >>> >>> The new code also has a better specification than the current one, while >>> being mostly compatible. Indeed, the current specification leaves room >>> for interpretation and thus cannot ensure that an implementation >>> produces consistent and unique results from one release to the next. The >>> newer spec ensures a unique result. >> >> Any specification change would need to go through the Compatibility and >> Specification Review process. [3] >> > > OK, as you will see, as soon as the code will be uploaded, the only > thing that formally affects output is the "1.0E23" versus "9.99....E22" > issue. Everything else is worded in such a way to remain compatible but > is simply a little bit more rigorous. Sounds good. > My wording was misleading: I already got the confirmation that my OCA > application has been accepted, so I'm formally ready to contribute. That?s good as it gives more time. >> Per the JDK 11 schedule [5] there could well be sufficient time to run >> this submission through the review processes. I suggest, once your OCA >> has been processed, to proceed by posting your proposed changes for >> review on this mailing list. Note that in general attachments are >> scrubbed, so the patch would need either to be included inline or >> published as a webrev [6]. >> > > OK, I'll take a look on how the mechanics works. > > I'm usually on Windows. Are there technical issues with it as far as > Webrev is concerned? I mean, I could setup a Linux VM in VirtualBox if > this simplifies my life, but I'd prefer continuing my main work in Win. As seen in Jon?s posting there are some attachment types which will work. As to webrev, I think it should work on Windows at least in cygwin but I?ve not used it there myself. If it?s just a matter of creating a webrev I could do that on your behalf based on your supplied patch. Thanks, Brian From martinrb at google.com Fri Mar 30 22:49:25 2018 From: martinrb at google.com (Martin Buchholz) Date: Fri, 30 Mar 2018 15:49:25 -0700 Subject: RFR: Some patches for sherman In-Reply-To: <26c8ce5e-4872-e5b9-00bb-8ea92a5c5fc4@gmail.com> References: <26c8ce5e-4872-e5b9-00bb-8ea92a5c5fc4@gmail.com> Message-ID: The qualified people may not be reading this mailing list. Adding authors/reviewers of Stable.java. The question is whether in final ZipFile z = ... while (...) { use(z.res); } annotating instance field ZipFile.res as @Stable will enable the optimization of reading the res field only once. On Fri, Mar 30, 2018 at 1:16 AM, Peter Levart wrote: > I'm forwarding this private message to core-libs-dev so a qualified person > may read it... > > Regards, Peter > > > -------- Forwarded Message -------- > Subject: Re: RFR: Some patches for sherman > Date: Fri, 30 Mar 2018 06:18:26 +0000 > From: Peter Levart > To: Martin Buchholz > > > > Hi Martin, > > On Fri, 30 Mar 2018, 05:28 Martin Buchholz, martinrb at google.com>> wrote: > > > > On Thu, Mar 29, 2018 at 7:57 AM, Peter Levart > > wrote: > > Hi Martin, > > On 03/27/2018 02:21 AM, Martin Buchholz wrote: > >> 8200124: Various cleanups in jar/zip >> http://cr.openjdk.java.net/~martin/webrevs/jdk/zip-cleanup/ >> >> https://bugs.openjdk.java.net/browse/JDK-8200124 >> > > As I already mentioned for your Thread cleanup patch, do you > think that ZipFile objects are something that ever gets assigned > to static final or @Stable fields? Only in that case would > @Stable have any effect for ZipFile fields. @Stable should > really be reserved for classes which instances are normally > assigned to static final fields, such as ThreadLocal, > ClassValue, etc... If the holder of the @Stable field can not be > made constant, then neither can the value of that field. > > > Peter, I was very surprised by your reply. I re-read the doc for > Stable and it says to me that in > > ZipFile z = ... > > while (...) { > z.res ... > } > > z.res only needs to be read once. > > > This is true even without @Stable on res field. And JIT already does all > it can without it. What JIT cannot do in above situation is make the value > of res a compile-time constant embedded in generated code, possibly > triggering other optimizations that arrise from the value of the field. And > the reason is not the absense of @Stable but the fact that ZipFile instance > can not be prooved to be constant. > > > If hotspot only optimizes @Stable for static fields, I would regard > that as a bug. > Only being able to optimize static fields is not very useful. > > > It optimizes (constant-folds) @Stable static fields and @Stable instance > fields for which it can proove that the holder object can not change during > the lifetime of generated code. In practice this means that there has to be > a chain of @Stable fields leading to optimized value, rooted at some static > final or static @Stable field. > > Maybe the same optimization could also be applied for locals that are > accessed in a loop for which the JIT could proove that it never ends or if > it ends that the generated code is deoptimized. But I doubt this is what > current JIT does. In your ZipFile case this would mean JIT would be > generating separate code blob for each ZipFile instance. > > All above is just a speculation and how I understand the @ Stable > amnotation. Someone more qualified could chime-in clear things a bit. > > Regards, Peter > > > > > From john.r.rose at oracle.com Fri Mar 30 23:38:17 2018 From: john.r.rose at oracle.com (John Rose) Date: Fri, 30 Mar 2018 16:38:17 -0700 Subject: RFR: Some patches for sherman In-Reply-To: References: <26c8ce5e-4872-e5b9-00bb-8ea92a5c5fc4@gmail.com> Message-ID: <7FCC2320-00DA-457C-928D-0E545F73AF7C@oracle.com> In short, Peter is right; sorry Martin. That annotation is private to java.base and not currently a feature that has support beyond its uses in java.base. The purpose of @Stable is to allow lazily evaluated variables (both static and non-static) to be constant-folded like static finals. In the case of a non-static @Stable variable, the containing reference must first constant-fold in order for the @Stable field to fold. (The rules for arrays are even trickier.) The optimizations for @Stable are not aimed at proving properties of @Stable fields inside non-constant objects (or non-c. arrays). But you are right, Martin, that the rules for @Stable would allow the optimization you are asking for. If we ever do lazy evaluation as a first class language feature (I can dream), we'll want both kinds of optimizations to be routine. BTW, note that the rules of @Stable do not guarantee stability of "z.res" unless "z.res" has been observed to be non-null in a dominating code path. As long as it has its default value of null, the variable not yet guaranteed to be constant. To optimize this correctly we would probably need loop predication (or perhaps peeling) to optimistically sample z.res and ensure that it is non-null before going into the real loop. I see that "z.res" is a tuple of some sort, so it's likely that normal loop code will null-check it implicitly, which is a start. If the loop peels for other reasons, then the stable invariant property would fall out "for free". But as I said, the JIT is not looking for @Stable fields except inside of constant (not just loop-invariant) objects. I don't recommend using @Stable except as a way to extend the reach of constant folding. Proving other properties like loop invariance isn't on the list yet. The docs for @Stable don't spell this out as clearly as one might want, but this sentence comes closest: "More specifically, the HotSpot VM will process non-null stable fields (final or otherwise) in a similar manner to static final fields with respect to promoting the field's value to a constant." ? John On Mar 30, 2018, at 3:49 PM, Martin Buchholz wrote: > > The qualified people may not be reading this mailing list. Adding authors/reviewers of Stable.java. The question is whether in > > > final ZipFile z = ... > while (...) { > use(z.res); > } > > > annotating instance field ZipFile.res as @Stable will enable the optimization of reading the res field only once. > > > On Fri, Mar 30, 2018 at 1:16 AM, Peter Levart > wrote: > I'm forwarding this private message to core-libs-dev so a qualified person may read it... > > Regards, Peter > > > -------- Forwarded Message -------- > Subject: Re: RFR: Some patches for sherman > Date: Fri, 30 Mar 2018 06:18:26 +0000 > From: Peter Levart > > To: Martin Buchholz > > > > > Hi Martin, > > On Fri, 30 Mar 2018, 05:28 Martin Buchholz, >> wrote: > > > > On Thu, Mar 29, 2018 at 7:57 AM, Peter Levart > >> wrote: > > Hi Martin, > > On 03/27/2018 02:21 AM, Martin Buchholz wrote: > 8200124: Various cleanups in jar/zip > http://cr.openjdk.java.net/~martin/webrevs/jdk/zip-cleanup/ > > > https://bugs.openjdk.java.net/browse/JDK-8200124 > > As I already mentioned for your Thread cleanup patch, do you > think that ZipFile objects are something that ever gets assigned > to static final or @Stable fields? Only in that case would > @Stable have any effect for ZipFile fields. @Stable should > really be reserved for classes which instances are normally > assigned to static final fields, such as ThreadLocal, > ClassValue, etc... If the holder of the @Stable field can not be > made constant, then neither can the value of that field. > > > Peter, I was very surprised by your reply. I re-read the doc for > Stable and it says to me that in > > ZipFile z = ... > > while (...) { > z.res ... > } > > z.res only needs to be read once. > > > This is true even without @Stable on res field. And JIT already does all it can without it. What JIT cannot do in above situation is make the value of res a compile-time constant embedded in generated code, possibly triggering other optimizations that arrise from the value of the field. And the reason is not the absense of @Stable but the fact that ZipFile instance can not be prooved to be constant. > > > If hotspot only optimizes @Stable for static fields, I would regard > that as a bug. > Only being able to optimize static fields is not very useful. > > > It optimizes (constant-folds) @Stable static fields and @Stable instance fields for which it can proove that the holder object can not change during the lifetime of generated code. In practice this means that there has to be a chain of @Stable fields leading to optimized value, rooted at some static final or static @Stable field. > > Maybe the same optimization could also be applied for locals that are accessed in a loop for which the JIT could proove that it never ends or if it ends that the generated code is deoptimized. But I doubt this is what current JIT does. In your ZipFile case this would mean JIT would be generating separate code blob for each ZipFile instance. > > All above is just a speculation and how I understand the @ Stable amnotation. Someone more qualified could chime-in clear things a bit. > > Regards, Peter > > > > > From paul.sandoz at oracle.com Sat Mar 31 00:01:20 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Fri, 30 Mar 2018 17:01:20 -0700 Subject: RFR: Some patches for sherman In-Reply-To: <7FCC2320-00DA-457C-928D-0E545F73AF7C@oracle.com> References: <26c8ce5e-4872-e5b9-00bb-8ea92a5c5fc4@gmail.com> <7FCC2320-00DA-457C-928D-0E545F73AF7C@oracle.com> Message-ID: <9596B12F-B600-4D34-97A5-FB5BC5E1D527@oracle.com> If the res field is non-volatile then is C2 already capable of hoisting the field access out of the loop as if the result was assigned to a local variable? final ZipFile z = ? final z_res = z.res; while (...) { use(z_res); } Paul. > On Mar 30, 2018, at 4:38 PM, John Rose wrote: > > In short, Peter is right; sorry Martin. > > That annotation is private to java.base and not currently a feature that > has support beyond its uses in java.base. The purpose of @Stable is > to allow lazily evaluated variables (both static and non-static) to be > constant-folded like static finals. In the case of a non-static @Stable > variable, the containing reference must first constant-fold in order for > the @Stable field to fold. (The rules for arrays are even trickier.) > > The optimizations for @Stable are not aimed at proving properties > of @Stable fields inside non-constant objects (or non-c. arrays). > But you are right, Martin, that the rules for @Stable would allow > the optimization you are asking for. If we ever do lazy evaluation > as a first class language feature (I can dream), we'll want both > kinds of optimizations to be routine. > > BTW, note that the rules of @Stable do not guarantee stability > of "z.res" unless "z.res" has been observed to be non-null in > a dominating code path. As long as it has its default value > of null, the variable not yet guaranteed to be constant. To > optimize this correctly we would probably need loop predication > (or perhaps peeling) to optimistically sample z.res and ensure > that it is non-null before going into the real loop. I see that > "z.res" is a tuple of some sort, so it's likely that normal loop > code will null-check it implicitly, which is a start. If the loop > peels for other reasons, then the stable invariant property > would fall out "for free". But as I said, the JIT is not looking > for @Stable fields except inside of constant (not just > loop-invariant) objects. > > I don't recommend using @Stable except as a way to extend > the reach of constant folding. Proving other properties like > loop invariance isn't on the list yet. > > The docs for @Stable don't spell this out as clearly as one > might want, but this sentence comes closest: "More specifically, > the HotSpot VM will process non-null stable fields (final or > otherwise) in a similar manner to static final fields with respect to > promoting the field's value to a constant." > > ? John > > On Mar 30, 2018, at 3:49 PM, Martin Buchholz > wrote: >> >> The qualified people may not be reading this mailing list. Adding authors/reviewers of Stable.java. The question is whether in >> >> >> final ZipFile z = ... >> while (...) { >> use(z.res); >> } >> >> >> annotating instance field ZipFile.res as @Stable will enable the optimization of reading the res field only once. >> >> >> On Fri, Mar 30, 2018 at 1:16 AM, Peter Levart > wrote: >> I'm forwarding this private message to core-libs-dev so a qualified person may read it... >> >> Regards, Peter >> >> >> -------- Forwarded Message -------- >> Subject: Re: RFR: Some patches for sherman >> Date: Fri, 30 Mar 2018 06:18:26 +0000 >> From: Peter Levart > >> To: Martin Buchholz > >> >> >> >> Hi Martin, >> >> On Fri, 30 Mar 2018, 05:28 Martin Buchholz, >> wrote: >> >> >> >> On Thu, Mar 29, 2018 at 7:57 AM, Peter Levart >> >> wrote: >> >> Hi Martin, >> >> On 03/27/2018 02:21 AM, Martin Buchholz wrote: >> 8200124: Various cleanups in jar/zip >> http://cr.openjdk.java.net/~martin/webrevs/jdk/zip-cleanup/ >> > >> https://bugs.openjdk.java.net/browse/JDK-8200124 >> >> As I already mentioned for your Thread cleanup patch, do you >> think that ZipFile objects are something that ever gets assigned >> to static final or @Stable fields? Only in that case would >> @Stable have any effect for ZipFile fields. @Stable should >> really be reserved for classes which instances are normally >> assigned to static final fields, such as ThreadLocal, >> ClassValue, etc... If the holder of the @Stable field can not be >> made constant, then neither can the value of that field. >> >> >> Peter, I was very surprised by your reply. I re-read the doc for >> Stable and it says to me that in >> >> ZipFile z = ... >> >> while (...) { >> z.res ... >> } >> >> z.res only needs to be read once. >> >> >> This is true even without @Stable on res field. And JIT already does all it can without it. What JIT cannot do in above situation is make the value of res a compile-time constant embedded in generated code, possibly triggering other optimizations that arrise from the value of the field. And the reason is not the absense of @Stable but the fact that ZipFile instance can not be prooved to be constant. >> >> >> If hotspot only optimizes @Stable for static fields, I would regard >> that as a bug. >> Only being able to optimize static fields is not very useful. >> >> >> It optimizes (constant-folds) @Stable static fields and @Stable instance fields for which it can proove that the holder object can not change during the lifetime of generated code. In practice this means that there has to be a chain of @Stable fields leading to optimized value, rooted at some static final or static @Stable field. >> >> Maybe the same optimization could also be applied for locals that are accessed in a loop for which the JIT could proove that it never ends or if it ends that the generated code is deoptimized. But I doubt this is what current JIT does. In your ZipFile case this would mean JIT would be generating separate code blob for each ZipFile instance. >> >> All above is just a speculation and how I understand the @ Stable amnotation. Someone more qualified could chime-in clear things a bit. >> >> Regards, Peter >> >> >> >> >> > From martinrb at google.com Sat Mar 31 00:26:05 2018 From: martinrb at google.com (Martin Buchholz) Date: Fri, 30 Mar 2018 17:26:05 -0700 Subject: RFR: Some patches for sherman In-Reply-To: <9596B12F-B600-4D34-97A5-FB5BC5E1D527@oracle.com> References: <26c8ce5e-4872-e5b9-00bb-8ea92a5c5fc4@gmail.com> <7FCC2320-00DA-457C-928D-0E545F73AF7C@oracle.com> <9596B12F-B600-4D34-97A5-FB5BC5E1D527@oracle.com> Message-ID: On Fri, Mar 30, 2018 at 5:01 PM, Paul Sandoz wrote: > If the res field is non-volatile then is C2 already capable of hoisting > the field access out of the loop as if the result was assigned to a local > variable? > > final ZipFile z = ? > final z_res = z.res; > while (...) { > use(z_res); > } > It can do this if it can inline everything and determine that nothing inside the loop writes to res AND there is no synchronization happening (else you would need to prove no other thread is writing to the field). So I would be surprised if any JIT would do this in practice for a complex loop. Relatedly, I have a local mod to ZipFile that does: final byte[] cen; final int[] entries; final int entryCount; final ZipCoder zc = this.zc; // Acquire the lock once briefly to obtain immutable data references. synchronized (ZipFile.this) { ensureOpen(); cen = zsrc.cen; entries = zsrc.entries; entryCount = zsrc.total; } .... use(cen, entries, entryCount, zc) From mandy.chung at oracle.com Sat Mar 31 01:12:16 2018 From: mandy.chung at oracle.com (mandy chung) Date: Sat, 31 Mar 2018 09:12:16 +0800 Subject: RFR: More cleanup patches In-Reply-To: References: <9244499d-625e-e191-4304-9e37f12dbfee@oracle.com> <4d8fd171-d2fe-7f62-48ab-0b6ed65960f7@oracle.com> Message-ID: On 3/31/18 12:29 AM, Martin Buchholz wrote: > > > On Fri, Mar 30, 2018 at 4:31 AM, mandy chung > wrote: > > > For this change, I am okay with most of the changes except I > prefer the while loop to the for-loop with the local variable > declaration. > > > I prefer the idiom with the declaration in the for loop ("keep > variable scope as small as possible"), but reverting: > > diff --git > a/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java > b/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java > --- > a/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java > +++ > b/src/java.base/share/classes/jdk/internal/module/ModuleHashesBuilder.java > @@ -77,7 +77,8 @@ > ? ? ? ? ?Graph.Builder builder = new Graph.Builder<>(); > ? ? ? ? ?Deque todo = new > ArrayDeque<>(configuration.modules()); > ? ? ? ? ?Set visited = new HashSet<>(); > -? ? ? ? for (ResolvedModule rm; (rm = todo.poll()) != null; ) { > +? ? ? ? ResolvedModule rm; > +? ? ? ? while ((rm = todo.poll()) != null) { > ? ? ? ? ? ? ?if (visited.add(rm)) { > ? ? ? ? ? ? ? ? ?builder.addNode(rm.name ()); > ? ? ? ? ? ? ? ? ?for (ResolvedModule dm : rm.reads()) { > @@ -211,7 +212,8 @@ > ? ? ? ? ?public Set dfs(Set roots) { > ? ? ? ? ? ? ?ArrayDeque todo = new ArrayDeque<>(roots); > ? ? ? ? ? ? ?Set visited = new HashSet<>(); > -? ? ? ? ? ? for (T u; (u = todo.poll()) != null; ) { > +? ? ? ? ? ? T u; > +? ? ? ? ? ? while ((u = todo.poll()) != null) { > ? ? ? ? ? ? ? ? ?if (visited.add(u) && contains(u)) { > ? ? ? ? ? ? ? ? ? ? ?adjacentNodes(u).stream() > ? ? ? ? ? ? ? ? ? ? ? ? ?.filter(v -> !visited.contains(v)) > +1 Thanks. Mandy From martinrb at google.com Sat Mar 31 01:31:06 2018 From: martinrb at google.com (Martin Buchholz) Date: Fri, 30 Mar 2018 18:31:06 -0700 Subject: RFR: Some patches for sherman In-Reply-To: <7FCC2320-00DA-457C-928D-0E545F73AF7C@oracle.com> References: <26c8ce5e-4872-e5b9-00bb-8ea92a5c5fc4@gmail.com> <7FCC2320-00DA-457C-928D-0E545F73AF7C@oracle.com> Message-ID: Thanks, John. I need to adjust my expectations. The word "constant" means something different to hotspot engineers. I'm still hoping to someday simply say, "here's a final field - just go ahead and trust that it's truly final" On Fri, Mar 30, 2018 at 4:38 PM, John Rose wrote: > > The docs for @Stable don't spell this out as clearly as one > might want, but this sentence comes closest: "More specifically, > the HotSpot VM will process non-null stable fields (final or > otherwise) in a similar manner to static final fields with respect to > promoting the field's value to a constant." > From raffaello.giulietti at gmail.com Sat Mar 31 14:24:53 2018 From: raffaello.giulietti at gmail.com (raffaello.giulietti at gmail.com) Date: Sat, 31 Mar 2018 16:24:53 +0200 Subject: Coding conventions for core-libs-dev In-Reply-To: <3BD60996-BEC9-4179-91F8-39E002B33594@oracle.com> References: <5c8944fa-4941-79b4-9320-a04ecb93b27a@gmail.com> <8FC2F9AF-7B48-45FD-B65E-405122F1E21D@oracle.com> <9ffa5039-82b6-6f0b-479b-307361d8ba7a@gmail.com> <3BD60996-BEC9-4179-91F8-39E002B33594@oracle.com> Message-ID: <384a86b7-5169-eede-5e52-38ee19a9fd5d@gmail.com> Hi, are there any Java coding conventions to follow? I found very outdated guidelines at http://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html with ab archaic line limitation of 80 or even 70 chars/line. Are there official, semi-official or suggested documents? Greetings Raffaello From forax at univ-mlv.fr Sat Mar 31 14:34:46 2018 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 31 Mar 2018 16:34:46 +0200 (CEST) Subject: Coding conventions for core-libs-dev In-Reply-To: <384a86b7-5169-eede-5e52-38ee19a9fd5d@gmail.com> References: <5c8944fa-4941-79b4-9320-a04ecb93b27a@gmail.com> <8FC2F9AF-7B48-45FD-B65E-405122F1E21D@oracle.com> <9ffa5039-82b6-6f0b-479b-307361d8ba7a@gmail.com> <3BD60996-BEC9-4179-91F8-39E002B33594@oracle.com> <384a86b7-5169-eede-5e52-38ee19a9fd5d@gmail.com> Message-ID: <308056596.2347163.1522506886903.JavaMail.zimbra@u-pem.fr> http://cr.openjdk.java.net/~alundblad/styleguide/index-v6.html is the closest you can find as an official coding convention for the OpenJDK. R?mi ----- Mail original ----- > De: "raffaello giulietti" > ?: "core-libs-dev" > Envoy?: Samedi 31 Mars 2018 16:24:53 > Objet: Coding conventions for core-libs-dev > Hi, > > are there any Java coding conventions to follow? > > I found very outdated guidelines at > http://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html > with ab archaic line limitation of 80 or even 70 chars/line. > > Are there official, semi-official or suggested documents? > > > > Greetings > Raffaello From neugens.limasoftware at gmail.com Sat Mar 31 14:51:19 2018 From: neugens.limasoftware at gmail.com (Mario Torre) Date: Sat, 31 Mar 2018 14:51:19 +0000 Subject: Coding conventions for core-libs-dev In-Reply-To: <308056596.2347163.1522506886903.JavaMail.zimbra@u-pem.fr> References: <5c8944fa-4941-79b4-9320-a04ecb93b27a@gmail.com> <8FC2F9AF-7B48-45FD-B65E-405122F1E21D@oracle.com> <9ffa5039-82b6-6f0b-479b-307361d8ba7a@gmail.com> <3BD60996-BEC9-4179-91F8-39E002B33594@oracle.com> <384a86b7-5169-eede-5e52-38ee19a9fd5d@gmail.com> <308056596.2347163.1522506886903.JavaMail.zimbra@u-pem.fr> Message-ID: Yes, but please try to keep the 80 columns (as per the document Remi suggested, unless it kills readability). It seems archaic, but not so much when you review patches and read code on a mobile device. Lots of people also like to keep their monitors in portrait mode, which means less real estate for long lines, not talking about the fact that this limit forces you to write more concise code! Cheers, Mario On Sat 31. Mar 2018 at 16:35, Remi Forax wrote: > http://cr.openjdk.java.net/~alundblad/styleguide/index-v6.html > is the closest you can find as an official coding convention for the > OpenJDK. > > R?mi > > ----- Mail original ----- > > De: "raffaello giulietti" > > ?: "core-libs-dev" > > Envoy?: Samedi 31 Mars 2018 16:24:53 > > Objet: Coding conventions for core-libs-dev > > > Hi, > > > > are there any Java coding conventions to follow? > > > > I found very outdated guidelines at > > > http://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html > > with ab archaic line limitation of 80 or even 70 chars/line. > > > > Are there official, semi-official or suggested documents? > > > > > > > > Greetings > > Raffaello > From raffaello.giulietti at gmail.com Sat Mar 31 15:29:57 2018 From: raffaello.giulietti at gmail.com (raffaello.giulietti at gmail.com) Date: Sat, 31 Mar 2018 17:29:57 +0200 Subject: Coding conventions for core-libs-dev In-Reply-To: References: <5c8944fa-4941-79b4-9320-a04ecb93b27a@gmail.com> <8FC2F9AF-7B48-45FD-B65E-405122F1E21D@oracle.com> <9ffa5039-82b6-6f0b-479b-307361d8ba7a@gmail.com> <3BD60996-BEC9-4179-91F8-39E002B33594@oracle.com> <384a86b7-5169-eede-5e52-38ee19a9fd5d@gmail.com> <308056596.2347163.1522506886903.JavaMail.zimbra@u-pem.fr> Message-ID: <8a169751-a421-baf3-f69d-e80f5eab0c38@gmail.com> On 2018-03-31 16:51, Mario Torre wrote: > Yes, but please try to keep the 80 columns (as per the document Remi > suggested, unless it kills readability). It seems archaic, but not so > much when you review patches and read code on a mobile device. Lots of > people also like to keep their monitors in portrait mode, which means > less real estate for long lines, not talking about the fact that this > limit forces you to write more concise code! > > Cheers, > Mario Portrait orientation might invite writing longer methods and choosing shorter names, which is arguably even worse than long lines ;-) Anyway, while 80 chars/line is not my first choice I'll or course adhere to the guidelines mentioned by R?mi. BTW, does "80" include the ending LF? Raffaello > > > On Sat 31. Mar 2018 at 16:35, Remi Forax > wrote: > > http://cr.openjdk.java.net/~alundblad/styleguide/index-v6.html > is the closest you can find as an official coding convention for the > OpenJDK. > > R?mi > > ----- Mail original ----- > > De: "raffaello giulietti" > > > ?: "core-libs-dev" > > > Envoy?: Samedi 31 Mars 2018 16:24:53 > > Objet: Coding conventions for core-libs-dev > > > Hi, > > > > are there any Java coding conventions to follow? > > > > I found very outdated guidelines at > > > http://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html > > with ab archaic line limitation of 80 or even 70 chars/line. > > > > Are there official, semi-official or suggested documents? > > > > > > > > Greetings > > Raffaello > From neugens.limasoftware at gmail.com Sat Mar 31 17:16:20 2018 From: neugens.limasoftware at gmail.com (Mario Torre) Date: Sat, 31 Mar 2018 17:16:20 +0000 Subject: Coding conventions for core-libs-dev In-Reply-To: <8a169751-a421-baf3-f69d-e80f5eab0c38@gmail.com> References: <5c8944fa-4941-79b4-9320-a04ecb93b27a@gmail.com> <8FC2F9AF-7B48-45FD-B65E-405122F1E21D@oracle.com> <9ffa5039-82b6-6f0b-479b-307361d8ba7a@gmail.com> <3BD60996-BEC9-4179-91F8-39E002B33594@oracle.com> <384a86b7-5169-eede-5e52-38ee19a9fd5d@gmail.com> <308056596.2347163.1522506886903.JavaMail.zimbra@u-pem.fr> <8a169751-a421-baf3-f69d-e80f5eab0c38@gmail.com> Message-ID: As a special exception, if you commit tomorrow, you can use CRLF ;) Cheers, Mario On Sat 31. Mar 2018 at 17:30, wrote: > On 2018-03-31 16:51, Mario Torre wrote: > > Yes, but please try to keep the 80 columns (as per the document Remi > > suggested, unless it kills readability). It seems archaic, but not so > > much when you review patches and read code on a mobile device. Lots of > > people also like to keep their monitors in portrait mode, which means > > less real estate for long lines, not talking about the fact that this > > limit forces you to write more concise code! > > > > Cheers, > > Mario > > Portrait orientation might invite writing longer methods and choosing > shorter names, which is arguably even worse than long lines ;-) > > Anyway, while 80 chars/line is not my first choice I'll or course adhere > to the guidelines mentioned by R?mi. BTW, does "80" include the ending LF? > > > > Raffaello > > > > > > > On Sat 31. Mar 2018 at 16:35, Remi Forax > > wrote: > > > > http://cr.openjdk.java.net/~alundblad/styleguide/index-v6.html > > is the closest you can find as an official coding convention for the > > OpenJDK. > > > > R?mi > > > > ----- Mail original ----- > > > De: "raffaello giulietti" > > > > > ?: "core-libs-dev" > > > > > Envoy?: Samedi 31 Mars 2018 16:24:53 > > > Objet: Coding conventions for core-libs-dev > > > > > Hi, > > > > > > are there any Java coding conventions to follow? > > > > > > I found very outdated guidelines at > > > > > > http://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html > > > with ab archaic line limitation of 80 or even 70 chars/line. > > > > > > Are there official, semi-official or suggested documents? > > > > > > > > > > > > Greetings > > > Raffaello > > > > From sergei.tsypanov at yandex.ru Sat Mar 31 20:33:13 2018 From: sergei.tsypanov at yandex.ru (=?utf-8?B?0KHQtdGA0LPQtdC5INCm0YvQv9Cw0L3QvtCy?=) Date: Sat, 31 Mar 2018 22:33:13 +0200 Subject: RFR: More cleanup patches In-Reply-To: References: Message-ID: <3547271522528393@web23j.yandex.ru> Hi Martin, as soon as the changes for 8199800: Optimize Boolean.parseBoolean(String) are merged we could replace code snippets like if (aValue.toUpperCase().equals("TRUE")) { value = Boolean.TRUE; } else { value = Boolean.FALSE; } with value = Boolean.parseBoolean(aValue); See javax.swing.plaf.synth.SynthParser for more similar cases. P. S. I'm not sure about this one in jdk.internal.reflect.ReflectionFactory String val = props.getProperty("sun.reflect.noInflation"); if (val != null && val.equals("true")) { noInflation = true; } It could be replaced with String val = props.getProperty("sun.reflect.noInflation"); noInflation = Boolean.parseBoolean(val); but then val="TRUE" means noInflation=true while currently noInflation=true exclusively when val="true". I've found similar code snippets in: java.awt.Component java.awt.Window javax.swing.DefaultCellEditor sun.net.www.protocol.httpDigestAuthentication and some other classes.